exam module¶
Functions¶
- exam.make_answer_key(exam)¶
Creates an answer key for a multiple-choice exam by wrapping each correct answer option in a
\hl{}command for highlighting.- Parameters:
exam (MCExam) – An
MCExaminstance whose elements will be copied and annotated.- Returns:
A deep copy of
exam.elementswith correct options highlighted.- Return type:
dict
Classes¶
- class exam.MCQuestion(question_string=None, correct_string=None)¶
Stores and manages the content of a single multiple-choice question.
The
\alland\nonespecial tokens are recognised only when they appear on a\itemline, so occurrences of those strings elsewhere in the question body are not misread as answer choices. Detected tokens are removed from the options list and tracked as boolean flags so they are always appended last during export.- Parameters:
question_string (str, optional) – The full LaTeX content of the question, including its options block. Defaults to None.
correct_string (str, optional) – The marker that identifies the correct answer (e.g.,
'CORRECT'). Defaults to None.
- correct_string: str¶
The marker token used to identify correct answer options.
- question_string: str¶
The original full LaTeX string for the question.
- question_header: str¶
The
\shuffle{...}or\noshuffle{...}header portion of the question.
- to_shuffle: bool¶
Whether the options should be shuffled. False when
\noshuffleis used.
- options: list of str¶
List of answer option strings (each prefixed with
\item). The\alland\noneoptions are not stored here; they are tracked as boolean flags and appended during export.
- all_of_above: bool¶
Whether an “All of the above” option is present.
- none_of_above: bool¶
Whether a “None of the above” option is present.
- all_of_above_correct: bool¶
Whether “All of the above” is the correct answer.
- none_of_above_correct: bool¶
Whether “None of the above” is the correct answer.
- shuffle_options(rng)¶
Returns a new
MCQuestionwith answer options in a randomized order. The\alland\noneoptions are unaffected because they are stored as flags and always appended last during export.- Parameters:
rng (numpy.random.Generator) – Random number generator used for shuffling.
- Returns:
A new
MCQuestioninstance with options reordered.- Return type:
- add_periods(include_equations=True, correct_string=None)¶
Adds a period to the end of each option’s main text if one is absent. When an option ends with a LaTeX math expression (
$...$), a period is appended only wheninclude_equationsis True. The correct-answer token is moved to the very end of the comment.- Parameters:
include_equations (bool, optional) – Whether to add a period after trailing math expressions. Defaults to True.
correct_string (str, optional) – Override for the correct-answer token. Defaults to None, which falls back to
self.correct_string.
- Returns:
None
- capitalize_first(correct_string=None)¶
Capitalizes the first letter of each option’s main text.
- Parameters:
correct_string (str, optional) – Override for the correct-answer token (accepted for a consistent signature but unused here). Defaults to None.
- Returns:
None
- class exam.MCGroup(group_lines, correct_string)¶
Stores and manages a group of related multiple-choice questions delimited by
\begin{mcgroup}{N}{header}and\end{mcgroup}in the LaTeX source.- Parameters:
group_lines (list of str) – Lines of LaTeX that make up the group block, excluding the
\end{mcgroup}line.correct_string (str) – The marker for correct answers, passed through to each
MCQuestion.
- correct_string: str¶
The marker token used to identify correct answer options.
- group_header: str¶
The descriptive header text from the
\begin{mcgroup}{N}{header}line.
- group_count: int¶
The number of questions in the group (taken from the parsed source and corrected to match the actual count if they differ).
- elements: dict¶
Mapping of integer index to
MCQuestionobjects within this group.
- shuffle_questions(rng)¶
Returns a new
MCGroupwith questions in a randomized order.- Parameters:
rng (numpy.random.Generator) – Random number generator used for shuffling.
- Returns:
A deep copy of this group with questions reordered.
- Return type:
- shuffle_options(rng)¶
Returns a new
MCGroupwith each question’s options shuffled.- Parameters:
rng (numpy.random.Generator) – Random number generator used for shuffling.
- Returns:
A deep copy of this group with options reordered.
- Return type:
- add_periods(include_equations=True, correct_string=None)¶
Adds periods to option text for all questions in the group. See
MCQuestion.add_periodsfor full parameter details.- Parameters:
include_equations (bool, optional) – Whether to add a period after trailing math expressions. Defaults to True.
correct_string (str, optional) – Override for the correct-answer token. Defaults to None.
- Returns:
None
- capitalize_first(correct_string=None)¶
Capitalizes the first letter of each option for all questions in the group.
- Parameters:
correct_string (str, optional) – Override for the correct-answer token. Defaults to None.
- Returns:
None
- class exam.MCExam(exam_file=None, exam_lines=None, correct_string='CORRECT', seed=None)¶
Stores and manages the content of a multiple-choice exam. Reads a LaTeX file, isolates the
mcquestionsenvironment, and parses it intoMCQuestionandMCGroupobjects. Also builds the answer key and computes letter labels.When
exam_fileis None the instance is initialized to a valid empty state. The preferred way to build anMCExamfrom a string rather than a file isMCExam.from_string().- Parameters:
exam_file (str, optional) – Path to the LaTeX exam file. Defaults to None.
exam_lines (list of str, optional) – Pre-read lines (currently unused; kept for API compatibility). Defaults to None.
correct_string (str, optional) – Marker for the correct answer. Defaults to
'CORRECT'.seed (int, optional) – Seed for the internal random number generator. Defaults to None.
- correct_string: str¶
The marker token used to identify correct answer options.
- filepath: pathlib.Path¶
Resolved absolute path to the source file, or None if no file was given.
- filename: str¶
Name of the source file, or None if no file was given.
- elements: dict¶
Mapping of integer index to
MCQuestionorMCGroupobjects in source order.
- answer_key: dict¶
Deep copy of
elementswith correct options wrapped in\hl{}.
- mc_answer_letters: list of str¶
One entry per question (or sub-question). Each entry is a comma-separated string of correct-answer letter labels (e.g.,
'(b)').
- question_count: int¶
Total number of individual questions, counting each sub-question within a group separately.
- classmethod from_string(tex, correct_string='CORRECT', seed=None, source_path=None, filename_hint=None)¶
Builds an
MCExamdirectly from a LaTeX string without a file on disk.- Parameters:
tex (str) – LaTeX source containing an
mcquestionsenvironment, or raw question content.correct_string (str, optional) – Marker for the correct answer. Defaults to
'CORRECT'.seed (int, optional) – Seed for the internal RNG. Defaults to None.
source_path (str, optional) – Path of the originating file, used to set
self.filepath. Defaults to None.filename_hint (str, optional) – Short filename to assign to
self.filename. Defaults to None.
- Returns:
A fully initialized
MCExaminstance.- Return type:
- print_exam()¶
Prints the content of the exam to the console.
- Returns:
None
- print_answer_key()¶
Prints the answer key for the exam to the console.
- Returns:
None
- show_duplicates()¶
Displays any duplicate answer options found across all exam questions.
- Returns:
None
- to_latex(key=False)¶
Returns the full LaTeX string for this exam without writing to disk.
- Parameters:
key (bool, optional) – If True, return the answer key version. Defaults to False.
- Returns:
Complete LaTeX source for the exam or answer key.
- Return type:
str
- export_exam(filename=None)¶
Exports the student exam to a LaTeX file.
- Parameters:
filename (str, optional) – Destination path. Defaults to the original filename.
- Returns:
The LaTeX string that was written.
- Return type:
str
- export_key(filename=None)¶
Exports the answer key with correct answers highlighted to a LaTeX file.
- Parameters:
filename (str, optional) – Destination path. Defaults to the original filename with
'_Key'appended before the extension.- Returns:
The LaTeX string that was written.
- Return type:
str
- export_mc_answers_to_text(filename=None, header_text=None, mc_start=1)¶
Exports the MC answer letters to a plain-text file. Each line contains a question number and its correct-answer letter, e.g.
'1. (b)'.- Parameters:
filename (str, optional) – Destination path. Defaults to the original filename with
'_MC_Answers.txt'appended before the extension.header_text (str, optional) – A title line written at the top of the file, followed by a blank line. Defaults to None.
mc_start (int, optional) – The global question number assigned to the first MC question. Useful when MC questions do not start at question 1 in the overall exam. Defaults to 1.
- Returns:
The text that was written to the file.
- Return type:
str
- shuffle_questions(filename=None, seed=None, shuffle_within_groups=True)¶
Returns a new exam with questions shuffled. When at least one standalone
MCQuestionexists, one is always placed first; the remaining standalone questions and anyMCGroupobjects are then randomly interleaved. When the exam contains onlyMCGroupobjects, all groups are shuffled without the forced-first-question step.- Parameters:
filename (str, optional) – Filename for the returned exam object. Defaults to the original stem with
'_questions_shuffled.tex'appended.seed (int, optional) – Random seed for reproducibility. Defaults to None.
shuffle_within_groups (bool, optional) – Whether to also shuffle questions within each
MCGroup. Defaults to True.
- Returns:
A new
MCExaminstance with shuffled questions.- Return type:
- shuffle_options(filename=None, seed=None)¶
Returns a new exam with answer options shuffled within each question. The
\alland\noneoptions always remain at the end because they are stored as flags and appended during export.- Parameters:
filename (str, optional) – Filename for the returned exam object. Defaults to the original stem with
'_options_shuffled.tex'appended.seed (int, optional) – Random seed for reproducibility. Defaults to None.
- Returns:
A new
MCExaminstance with shuffled options.- Return type:
- shuffle_options_and_questions(filename=None, seed=None, shuffle_within_groups=True)¶
Returns a new exam with both options and questions shuffled.
- Parameters:
filename (str, optional) – Filename for the returned exam object. Defaults to the original stem with
'_options_shuffled.tex'appended.seed (int, optional) – Random seed for reproducibility. Defaults to None.
shuffle_within_groups (bool, optional) – Whether to shuffle questions within groups. Defaults to True.
- Returns:
A new
MCExaminstance with shuffled options and questions.- Return type:
- add_periods(include_equations=True)¶
Adds periods to the end of answer choice text throughout the exam.
- Parameters:
include_equations (bool, optional) – Whether to add a period after trailing math expressions. Defaults to True.
- Returns:
None
- capitalize_first()¶
Capitalizes the first letter of each answer choice throughout the exam.
- Returns:
None
- set_seed(seed=None)¶
Sets the random seed for the exam’s internal random number generator.
- Parameters:
seed (int, optional) – Seed value. Defaults to None.
- Returns:
None
- class exam.FRExam(filename=None)¶
Handles free-response exams using the
\question[points]syntax. Reads a LaTeX file and parses all\questionblocks into a list of question dicts.\input{}commands that reference files containing a\questiontoken are expanded automatically; figure and TikZ inputs inside answer blocks are left untouched.- Parameters:
filename (str, optional) – Path to the LaTeX exam file. If provided, the file is read and parsed immediately. Defaults to None.
- filepath: pathlib.Path¶
Resolved absolute path to the source file, or None if no file was given.
- filename: str¶
Name of the source file, or None if no file was given.
- questions: list of dict¶
List of parsed question dicts. Each dict has keys
'file'(source filename),'points'(int or None), and'text'(full LaTeX string for the question).
- classmethod from_string(tex, source_path=None, filename_hint=None)¶
Builds an
FRExamdirectly from a LaTeX string without a file on disk. Whensource_pathis provided its parent directory is used to resolve any\input{}commands that reference sub-files containing a\questiontoken.- Parameters:
tex (str) – LaTeX source containing free-response question content.
source_path (str, optional) – Path of the originating file, used to resolve relative
\input{}paths. Defaults to None.filename_hint (str, optional) – Short filename to assign to
self.filename. Defaults to None.
- Returns:
A fully initialized
FRExaminstance.- Return type:
- to_latex(key=False)¶
Returns the full LaTeX string for this free-response exam.
- Parameters:
key (bool, optional) – If True, reveal answer environments. Defaults to False.
- Returns:
Complete LaTeX source for the exam or answer key.
- Return type:
str
- export_exam(filename=None)¶
Exports the student exam version (answers hidden) to a LaTeX file.
- Parameters:
filename (str, optional) – Destination path. Defaults to
'FR_Exam.tex'in the same directory as the source file.- Returns:
None
- export_key(filename=None)¶
Exports the answer key version (answers revealed) to a LaTeX file.
- Parameters:
filename (str, optional) – Destination path. Defaults to
'FR_Key.tex'in the same directory as the source file.- Returns:
None
- reveal_answers(text=None)¶
Returns the exam text with
\begin{answer}...\end{answer}blocks expanded.- Parameters:
text (str, optional) – LaTeX text to process. Defaults to the concatenated text of all stored questions.
- Returns:
LaTeX text with answer environments expanded.
- Return type:
str
- summary(max_chars=80)¶
Prints a summary of all parsed free-response questions, showing the question number, point value, source file, and a short preview of the question text.
- Parameters:
max_chars (int, optional) – Maximum number of characters to show in the question preview. Defaults to 80.
- Returns:
None
- class exam.Exam(filename, mc=None, fr=None, correct_string='CORRECT', seed=None)¶
Combines
MCExamandFRExamcontent into a single LaTeX document. Auto-detects MC and FR sections from\input{}statements or inline environments. Pre-builtMCExamandFRExamobjects may be passed directly to bypass auto-detection.- Parameters:
filename (str) – Path to the main exam LaTeX file.
mc (MCExam, optional) – Pre-parsed multiple-choice exam. Defaults to None (auto-detect).
fr (FRExam, optional) – Pre-parsed free-response exam. Defaults to None (auto-detect).
correct_string (str, optional) – Marker for correct MC answers. Defaults to
'CORRECT'.seed (int, optional) – Random seed for reproducibility. Defaults to None.
- mc: MCExam or None¶
The multiple-choice portion of the exam.
- fr: FRExam or None¶
The free-response portion of the exam.
- shuffle_options(seed=None, filename=None)¶
Returns a new
Examwith shuffled MC options, preserving FR questions.- Parameters:
seed (int, optional) – Random seed for reproducibility. Defaults to None.
filename (str, optional) – If provided, sets the base path for subsequent
export_examandexport_keycalls.
- Returns:
A deep copy of this
Examwith MC options shuffled.- Return type:
- to_latex(key=False)¶
Returns the full LaTeX string for the combined MC and FR exam. Raises
ValueErrorif the assembled output does not contain exactly onemcquestionsand onefrquestionsenvironment.- Parameters:
key (bool, optional) – If True, produce the answer key version. Defaults to False.
- Returns:
Complete LaTeX source for the exam or answer key.
- Return type:
str
- Raises:
ValueError – If an environment appears more or fewer than once.
- export_exam(filename=None)¶
Exports the combined student exam (no answers, no key-only content) to a LaTeX file.
- Parameters:
filename (str, optional) – Destination path. Defaults to the source filename with
'_Exported'appended before the extension.- Returns:
None
- export_key(filename=None)¶
Exports the combined instructor key (FR answers shown, key-only content included) to a LaTeX file.
- Parameters:
filename (str, optional) – Destination path. Defaults to the source filename with
'_Exported_Key'appended before the extension.- Returns:
None
- export_mc_answers_to_text(filename=None, header_text=None)¶
Exports the MC answer letters to a plain-text file with correct question numbering, even when FR questions precede the MC section. Scans the assembled exam to determine whether
frquestionsappears beforemcquestions, and if so counts the FR questions to compute the MC start number automatically.- Parameters:
filename (str, optional) – Destination path. Defaults to the source filename with
'_MC_Answers.txt'appended before the extension.header_text (str, optional) – A title line written at the top of the file, followed by a blank line. Defaults to None.
- Returns:
The text that was written to the file, or None if there are no MC questions.
- Return type:
str or None
- summary()¶
Prints a short summary of the combined exam’s MC and FR content.
- Returns:
None
- verify_integrity(latex_text=None)¶
Runs basic consistency checks on the combined exam LaTeX. Verifies that each expected environment appears exactly once and that no unresolved
\inputstatements remain.- Parameters:
latex_text (str, optional) – LaTeX text to check. Defaults to
self.to_latex(key=False).- Returns:
True if all checks pass, False otherwise.
- Return type:
bool