|
| 1 | +import json |
| 2 | +from models.json_extractor import JsonExtractor |
| 3 | +from models.fulltest import Test |
| 4 | +from models.question import Question |
| 5 | +from app.ai_clients import ask_gemini |
| 6 | +from .utils import update_token_count |
| 7 | +from models.prompt_builders import TestPromptBuilder, AnswerPromptBuilder |
| 8 | + |
| 9 | +def generate_test_service(topic, format_type, additional_context, language, user_profile=None, lesson_content_context=""): |
| 10 | + prompt = TestPromptBuilder.build_multiple_choice_prompt( |
| 11 | + topic, additional_context, language, |
| 12 | + user_profile=user_profile, |
| 13 | + lesson_content_context=lesson_content_context |
| 14 | + ) |
| 15 | + raw_output, tokens = ask_gemini(prompt, json_mode=True) |
| 16 | + update_token_count(tokens) |
| 17 | + |
| 18 | + if not raw_output or "Error:" in raw_output: |
| 19 | + print(f"Failed to generate test with Gemini. AI response: {raw_output}") |
| 20 | + return None |
| 21 | + |
| 22 | + test_data = JsonExtractor.extract_json(raw_output) |
| 23 | + questions = [ |
| 24 | + Question(question=q.get("question"), options=q.get("options", {})) |
| 25 | + for q in test_data.get("questions", []) |
| 26 | + ] |
| 27 | + |
| 28 | + return Test( |
| 29 | + test_name=test_data.get("test-name", "Unnamed Test"), |
| 30 | + topic=test_data.get("topic", topic), |
| 31 | + questions=questions |
| 32 | + ) |
| 33 | + |
| 34 | + |
| 35 | +def evaluate_answers_service(questions, user_answers, language): |
| 36 | + qa_list = [] |
| 37 | + for q, ua in zip(questions, user_answers): |
| 38 | + answer_key = ua.get('answer_value', ua.get('answer', '')) |
| 39 | + answer_text = ua.get('answer', '') |
| 40 | + if hasattr(q, 'options') and answer_key in q.options: |
| 41 | + answer_text = q.options[answer_key] |
| 42 | + qa_list.append({ |
| 43 | + "question": q.question, |
| 44 | + "answer": answer_text, |
| 45 | + "original_answer": answer_key |
| 46 | + }) |
| 47 | + |
| 48 | + from app.ai_clients import ask_gemini |
| 49 | + prompt = AnswerPromptBuilder.build_batch_check_prompt( |
| 50 | + [{"question": qa["question"], "answer": qa["answer"]} for qa in qa_list], |
| 51 | + language |
| 52 | + ) |
| 53 | + response_text, tokens = ask_gemini(prompt, json_mode=True) |
| 54 | + update_token_count(tokens) |
| 55 | + |
| 56 | + if not response_text or "Error:" in response_text: |
| 57 | + return [] |
| 58 | + |
| 59 | + try: |
| 60 | + response_json = JsonExtractor.extract_json(response_text) |
| 61 | + assessments = response_json.get("assessments", []) |
| 62 | + detailed_results = [] |
| 63 | + |
| 64 | + for i, qa in enumerate(qa_list): |
| 65 | + assessment = next( |
| 66 | + (item['assessment'] for item in assessments if item['id'] == i), |
| 67 | + "Evaluation Error" |
| 68 | + ) |
| 69 | + detailed_results.append({ |
| 70 | + "question": qa["question"], |
| 71 | + "answer": qa["answer"], |
| 72 | + "original_answer": qa["original_answer"], |
| 73 | + "assessment": assessment |
| 74 | + }) |
| 75 | + return detailed_results |
| 76 | + |
| 77 | + except (ValueError, KeyError) as e: |
| 78 | + print(f"Error parsing Gemini batch assessment response: {e}") |
| 79 | + return [] |
| 80 | + |
| 81 | + |
| 82 | +def calculate_percentage_score_service(detailed_results): |
| 83 | + from app.ai_clients import ask_gemini |
| 84 | + prompt = "Based on these answers and evaluations, give a final score from 0-100:\n\n" |
| 85 | + for result in detailed_results: |
| 86 | + prompt += f"Q: {result['question']}\nA: {result['answer']}\nAssessment: {result['assessment']}\n\n" |
| 87 | + prompt += "Return just the number." |
| 88 | + result_text, tokens = ask_gemini(prompt, json_mode=False) |
| 89 | + update_token_count(tokens) |
| 90 | + |
| 91 | + return int(''.join(filter(str.isdigit, result_text))) if result_text and "Error:" not in result_text else 0 |
0 commit comments