← Back to Projects

ExamEngineer

Authoring, randomization, and automatic grading of engineering exercises — paper exams to LMS deployment

Writing exams by hand in LaTeX is tedious and error-prone — copy formulas, plug in numbers, hope you didn't make a sign error in the solution, and repeat. ExamEngineer eliminates that entire class of mistakes. You write each equation once; the system computes numeric results, converts units, and typesets both the exam paper and the matching solution booklet automatically.

It now goes one step further: ExamEngineer pushes individualized exercises directly into THD's iLearn (Moodle) LMS, hands every enrolled student a numerically unique variant of the same task, downloads their submissions, and writes back grades and feedback automatically — turning weekly homework from a hand-correction backlog into a self-paced practice loop.

Built for day-to-day use at Technische Hochschule Deggendorf. In production use across multiple engineering modules in Mechanical Engineering & Mechatronics.

New: Individualized Exercises in iLearn

ExamEngineer integrates with iLearn, THD's Moodle instance, via the Moodle Web Services REST API. For every student enrolled in a course, the system generates a personal variant of an exercise with different numerical values, uploads the corresponding PDF as feedback file, and reads submissions back automatically.

course roster (iLearn)  ──▶  per-student seed  ──▶  randomized PDF
                                                       │
                                                       ▼
                                              uploaded to iLearn
                                                       │
student submits answers  ──▶  download & compare  ──▶  grade + feedback
       (iLearn)                  (within tolerance)       written back
  • Per-student randomization — each variant uses a deterministic seed derived from the student ID, so the same student always gets the same task on re-render.
  • Automatic distribution — the personal task PDF is attached to the student's iLearn assignment as feedback file before the deadline.
  • Numeric answer comparison — submitted result variables are matched against the computed reference values within configurable tolerances; partial credit per sub-question is supported.
  • Grade write-back — points and per-question feedback are pushed back to the iLearn gradebook through mod_assign_save_grade; students see their progress in the standard Moodle UI.
  • Practice tool, not high-stakes assessment — designed as a self-learning feedback loop for weekly exercises, with all the same problems available offline as paper exams in the assembler.

How It Works

problem.yaml  ─┐
problem.yaml  ─┤──▶  Python pipeline  ──▶  exam.tex      ──▶  exam.pdf
exam.yaml     ─┘     (SymPy + Pint)       solution.tex  ──▶  solution.pdf
                                          collection.qmd ──▶  HTML book
                                          per-student    ──▶  iLearn

Problems are defined as YAML files with typed content modules — variables, equations, display instructions, images, plots. An exam YAML simply lists which problems to include and sets header metadata. The Python pipeline loads everything, solves the equations symbolically, renders LaTeX via Jinja2 templates, and compiles to PDF with LuaLaTeX. The same source feeds paper exams, HTML course books, and per-student iLearn assignments — one definition, many channels, zero manual arithmetic.

Example problem definition

id: "impedance_001"
title: "AC Circuit Impedance"
language: "de"

modules:
  - type: variables
    variables:
      R: { value: "10 ohm" }
      C: { value: "47 uF" }
      f: { value: "50 Hz" }

  - type: question
    credits: 3
    question: "Calculate the impedance $Z$."
    modules:
      - type: unknowns
        unknowns:
          Z: { unit: "ohm" }
      - type: equation
        equation: "Z = R + 1/(j*2*pi*f*C)"
        show: solution   # only appears in solution booklet

The system computes Z, formats it as a complex number with units, and places the full solution step in the solution booklet while showing only the question in the exam version. The same YAML, with value ranges added, generates one variant per student for iLearn.

Key Features

  • Individualized exercises in iLearn (Moodle) with automatic grading

    ExamEngineer connects to THD's iLearn Moodle instance via the Web Services API. For every enrolled student, it generates a numerically unique variant of the same exercise, uploads the personal task PDF as feedback, and downloads submitted solutions. The student's reported answers are compared to the computed reference values within tolerance, and a grade plus per-question feedback is written back to the iLearn gradebook automatically. A practice tool, not a high-stakes exam channel — but it scales to entire cohorts without manual correction.

  • Automatic solution generation

    Equations are solved symbolically with SymPy and evaluated with full unit tracking via Pint. No manual calculations, no transcription errors. The same equation definition produces both the exam question and the worked solution.

  • Exam randomization with validation

    Define value ranges for each variable and constraints on computed results. The system generates valid random instances via rejection sampling and reports the success rate before you deploy — every student receives a unique, guaranteed-solvable exercise with realistic numbers.

  • Reusable problem library

    Problems are YAML building blocks. Once written, they can be dropped into any future exam, collection, or iLearn assignment. Variable values can be overridden per use without modifying the original. The library grows with every semester.

  • Composable content modules

    Each problem is assembled from typed modules: text, equations, variables, unknowns, images, function plots (pgfplots), code listings (minted), and raw LaTeX. No LaTeX knowledge required for everyday authoring.

  • Three-panel web frontend

    A browser-based IDE with the problem library on the left, a five-tab editor in the middle (Preview, Edit, Math, Log, Solution), and the exam/collection assembler on the right. Schema-assisted editing, live PDF preview, randomization checks, and one-click builds — all without touching a terminal. Built with Flask and HTMX.

  • Correction assistant

    A grading helper lets instructors enter student results and pin wrong intermediate values. Downstream results recalculate automatically, making partial-credit grading on paper exams faster and more consistent.

  • HTML/Quarto export for course materials

    Collections can be exported as Quarto projects in addition to PDF — one chapter per problem or a single scrollable document — for publishing exercises and worked solutions as browser-readable course material.

  • Incremental builds & validation

    A Make-based build system only recompiles what changed. YAML inputs are validated against JSON schemas before processing — errors surface as plain-language messages, not Python tracebacks.

  • Multi-language & accessible typography

    German and English, with locale-aware number formatting. Body text in Atkinson Hyperlegible Next and formulas in IBM Plex Math — optimized for readability under exam conditions.

Technical Stack

Component Role
Python 3.12 Core pipeline, symbolic computation (SymPy), unit handling (Pint), templating (Jinja2)
LuaLaTeX PDF compilation via fontspec, minted (code), pgfplots (function plots)
Flask + HTMX Three-panel web IDE for authoring, library management, randomization, PDF preview, and build triggering
Moodle Web Services API iLearn integration: per-student variants, PDF distribution, submission download, automatic grading and feedback
Quarto Optional HTML export of exercise collections as course-material books or single documents
JSON Schema Validation of all YAML inputs before processing
GNU Make Incremental, dependency-tracked builds with parallel compilation support

Status

In production use for multiple engineering modules at THD — Electrical Engineering, Mechatronics, and Mechanical Engineering. The problem library is continuously growing as legacy exams are migrated to the YAML format. The iLearn integration is being piloted in the module Elektrische Antriebe in coordination with THD's Innovative Lehre department, with a dedicated Web-Service token scoped to the course. ExamEngineer is being prepared for open-source release. If you teach engineering courses at a university and are looking for a better way to manage exams and weekly exercises, I'd love to hear from you — early adopters who can bring additional problem types and field experience are especially welcome.

Interested?

If you'd like to use ExamEngineer in your own courses or institution, I'm happy to help get you started.

Get in touch