exercise_knowledge.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. """习题与知识点编码的匹配、范围过滤。"""
  2. from __future__ import annotations
  3. from app.models import Exercise
  4. from app.utils.knowledge_codes import knowledge_family_prefix, split_knowledge_codes
  5. def exercise_matches_knowledge_point(ex: Exercise, selected_code: str) -> bool:
  6. sel = (selected_code or "").strip()
  7. if not sel:
  8. return False
  9. raw = (getattr(ex, "knowledge_code", None) or "").strip()
  10. if not raw:
  11. return False
  12. ex_codes = split_knowledge_codes(raw)
  13. if not ex_codes:
  14. ex_codes = [raw]
  15. if sel in ex_codes:
  16. return True
  17. fam = knowledge_family_prefix(sel)
  18. if fam:
  19. for c in ex_codes:
  20. if c.startswith(fam) or c == sel:
  21. return True
  22. return False
  23. def exercise_matches_any_selected(ex: Exercise, selected_codes: list[str]) -> bool:
  24. return any(exercise_matches_knowledge_point(ex, c) for c in selected_codes if c.strip())
  25. def exercise_in_grade_category_scope(
  26. ex: Exercise,
  27. knowledge_grade: str | None,
  28. knowledge_category: str | None,
  29. ) -> bool:
  30. """题量补足:仅允许与当前页面所选年级、类别一致(题目需有对应元数据)。"""
  31. g_req = (knowledge_grade or "").strip()
  32. c_req = (knowledge_category or "").strip()
  33. if not g_req and not c_req:
  34. return False
  35. g_ex = (getattr(ex, "knowledge_grade", None) or "").strip()
  36. c_ex = (getattr(ex, "knowledge_category", None) or "").strip()
  37. if g_req and g_ex != g_req:
  38. return False
  39. if c_req and c_ex != c_req:
  40. return False
  41. return bool(g_ex or c_ex)