Learner Profile module. It consumes the profile file produced by ``Code/prepare/build_profile.py``. The six fields follow the paper implementation: ``student_id, activity, diversity, preference, success_rate, IRT ability``.
| 20 | |
| 21 | |
| 22 | class Profile: |
| 23 | """Learner Profile module. |
| 24 | |
| 25 | It consumes the profile file produced by ``Code/prepare/build_profile.py``. |
| 26 | The six fields follow the paper implementation: |
| 27 | ``student_id, activity, diversity, preference, success_rate, IRT ability``. |
| 28 | """ |
| 29 | |
| 30 | def __init__(self, agent_id: int, data_path: str | Path | None = None): |
| 31 | path = Path(data_path or DATA_PATH) / "profile.json" |
| 32 | data = load_json(path) |
| 33 | raw = data.get(str(agent_id)) |
| 34 | if raw is None: |
| 35 | raise KeyError(f"No profile for agent/student id {agent_id} in {path}") |
| 36 | parts = str(raw).strip().split("\t") |
| 37 | if len(parts) < 6: |
| 38 | raise ValueError(f"Profile row must contain six tab-separated fields: {raw!r}") |
| 39 | self.values = LearnerProfileValues( |
| 40 | user_id=int(float(parts[0])), |
| 41 | activity_ratio=float(parts[1]), |
| 42 | diversity_ratio=float(parts[2]), |
| 43 | preference=normalize_concept(parts[3]), |
| 44 | success_rate_value=float(parts[4]), |
| 45 | ability_value=float(parts[5]), |
| 46 | ) |
| 47 | |
| 48 | def activity(self) -> str: |
| 49 | return "high" if self.values.activity_ratio > ACTIVITY_MEAN else "low" |
| 50 | |
| 51 | def diversity(self) -> str: |
| 52 | return "high" if self.values.diversity_ratio > DIVERSITY_MEAN else "low" |
| 53 | |
| 54 | def preference(self) -> str: |
| 55 | return self.values.preference |
| 56 | |
| 57 | def success_rate(self) -> str: |
| 58 | ar = self.values.success_rate_value |
| 59 | if ar > 0.6: |
| 60 | return "high" |
| 61 | if ar > 0.3: |
| 62 | return "medium" |
| 63 | return "low" |
| 64 | |
| 65 | def ability(self) -> str: |
| 66 | ab = self.values.ability_value |
| 67 | if ab > 0.5: |
| 68 | return "good" |
| 69 | if ab > 0.4: |
| 70 | return "common" |
| 71 | return "poor" |
| 72 | |
| 73 | def build_prompt(self) -> str: |
| 74 | tips_act = { |
| 75 | "high": "you maintain a high level of online exercise activity and practice frequently", |
| 76 | "low": "you practice less regularly and with lower enthusiasm", |
| 77 | } |
| 78 | tips_div = { |
| 79 | "high": "you explore diverse knowledge categories", |