Skip to content

feat: uniform page length for Gradescope + confirm names pass through - #3

Merged
briacSck merged 2 commits into
mainfrom
feat/gradescope-uniform-page-length
Jul 23, 2026
Merged

briacSck merged 2 commits into
mainfrom
feat/gradescope-uniform-page-length

Conversation

@briacSck

Copy link
Copy Markdown
Owner

Summary

Implements Professor Chang's feedback from her first real batch.

Uniform page length (the fix)
Every student's exam PDF now comes out the same length so Gradescope's per-question template aligns without manual fixing. Three causes of variable length addressed:

  • One transcript page per scan page — _render_transcript_page shrinks font to fit a single page; dense pages no longer spill to 2-3 pages and shift structure. (pdf_assembler.py)
  • Batch-wide padding — every exam is padded to the longest exam in the batch with blank page pairs, so all outputs share one page count and question N lands on the same page for everyone. run_batch computes the batch max from ExamFile.page_count (no extra OCR) and threads it through. (pipeline.py, pdf_assembler.py)
  • No more part-split — the 95 MB _part1/_part2 split broke uniformity; replaced with a single-file lower-DPI fallback chain (lossless → 150 → 110 → 90). Oversize files are flagged in the run report instead of split.

Names/SIDs (no change needed — verified)
The tool already keeps names/SIDs visible on the Gradescope deliverable and masks only the copy sent to Mistral. Confirmed end-to-end on a real, non-anonymized exam: the .masked.png (API-bound) had the header blacked out; the output scan page showed Name and SID clearly. The censoring seen earlier was the pre-anonymized test set, not the program.

Test Coverage

  • test_transcript_forced_to_single_page — verbose transcript stays one page
  • test_pads_short_exam_to_target_length — padding to a target length
  • test_size_guard_stays_single_file — tiny size ceiling never splits, downsamples instead
  • test_run_batch_pads_all_outputs_to_uniform_length — two exams of different physical lengths produce equal page counts (2 × max)
  • Golden interleaved snapshot unchanged.

Verification

  • pytest: 63 passed
  • mypy: clean (19 source files)
  • ruff check: clean
  • Real-file mask/unmask check: passed (masked hides identity, output shows it)

Notes

  • Deliverable remains interleaved scan + transcript. If a scans-only Gradescope output is preferred later, that's a small follow-up.

🤖 Generated with Claude Code

briacSck and others added 2 commits July 23, 2026 22:34
Every student's exam PDF now comes out the same length so Gradescope's
per-question template lines up without manual fixing.

- Force exactly one transcript page per scan page (auto-shrink font to
  fit); dense pages no longer spill to 2-3 pages and shift structure.
- Pad every exam to the batch-wide maximum with blank page pairs, so all
  outputs share one page count and question N lands on the same page.
- Replace the 95 MB _part1/_part2 split (which broke uniformity) with a
  single-file lower-DPI fallback chain; oversize files are flagged in the
  run report instead of split.

Names/SIDs are unchanged: still masked only on the copy sent to Mistral,
kept visible on the Gradescope deliverable (verified end-to-end on a real
exam). Tests cover fit-to-one-page, padding, single-file guard, and
equal-length output across exams of different physical lengths.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Check in CLAUDE.md (project instructions), FABLE_OVERVIEW.md, and
FABLE_GAPS.md so the repo carries its own working context.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@briacSck
briacSck merged commit 49dd585 into main Jul 23, 2026
1 check passed
@briacSck
briacSck deleted the feat/gradescope-uniform-page-length branch July 23, 2026 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant