Buckets:
| import re, json | |
| txt = open('/work/_pages.txt').read() | |
| pages = txt.split('\n\f\n') | |
| assert len(pages) == 195 | |
| EXAM_BOUNDS = [('A', 3, 50), ('B', 51, 115), ('C', 116, 164), ('D', 165, 195)] | |
| def clean(s): | |
| return re.sub(r'\s+', ' ', s).strip() | |
| def parse_exam(letter, start, end): | |
| blob = '\n'.join(pages[start-1:end]) | |
| blocks = re.split(r'\n(?=QUESTION \d+\n)', blob) | |
| recs = [] | |
| for b in blocks[1:]: | |
| m = re.match(r'QUESTION (\d+)\n', b) | |
| if not m: | |
| continue | |
| qnum = int(m.group(1)) | |
| body = b[m.end():] | |
| page = None | |
| for i in range(start, end + 1): | |
| if re.search(r'(^|\n)QUESTION %d\n' % qnum, pages[i-1]): | |
| page = i | |
| break | |
| if page is None: | |
| page = start | |
| is_dd = body.lstrip().startswith('DRAG DROP') | |
| om = re.search(r'(^|\n)A\. ', body) | |
| stem = clean(body[:om.start()]) if om else '' | |
| options = {} | |
| if om: | |
| opt_zone = body[om.start():] | |
| ca = re.search(r'(^|\n)Correct Answer:', opt_zone) | |
| oz = opt_zone[:ca.start()] if ca else opt_zone | |
| pairs = re.findall(r'([A-E])\. ((?:(?!\n[A-E]\. |\nCorrect Answer:).)+)', oz, re.S) | |
| for k, v in pairs: | |
| options[k] = clean(v) | |
| cm = re.search(r'Correct Answer: ([A-E ]*)', body) | |
| correct = cm.group(1).strip() if cm else '' | |
| if is_dd: | |
| correct = '' | |
| expl = '' | |
| em = re.search(r'(^|\n)Explanation(/Reference)?:?\s*\n', body) | |
| if em: | |
| tail = body[em.end():] | |
| tail = re.sub(r'(^|\n)Reference:\s*\n?', '', tail) | |
| tail = tail.split('\nhttps://')[0] | |
| tail = re.sub(r'\nVendor:.*$', '', tail, flags=re.S) | |
| tail = clean(tail) | |
| if tail and not re.fullmatch(r'(https?://\S*\s*)*', tail): | |
| expl = tail | |
| has_exhibit = 'Refer to the exhibit' in body | |
| recs.append({ | |
| 'exam': letter, 'qnum': qnum, 'page': page, | |
| 'stem': stem, | |
| 'options': options, 'correct': correct, | |
| 'explanation': expl, 'has_exhibit': has_exhibit, | |
| }) | |
| return recs | |
| recs = [] | |
| for letter, s, e in EXAM_BOUNDS: | |
| recs.extend(parse_exam(letter, s, e)) | |
| assert len(recs) == 388, len(recs) | |
| n_ex = sum(r['has_exhibit'] for r in recs) | |
| n_dd = sum(1 for r in recs if r['correct'] == '') | |
| n_expl = sum(1 for r in recs if r['explanation']) | |
| print('records:', len(recs), 'exhibit:', n_ex, 'dragdrop/empty-correct:', n_dd, 'with explanation:', n_expl) | |
| assert 70 <= n_ex <= 95 and 20 <= n_dd <= 30 | |
| with open('/work/questions_all.jsonl', 'w') as f: | |
| for r in recs: | |
| f.write(json.dumps(r) + '\n') | |
| print('wrote questions_all.jsonl') | |
Xet Storage Details
- Size:
- 2.76 kB
- Xet hash:
- 7002dafbbb8583ccef38b5e2952a1355a0ed3af1bf5f3c6f45cf2708da25a8b4
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.