Skip to content

Exam quality — CS101 benchmarked against CS 61A Midterm 1 (Fall 2026)

CS 61A — Structure and Interpretation of Computer Programs, Midterm 1, Fall 2026 (UC Berkeley, DeNero/Rao lineage). Paper: https://cs61a.org/resources/fa26/mt1/61a-fa26-mt1.pdf Archive of every past paper with solutions: https://website.cs61a.org/resources/

50 minutes · 20 points · 4 questions · closed book, one A4 page of own notes, provided study guide. Marks 6 / 4 / 4 / 6.

Second reference: MIT 6.100L assessment structure — 10 microquizzes (30 min, in-class, on computer) + 5 problem sets + weekly finger exercises, weighted 45 / 45 / 10. Note the shape: frequent, small, executed, not one long paper.


>>> z = 'but'
>>> f = lambda g: g(z)
>>> z = 'so'
>>> x, y = print(1 or 2), (3 and 0)
>>> print(print(x, '=', y), '+', f(print), '= zero?')

Four blanks, 1–2 marks each. Every blank is a semantic trap: late binding of z into the lambda, print returning None, or/and yielding operands not booleans, print receiving a None argument. Nothing is recall. All of it is predicting execution — the exact skill the course claims to teach.

new_print shadows the builtin, then is applied to itself twice. The student must produce the output and is invited to draw an environment diagram, with labelled frames f1: [parent= ] … f5:. The question marks the model, not the answer: the frames are given, the parent links and return values are not.

Implement num_long_groups… You may not write str, len, if, else, [, ], 3, 4, 5, 6, 7, 8, or 9 in your answers.

Two fill-in-the-blank sub-expressions, each with 10 distractors. The ban is the question: it forces arithmetic digit extraction and boolean-free comparison, and it forecloses every one-liner a student might reach for. You cannot pass by recognising the pattern.

  • 4.1 implement gap (3 marks for one sub-expression).
  • 4.2 implement odd_gap, which must call gap — one blank.
  • 4.3 an A+ question worth 0 points, explicitly “not worth any points… finish the rest of the exam first”, also under a writing ban (for, if, and, or, map, filter, := all forbidden).

Part 3 depends on part 1 having been solved correctly; the marks say so (1 mark for the loop condition, 3 for the recurrence). A stretch question exists and is free.


DimensionCS61A MT1My CS101 paperVerdict
Cognitive taskPredict execution, implement under constraintRecall definitions, explain in proseMine is weaker
Prose requiredAlmost none~40% of marksMine rewards articulation over ability
Constraint questionsCore device (two of four questions)NoneAbsent
Execution-model artefactEnvironment diagramsNoneAbsent
Marks granularity1–2 per blank, 10 distractors per blank10 marks per problem, no distractorsMine is coarse
Part dependencyQ4.2 uses Q4.1Independent questionsAbsent
Stretch questionA+ worth 0NoneAbsent
Time per point2.5 min1.5 minMine is too tight for its own questions
Misconception trappingBuilt into every blankNamed in the teaching, tested by recallHalf-done
Bluff resistanceVery high — output is checkableLow — “state why” is markable but gameableMine is weaker

  1. A3, A4, A6, A7 are recall. “What does round(2.5) return” is answered by a memoriser. CS61A never asks a question a flashcard could pass.
  2. “State the reason” carries 1 mark in ten of my A-items. Prose about mechanism is not the same as mechanism. The real paper tests whether you can do it under a handicap.
  3. No constrained implementation. My B4 asks for a counter; CS61A would ban for, len, str and + to force the same solution by a different road.
  4. No execution-model artefact. I never ask for an environment diagram or a frame trace, so a student can pass while holding the wrong mental model of scope — the single most predictive misconception in introductory programming.
  5. 10-mark questions hide partial credit. With 10 marks on B1, a student who gets the rounding mode wrong loses 2 and the marker has to invent the rest. Two-mark sub-items make the scheme mechanical.
  6. No dependency between parts. CS61A’s 4.2 is only answerable if 4.1 is right, which tests composition. My questions are independent, so a student can score well with four disconnected competencies.
  7. No stretch. Nothing separates a Distinction from a quiet prodigy.

Replacement questions, written in the benchmark’s style

Section titled “Replacement questions, written in the benchmark’s style”

These replace A3/A4/A6 and B1. Same syllabus, same domain, real difficulty.

def make_fee():
rate = 0.18
fee = lambda gross: gross * rate
rate = 0.20
return fee
print(make_fee()(10000))

(a) Output? (b) Change one line so the output becomes 1800.0, and name the mechanism that makes your change work while the original does not.

*Verified: original prints 2000.0. The closure captures the name rate, not its value, so the rebinding after definition is visible at call time. A student holding the “captured at definition” model answers 1800 and cannot explain (b). The correct fix is a default argument, `lambda gross, r=rate: gross

  • r`, which is evaluated once at definition — which is also the clearest possible statement of the difference.*

R2 (4 marks) — constrained implementation

Section titled “R2 (4 marks) — constrained implementation”

Implement owed_pence(net_fee, paid) returning the amount still owed, using no comparison operators (<, >, <=, >=), no if, and no else, and returning 0 — never a negative number — when nothing is owed.

def owed_pence(net_fee, paid):
"""Return max(0, net_fee - paid) without comparison operators."""
return max(0, net_fee - paid)

The ban forces max, which is exactly the builtin the syllabus introduced for this. One mark for max, one for the subtraction not being reversed, two for 0 on the negative case.

R3 (3 marks) — environment diagram, marked

Section titled “R3 (3 marks) — environment diagram, marked”
def f(x):
def g(y):
return x + y
x = x * 2
return g
h = f(3)
print(h(1))

Complete the frames: f1: [parent= ] with locals at definition, at return g, and at the call to h. Output in one more blank.

Marks: 1 per frame’s locals, 1 for the return value 7 (not 4 — the closure sees the rebound x).

(a) Implement fee_rate(gross) returning 18 when gross >= 10000, else 15, without if/else (use arithmetic or a comparison’s truth value). (b) Now implement fee_pence(gross) calling fee_rate, returning the fee in pence rounded half up, for any gross ≥ 0.

Part (b) is unanswerable if (a) is wrong, which is the point. Marks: 2 for (a)‘s expression, 4 for (b) — 2 for delegating, 1 for half-up rounding, 1 for the pence conversion.


Added to course standards:

  1. No recall items. Every question predicts execution, implements under constraint, or diagnoses a supplied artefact.
  2. At least one constrained implementation per paper — a ban on the obvious construct, stated in the question.
  3. At least one execution-model artefact — environment diagram or frame trace, with the frames provided and the contents blank.
  4. Sub-items of 1–4 marks. No 10-mark questions.
  5. At least one dependent chain where part n+1 requires part n.
  6. A stretch item worth 0, explicitly marked as such.
  7. Prose capped: no more than 15% of marks may be answered in sentences.

My CS101 paper measures whether a student can talk about Python. The CS61A paper measures whether a student can run Python in their head under a handicap. Mine is a well-formatted comprehension test; theirs is an assessment. The difference is not wording or marking — it is that every question in theirs has a right answer a machine could verify, and every question in mine can be bluffed by a student who has read the chapter.

Fixed by rewriting the paper against R1–R4’s pattern, not by adding more questions.