Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- import re
- import base64
- start = 111705
- ans = {
- 'Q01': 'C', 'Q02': 'B', 'Q03': 'A', 'Q04': 'A', 'Q05': 'B',
- 'Q06': 'A', 'Q07': 'A', 'Q08': 'A', 'Q09': 'C', 'Q10': 'A',
- 'Q11': 'B', 'Q12': 'A', 'Q13': 'A', 'Q14': 'D', 'Q15': 'A',
- 'Q16': 'B', 'Q17': 'C', 'Q18': 'A', 'Q19': 'C', 'Q20': 'A',
- 'Q21': 'B', 'Q22': 'B', 'Q23': 'A', 'Q24': 'B', 'Q25': 'C'
- }
- IMG_DIR = "img"
- OUT_FILE = "moodle_questions.xml"
- # Expected filename pattern: microtk_jan-apr_2025_001.png ... 025.png
- # We'll sort by the trailing number before extension if present; otherwise lexicographic.
- num_pat = re.compile(r"(\d+)(?=\.[A-Za-z]+$)")
- def sort_key(fn: str):
- m = num_pat.search(fn)
- return (int(m.group(1)) if m else 10**9, fn)
- files = [f for f in os.listdir(IMG_DIR) if os.path.isfile(os.path.join(IMG_DIR, f))]
- files = [f for f in files if f.lower().endswith((".png", ".jpg", ".jpeg", ".gif", ".webp"))]
- files.sort(key=sort_key)
- if len(files) != 25:
- raise SystemExit(f"Expected 25 images in '{IMG_DIR}', found {len(files)}: {files}")
- def b64_of(path: str) -> str:
- with open(path, "rb") as f:
- return base64.b64encode(f.read()).decode("ascii")
- def answer_block(letter: str, correct_letter: str) -> str:
- frac = "100" if letter == correct_letter else "-25"
- return f''' <answer fraction="{frac}" format="html">
- <text><![CDATA[<p>Option {letter}</p>]]></text>
- <feedback format="html">
- <text></text>
- </feedback>
- </answer>'''
- template = """<!-- question: {qid} -->
- <question type="multichoice">
- <name>
- <text>{qname}</text>
- </name>
- <questiontext format="html">
- <text><![CDATA[<p><img src="@@PLUGINFILE@@/{fname}"></p>]]></text>
- <file name="{fname}" path="/" encoding="base64">{b64}</file>
- </questiontext>
- <generalfeedback format="html">
- <text></text>
- </generalfeedback>
- <defaultgrade>1.0000000</defaultgrade>
- <penalty>0.0000000</penalty>
- <hidden>0</hidden>
- <idnumber></idnumber>
- <single>true</single>
- <shuffleanswers>false</shuffleanswers>
- <answernumbering>ABCD</answernumbering>
- <showstandardinstruction>0</showstandardinstruction>
- <correctfeedback format="html">
- <text><![CDATA[<p>Your answer is correct.</p>]]></text>
- </correctfeedback>
- <incorrectfeedback format="html">
- <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
- </incorrectfeedback>
- <shownumcorrect/>
- {answers}
- </question>
- """
- xml_parts = ['<?xml version="1.0" encoding="UTF-8"?>\n<quiz>\n']
- qid = start
- for i, fname in enumerate(files, start=1):
- qname = f"Q{i:02d}"
- correct = ans[qname].upper()
- if correct not in ("A", "B", "C", "D"):
- raise SystemExit(f"Invalid correct option for {qname}: {correct}")
- b64 = b64_of(os.path.join(IMG_DIR, fname))
- answers = "\n".join([
- answer_block("A", correct),
- answer_block("B", correct),
- answer_block("C", correct),
- answer_block("D", correct),
- ])
- xml_parts.append(template.format(
- qid=qid,
- qname=qname,
- fname=fname,
- b64=b64,
- answers=answers
- ))
- xml_parts.append("\n")
- qid += 1
- xml_parts.append("</quiz>\n")
- with open(OUT_FILE, "w", encoding="utf-8") as f:
- f.write("".join(xml_parts))
- print(f" Generated: {OUT_FILE}")
Add Comment
Please, Sign In to add comment