|
import json |
|
import re |
|
from math import prod |
|
from typing import List |
|
|
|
def extract_json(response: str) -> dict: |
|
""" |
|
Extract JSON content from a string response. |
|
|
|
Args: |
|
response (str): String containing JSON content, possibly within code blocks. |
|
|
|
Returns: |
|
dict: Extracted and parsed JSON content. |
|
|
|
Raises: |
|
ValueError: If no valid JSON content could be extracted. |
|
""" |
|
try: |
|
evaluation_json = json.loads(response) |
|
except json.JSONDecodeError: |
|
|
|
match = re.search(r'```json\n(.*?)\n```', response, re.DOTALL) |
|
if not match: |
|
|
|
match = re.search(r'```\n(.*?)\n```', response, re.DOTALL) |
|
|
|
if match: |
|
evaluation_content = match.group(1) |
|
evaluation_json = json.loads(evaluation_content) |
|
else: |
|
raise ValueError("Failed to extract valid JSON content") |
|
return evaluation_json |
|
|
|
|
|
def convert_score_fields(data: dict) -> dict: |
|
""" |
|
Convert score fields in a dictionary to integers recursively. |
|
|
|
Args: |
|
data (dict): Dictionary containing score fields to convert. |
|
|
|
Returns: |
|
dict: Dictionary with score fields converted to integers. |
|
|
|
Raises: |
|
ValueError: If a score value cannot be converted to integer. |
|
""" |
|
|
|
converted_data = {} |
|
for key, value in data.items(): |
|
if key == "score": |
|
if isinstance(value, int): |
|
converted_data[key] = value |
|
elif isinstance(value, str) and value.isdigit(): |
|
converted_data[key] = int(value) |
|
else: |
|
raise ValueError(f"Invalid score value: {value!r}") |
|
elif isinstance(value, dict): |
|
converted_data[key] = convert_score_fields(value) |
|
else: |
|
converted_data[key] = value |
|
return converted_data |
|
|
|
|
|
def calculate_geometric_mean(scores: List[int]) -> float: |
|
""" |
|
Calculate the geometric mean of a list of scores. |
|
|
|
Args: |
|
scores (List[int]): List of integer scores, may contain None values. |
|
|
|
Returns: |
|
float: Geometric mean of non-None scores. Returns 0.0 if list is empty |
|
or contains only None values. |
|
""" |
|
scores = [s for s in scores if s is not None] |
|
if not scores: |
|
return 0.0 |
|
product = prod(scores) |
|
return product ** (1 / len(scores)) |
|
|