Spaces:
Sleeping
Sleeping
| # frontend/validation.py | |
| """ | |
| Validation logic for MOS evaluation form data. | |
| """ | |
| import json | |
| import gradio as gr | |
| from typing import Dict, Any, Tuple | |
| def validate_mos_completion(mos_data_json: str, expected_clips: int) -> Tuple[bool, str]: | |
| """ | |
| Validate that all MOS clips have been rated. | |
| Returns: | |
| (is_valid, error_message) | |
| """ | |
| if not mos_data_json or mos_data_json == "None": | |
| return False, "⚠️ Please rate at least one dimension for each clip before continuing!" | |
| try: | |
| ratings_data = json.loads(mos_data_json) | |
| # Check that each clip is completed | |
| # Clip is complete if: all 5 ratings are filled OR gender_mismatch is checked | |
| clips_with_ratings = 0 | |
| for clip_id, ratings in ratings_data.items(): | |
| rating_dims = ["clarity", "pronunciation", "prosody", "naturalness", "overall"] | |
| filled_ratings = [dim for dim in rating_dims if ratings.get(dim)] | |
| all_ratings_filled = len(filled_ratings) == 5 | |
| has_gender_mismatch = ratings.get("gender_mismatch", False) | |
| if all_ratings_filled or has_gender_mismatch: | |
| clips_with_ratings += 1 | |
| if clips_with_ratings < expected_clips: | |
| return False, f"⚠️ Please complete all clips before continuing! Each clip needs either all 5 ratings, or a gender flag. ({clips_with_ratings}/{expected_clips} completed)" | |
| return True, "" | |
| except json.JSONDecodeError: | |
| return False, "⚠️ Error reading ratings. Please try again!" | |
| def validate_ab_completion(ab_data_json: str, expected_comparisons: int, comparison_type: str = "comparisons") -> Tuple[bool, str]: | |
| """ | |
| Validate that all A/B comparisons have been completed. | |
| A comparison is considered complete if either: | |
| - A choice is selected (A, B, or tie), OR | |
| - At least one gender mismatch checkbox is checked | |
| Args: | |
| ab_data_json: JSON string containing comparison data | |
| expected_comparisons: Number of comparisons expected | |
| comparison_type: Type of comparison for error message (e.g., "model comparisons", "gender comparisons") | |
| Returns: | |
| (is_valid, error_message) | |
| """ | |
| if not ab_data_json or ab_data_json == "None": | |
| return False, f"⚠️ Please make a choice for each {comparison_type} before continuing!" | |
| try: | |
| comparisons_data = json.loads(ab_data_json) | |
| # Check that each comparison is completed | |
| # Complete if: has a choice OR has gender mismatch checked | |
| completed_comparisons = 0 | |
| for comp_id, comparison in comparisons_data.items(): | |
| has_choice = bool(comparison.get("choice")) | |
| has_gender_mismatch = ( | |
| comparison.get("gender_mismatch_a", False) or | |
| comparison.get("gender_mismatch_b", False) or | |
| comparison.get("gender_mismatch_male", False) or | |
| comparison.get("gender_mismatch_female", False) | |
| ) | |
| if has_choice or has_gender_mismatch: | |
| completed_comparisons += 1 | |
| if completed_comparisons < expected_comparisons: | |
| return False, f"⚠️ Please complete all {comparison_type} before continuing! Each needs either a choice or gender flag. ({completed_comparisons}/{expected_comparisons} completed)" | |
| return True, "" | |
| except json.JSONDecodeError: | |
| return False, f"⚠️ Error reading {comparison_type}. Please try again!" | |
| def validate_overall_feedback(overall_preference: str) -> Tuple[bool, str]: | |
| """ | |
| Validate that overall feedback has been selected. | |
| Returns: | |
| (is_valid, error_message) | |
| """ | |
| if not overall_preference or overall_preference == "None" or overall_preference == "": | |
| return False, "⚠️ Please select an overall preference before submitting!" | |
| return True, "" | |
| def validate_final_submission(overall_preference: str) -> Tuple[bool, str]: | |
| """ | |
| Validate final submission - only checks that overall preference is selected. | |
| Returns: | |
| (is_valid, error_message) | |
| """ | |
| # Only check that overall feedback is selected | |
| return validate_overall_feedback(overall_preference) | |