A1 postmortem — what the class got wrong

The mistakes that came up in enough files to be worth writing once rather than seventeen times, and the two the assignment page caused.

Published

September 8, 2026

A1 is marked, and your own feedback is in your DMs. This is the other half: the things that came up in enough files to be worth writing once rather than seventeen times. Nobody’s code is quoted here.

There is a theme, and it is worth naming before the list. The parts of a program have to agree with each other, and nothing in Pyret makes them. Most of what follows is a version of that.

The helper and the flag never met

Step 5 asked for a helper — a function computing one measurement from another, the height from the width. Step 6 asked for flag. In most files those two never meet. The helper sits at the top, correct and unused, and flag works out its height a second time further down.

That is not a complaint about style. It means the file can contradict itself and nothing notices — and this is not hypothetical. Seven of the seventeen files say one thing and draw another.

The shape of it is always the same. The helper says the height is two-thirds of the width, because 3:2 is the ratio the assignment page happened to use in its example. The flag then draws something else — three stripes at a quarter of the width each, say, which makes the flag three-quarters as tall as it is wide. The function directly above the picture states a proportion the picture does not have. Every where: example still passes, because the examples only ever ask the helper about itself. Nothing in Pyret compares the rule to the drawing.

These are not careless files; several of them are among the best submitted. And in most of the seven the flag is the correct half — the student drew the flag they meant to draw, and the 2/3 is a leftover that came off the assignment page rather than out of their own design. That is the quiet version of this problem, and it is the reason it went unnoticed: nobody wrote anything wrong. They just never made the two halves talk to each other.

No points came off for this, and where they had, they have been put back. An error in seven files out of seventeen is a problem with how I set the assignment, not with the seventeen of you, and the page has been rewritten. It will cost points on A2, when the page is no longer the reason.

The fix is one line — have flag call the helper:

fun flag(unit :: Number) -> Image:
  width = unit * 3
  height = flag-height(width)
  ...
end

Now there is one answer in the file instead of two. Change your mind about the ratio and you change it in one place, and the picture follows — and if the rule and the drawing ever disagree, they disagree loudly instead of quietly. Five of you did this, and those files are the easiest to read.

Where your examples came from

The assignment page printed a flag-height with its body left as ... and three examples filled in:

where:
  flag-height(30) is 20
  flag-height(0) is 0
  flag-height(10) is 20/3

Five files handed all three of those back unchanged, and a sixth kept two. There is nothing dishonest about that — it was sitting on the page. But look at what those three lines actually claim: they describe a flag whose height is two-thirds of its width, because that is the ratio the page picked for its illustration. If your flag is not 3:2, you have written down three promises about somebody else’s flag and then checked that you can keep them.

That is the previous problem again, one level up. Your examples are supposed to be about your flag — your ratio, your numbers, worked out by hand.

Nobody lost a point for copying those three lines, and if you did lose one, you have it back. The page printed the whole block already worked out and never once said the examples had to be about the flag you drew. Five of you copied it, which is a fact about the page and not about the five of you. I have rewritten that step so the worked example is now the area of a square, which cannot be pasted into a flag.

A separate point, and this one is worth points on the next assignment. An example should be an answer you worked out, not the body’s formula copied across:

flag-height(30) is 30 * 2/3
flag-height(30) is 20

What separates these two is not what they say but where they came from. Copy the expression out of the body and the example inherits whatever is wrong with the body — the same misread ratio, the same slip in the arithmetic — and then happily agrees with it. It is checking that you can copy, which you can.

The 20 had to come from somewhere else: you divided 30 by 3 and doubled it, on paper, before the body existed. Now there are two independent routes to the same number, and a test is only worth running when the two routes could disagree.

Writing 20/3 rather than 6.667 is not the same thing at all — that is an exact answer you worked out, and it is the right way to write one down.

A colour name should say what the colour is for

Step 3 told you to name your colours, and several files did it like this:

red = "red"
white = "white"

Those lines buy you nothing. red is exactly as informative as "red", and a reader now has to go and find the binding to learn what they already knew. The same step said a name should say what a thing is, not what it is made of — stripe-height, not twenty. red = "red" is twenty = 20 for colours.

The near miss is worse than the no-op:

purple = "lavender"

At the call site that reads as purple, and what you get is lavender. The name now tells a reader something slightly untrue, where the plain "lavender" would have told them exactly the truth. That is the one way a name can be worse than the value it replaced.

Name the job instead:

stripe-color = "lavender"
background-color = "white"

That says what the colour is doing, gives you one place to change your mind, and cannot drift away from its value.

This one was my fault as much as anyone’s: step 3 only told you to stop repeating a colour string, which does not say what to call it instead. The A1 page has been updated with the rule above.

unit is a length, not a scale factor

“One change to unit rescales the whole flag” got read two ways. Most of you took unit for a small length — twenty pixels or so — and built every measurement as a multiple of it. A couple took it for a multiplier and wrote things like unit * 300. That is a fair reading of the sentence, and the code scales perfectly; it also makes flag(60) about eighteen thousand pixels wide, which is more picture than anything can draw.

Nobody lost points for it. But it is a good argument for the contract: when a function takes a number, say what kind of number, and pick examples that make its size obvious.

Step 7 asked for one expression

Six files drew three flags on three separate lines. That gives you three pictures, which is not the point. One expression puts the three sizes into a single image, side by side, where you can see at a glance that the shapes are identical and only the scale changed — which is the whole claim step 4 asked you to make:

beside(beside(flag(30), flag(60)), flag(90))

beside takes exactly two images, so three of anything means nesting one call inside another. Same trick as putting above inside overlay.

The design recipe, in numbers

Across all 17 submissions:

did it
Types on the helper 12 of 17
doc: on the helper 12 of 17
Three or more where: examples 13 of 17
Examples worked out for their own flag 7 of 17
Types on flag 9 of 17
doc: on flag 11 of 17
Helper actually called inside flag 5 of 17
Helper states a rule the flag breaks 7 of 17

The top of that list is in good shape — most of you write the contract and the purpose without being nagged for them. The bottom rows are the ones to carry into A2: an example that is about your own design, a helper the rest of the file actually uses, and a rule that describes the flag you actually drew.

If you want the procedure the top rows are measuring, it is on the design recipe page.