Repository navigation
Expand file tree
/
Copy pathstudy_question_utils.py
More file actions
67 lines (55 loc) · 2.63 KB
/
Copy pathstudy_question_utils.py
File metadata and controls
67 lines (55 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
from __future__ import annotations
import re
from typing import Any
from question_bank import sanitize_text
def normalized_study_label(value: str) -> str:
text = " ".join(str(value or "").replace("&", "and").replace(",", " ").split()).casefold()
aliases = {
"security program management and oversight": "security program management and oversight",
"threats vulnerabilities and mitigations": "threats vulnerabilities and mitigations",
"threats vulnerability and mitigations": "threats vulnerabilities and mitigations",
}
return aliases.get(text, text)
def primary_topic_label(question: dict[str, Any]) -> str:
topics = tuple(str(topic).strip() for topic in question.get("topics", []) if str(topic).strip())
domain = str(question.get("domain") or "Unsorted")
if topics:
return normalized_study_label(topics[0])
return normalized_study_label(domain)
def coverage_unit_for_question(question: dict[str, Any]) -> tuple[str, str]:
objective_code = str(question.get("objective_code") or "").strip()
if objective_code:
return ("Objective", objective_code)
topic = primary_topic_label(question)
if topic and topic != "Unsorted":
return ("Topic", topic)
return ("Domain", normalized_study_label(str(question.get("domain") or "Unsorted")))
def stem_style_for_question(question: dict[str, Any]) -> str:
prompt = sanitize_text(str(question.get("prompt") or "")).lower()
if not prompt:
return "General"
if re.search(r"\b(except|least|not)\b", prompt):
return "Exception"
if re.search(r"\b(best|most|primary)\b", prompt):
return "Best fit"
if re.search(r"\b(first|next|initial|immediate)\b", prompt):
return "Order"
if re.search(r"\b(root cause|likely|why|cause|diagnos|issue|failure|problem)\b", prompt):
return "Troubleshooting"
if re.search(r"^(what|which)\s", prompt) and re.search(
r"\b(defines?|describes?|term|acronym|stands for|known as)\b", prompt
):
return "Definition"
if len(prompt.split()) >= 22 or re.search(r"\b(should|implement|use|respond|handle|mitigate)\b", prompt):
return "Scenario"
return "General"
def question_mentions_label(question: dict[str, Any], label: str) -> bool:
needle = str(label or "").strip()
if not needle:
return False
haystack = " ".join(
[str(question.get("prompt") or "")] + [str(text or "") for text in (question.get("choices") or {}).values()]
)
if needle.isupper() and len(needle) <= 8:
return re.search(rf"\b{re.escape(needle)}\b", haystack) is not None
return needle.lower() in haystack.lower()