""" Cognition Simulator v1.0 - World Class Expertise Generates realistic aggregated metrics for cognition tests based on student profiles. """ import random import pandas as pd from typing import Dict, List, Any class CognitionSimulator: def __init__(self): pass def simulate_student_test(self, student: Dict, test_name: str, age_group: str) -> Dict: """ Simulates aggregated metrics for a specific student and test. """ # Baseline performance from student profile (Cognitive Overall score if available, or random 6-9) # Using numeric scores from 3000-students.xlsx if possible, otherwise random high-quality baseline. # Note: 3000-students.xlsx has: Openness, Conscientiousness, etc. # We can derive baseline from Conscientiousness (diligence) and Openness (curiosity/speed). conscientiousness = student.get('Conscientiousness Score', 70) / 10.0 openness = student.get('Openness Score', 70) / 10.0 baseline_accuracy = (conscientiousness * 0.6 + openness * 0.4) / 10.0 # 0.0 to 1.0 # Add random variation accuracy = min(max(baseline_accuracy + random.uniform(-0.1, 0.15), 0.6), 0.98) rt_baseline = 1500 - (accuracy * 500) # Faster accuracy usually means faster RT in these tests participant = f"{student.get('First Name', '')} {student.get('Last Name', '')}".strip() cpid = student.get('StudentCPID', 'UNKNOWN') # Test specific logic if 'Problem_Solving' in test_name or 'Reasoning' in test_name: total_rounds = 26 if age_group == '14-17' else 31 correct = int(total_rounds * accuracy) incorrect = total_rounds - correct if 'SBDM' in test_name: # Special schema return { "Participant": participant, "Student CPID": cpid, "Total Rounds Answered": total_rounds, "Total Rounds not Answered": int(0), "Overall C_score": int(correct * 2), "Overall N_score": int(incorrect), "Overall I_Score": int(random.randint(5, 15)), "Average C_Score": float(round((correct * 2.0) / total_rounds, 2)), "Average N_Score": float(round(float(incorrect) / total_rounds, 2)), "Average I_Score": float(round(random.uniform(0.5, 1.5), 2)), "Average Reaction Time for the task": float(round(float(rt_baseline) + random.uniform(-100, 200), 2)) } return { "Participant": participant, "Student CPID": cpid, "Total Rounds Answered": total_rounds, "Total Rounds not Answered": 0, "No. of Correct Responses": correct, "No. of Incorrect Responses": incorrect, "Total Score of the Task": correct, "Average Reaction Time": float(round(float(rt_baseline + random.uniform(-100, 300)), 2)) } elif 'Cognitive_Flexibility' in test_name: total_rounds = 72 correct = int(total_rounds * accuracy) incorrect = total_rounds - correct return { "Participant": participant, "Student CPID": cpid, "Total Rounds Answered": total_rounds, "Total Rounds not Answered": 0, "No. of Correct Responses": correct, "No. of Incorrect Responses": incorrect, "Total Score of the Task": correct, "Average Reaction Time": float(round(float(rt_baseline * 0.8), 2)), "No. of Reversal Errors": int(random.randint(2, 8)), "No. of Perseveratory errors": int(random.randint(1, 5)), "No.of Final Reversal Errors": int(random.randint(1, 3)), "Win-Shift rate": float(round(float(random.uniform(0.7, 0.95)), 2)), "Lose-Shift Rate": float(round(float(random.uniform(0.1, 0.3)), 2)), "Overall Accuracy": float(round(float(accuracy * 100.0), 2)) } elif 'Color_Stroop' in test_name: total_rounds = 80 congruent_acc = accuracy + 0.05 incongruent_acc = accuracy - 0.1 return { "Participant": participant, "Student CPID": cpid, "Total Rounds Answered": total_rounds, "Total Rounds not Answered": 0, "No. of Correct Responses": int(total_rounds * accuracy), "No. of Correct Responses in Congruent Rounds": int(40 * congruent_acc), "No. of Correct Responses in Incongruent Rounds": int(40 * incongruent_acc), "No. of Incorrect Responses": int(total_rounds * (1-accuracy)), "No. of Incorrect Responses in Congruent Rounds": int(40 * (1-congruent_acc)), "No. of Incorrect Responses in Incongruent Rounds": int(40 * (1-incongruent_acc)), "Total Score of the Task": int(total_rounds * accuracy), "Congruent Rounds Average Reaction Time": float(round(float(rt_baseline * 0.7), 2)), "Incongruent Rounds Average Reaction Time": float(round(float(rt_baseline * 1.2), 2)), "Average Reaction Time of the task": float(round(float(rt_baseline), 2)), "Congruent Rounds Accuracy": float(round(float(congruent_acc * 100.0), 2)), "Incongruent Rounds Accuracy": float(round(float(incongruent_acc * 100.0), 2)), "Overall Task Accuracy": float(round(float(accuracy * 100.0), 2)), "Interference Effect": float(round(float(rt_baseline * 0.5), 2)) } elif 'Sternberg' in test_name: total_rounds = 120 correct = int(total_rounds * accuracy) return { "Participant": participant, "Student CPID": cpid, "Total Rounds Answered": total_rounds, "Total Rounds not Answered": 0, "No. of Correct Responses": correct, "No. of Incorrect Responses": total_rounds - correct, "Total Score of the Task": correct, "Average Reaction Time for Positive Probes": float(round(float(rt_baseline * 1.1), 2)), "Average Reaction Time for Negative Probes": float(round(float(rt_baseline * 1.15), 2)), "Average Reaction Time": float(round(float(rt_baseline * 1.12), 2)), "Overall Accuracy": float(round(float(accuracy * 100.0), 2)), "Hit Rate": float(round(float(accuracy + 0.02), 2)), "False Alarm Rate": float(round(float(random.uniform(0.05, 0.15)), 2)), "Slope of RT vs Set Size": float(round(float(random.uniform(30.0, 60.0)), 2)), "Response Bias": float(round(float(random.uniform(-0.5, 0.5)), 2)), "Sensitivity (d')": float(round(float(random.uniform(1.5, 3.5)), 2)) } elif 'Visual_Paired' in test_name: total_rounds = 45 correct = int(total_rounds * accuracy) return { "Participant": participant, "Student CPID": cpid, "Total Rounds Answered": total_rounds, "Total Rounds not Answered": 0, "No. of Correct Responses": correct, "No. of Incorrect Responses": total_rounds - correct, "Total Score in Immediate Cued Recall test": int(random.randint(10, 15)), "Total Score in Delayed Cued Recall test": int(random.randint(8, 14)), "Total Score in Recognition test": int(random.randint(12, 15)), "Total Score of the Task": int(correct), "Immediate Cued Recall Average Reaction Time": float(round(float(rt_baseline * 1.5), 2)), "Delayed Cued Recall Average Reaction Time": float(round(float(rt_baseline * 1.6), 2)), "Recognition Phase Average Reaction time": float(round(float(rt_baseline * 1.2), 2)), "Average Reaction Time": float(round(float(rt_baseline * 1.4), 2)), "Immediate Cued Recall Accuracy Rate": float(round(float(accuracy * 100.0), 2)), "Delayed Cued Recall Accuracy Rate": float(round(float((accuracy - 0.05) * 100.0), 2)), "Recognition Phase Accuracy Rate": float(round(float((accuracy + 0.05) * 100.0), 2)), "Overall Accuracy Rate": float(round(float(accuracy * 100.0), 2)), "Consolidation Slope": float(round(float(random.uniform(-0.5, 0.1)), 2)), "Consolidation Slope (%)": float(round(float(random.uniform(-10.0, 5.0)), 2)) } elif 'Response_Inhibition' in test_name: total_rounds = 60 correct = int(total_rounds * accuracy) return { "Participant": participant, "Student CPID": cpid, "Total Rounds Answered": total_rounds, "Total Rounds not Answered": 0, "No. of Correct Responses": correct, "No. of Correct Responses in Go Rounds": int(40 * accuracy), "No. of Correct Responses in No-Go Rounds": int(20 * (accuracy - 0.1)), "No. of Incorrect Responses": total_rounds - correct, "No. of Incorrect Responses in Go Rounds": int(40 * (1-accuracy)), "No. of Incorrect Responses in No-Go Rounds": int(20 * (1-(accuracy-0.1))), "Total Score of the Task": correct, "Go Rounds Average Reaction Time": float(round(float(rt_baseline * 0.8), 2)), "No- Rounds Average Reaction Time": float(round(float(rt_baseline * 1.2), 2)), "Average Reaction Time of the task": float(round(float(rt_baseline), 2)), "Go Rounds Accuracy": float(round(float(accuracy * 100.0), 2)), "No-Go Rounds Accuracy": float(round(float((accuracy - 0.1) * 100.0), 2)), "Overall Task Accuracy": float(round(float(accuracy * 100.0), 2)), "No. of Commission Errors": int(random.randint(2, 10)), "No. of Omission Error": int(random.randint(1, 5)), "Omission Error Rate": float(round(float(random.uniform(0.01, 0.05)), 2)), "Hit Rate": float(round(float(accuracy), 2)), "False Alarm Rate": float(round(float(random.uniform(0.1, 0.3)), 2)) } # Default fallback return { "Participant": participant, "Student CPID": cpid, "Total Rounds Answered": 0, "Total Score of the Task": 0 }