VG151 — Midterm 1: A Chronicle

(All timezones are UTC+8)

2022-10-19 10:00, Zoom

The ENGR151 teaching team (TT for short) gathered online for our first exam preparation. At first we thought the exam would be online and spent an hour thinking of ways to prevent cheating, as there has never been an online coding exam. We have a few questions on their project (for example how did you plot your rectangles in matlab) that would be super easy to cheat on, so Manuel proposed an oral exam (as was tried on international students who attended this course online constantly).

Fortunately, this exam model was never tried because we got news that next week will be offline again, after more than one month of lockdown.

The exam consists of two parts: part A is on paper, and part B is coding. We created a Gitea issue to track our ideas for part B.

2022-10-19 11:08, Gitea

One TA submitted their idea to the thread. It's about Sierpiński triangles. I know where they found it: the Wikipedia article on recursion, section "In Mathematics".

Evolution of a Sierpiński triangle

2022-10-19 16:46, Gitea

Another idea emerged. It was about a basic line interpreter that takes a file of definitions of shapes (position, size, color, etc) and plots them accordingly.

2022-10-19 17:47, Gitea

And here's my idea: I was taking discrete math, and in set theory they have this trick where you represent a natural number n + 1 with n U {n} (where U stands for union). So, if we take 0 to be the empty set {}, 1 is {} U {{}} = {{}}, 2 is {{}} U {{{}}} = {{}, {{}}}, etc etc. Here's my code:

function set_theory
        n = input('Input a natural number: ');
        disp(n2s(n));
end

function s = n2s(n)
        % convert natural number to set theory representation
        if n == 0
                s = '{}';
                return
        elseif n == 1
                % handle edge case where we need no comma
                s = '{{}}';
                return
        end

        s1 = n2s(n - 1);
        % pretty much a hack: strip the trailing },
        % push s1, and put the } back
        s = [s1(1:end-1) ', ' s1, '}'];
        return
end

I thought it was a simple exercise, almost too simple as long as you know how recursion works.

2022-10-20 13:06, Gitea

Manuel has read all our ideas, and decided to go with two:

  • The shape interpreter, and
  • My set theory recusive algorithm

However, he commented that the interpreter needs to be more challenging, and that he will remove the set theory notation from mine in favor of something else, but it remained a mystery at the moment.

2022-10-20 17:15, Gitea

Babe wake up, new interpreter specifications just dropped

We added:

  • compose instruction that works like classes
  • fill colors
  • absolute or relative movement

2022-10-21 21:15, Mattermost

Manuel put together an early draft of the testpaper for us to check. There are three exercises:

  • One exercise about the shape interpreter
  • One exercise about some alien sci-fi in the Minami-ke lore
  • One exercise about RGB image manipulation

The sci-fi goes like this: (paraphrased)

Minami Haruka shows her sisters a weird device she found with a keypad and a screen. When she presses 0, screen reads -.; 1 → --.., 2 → --._--..., and 3 → --._--.._--._--.....

Kana suspects that aliens are using this device to "communicate as they plan to invade campus", but Haruka found a pattern. What pattern?

- is {, . is }, and _ is ,.

Now that the lore is over, the questions are

  • What is 4
  • Diagram of recursion
  • Base case
  • Steps repeated
  • Describe algorithm
  • Implement algorithm
  • What is 12

I admire Manuel's imagination that exploded an innocent set theory notation to make such a bizzare scenario.

Also, another side effect is, the order of this sequence is well-defined. No need to worry about {{}, {{}}} and {{{}}, {}}.

2022-10-22 19:28, Mattermost

Manuel sent us his semi-ready version of the testpaper, on which I discovered a flaw:

Convert from hexadecimal into binary: 16, AG.

I reported it to Manuel, expecting him to fix it:

pretty sure AG isn't a hex number

Here's how he replied:

AG i know this is not hexadecimal, but do they? :smirk_cat:

I like tricky questions...

when they ask us duirng [sic] the exam we just tell them if they think there is a mistake they explain it

At this moment I knew our students are about to be bamboozled. We'll wait and see…

Also, there was a sample output image for the shape interpreter exercise. On the screen it looks like this (cropped so I don't get sued):

A color image with green, yellow, cyan, red and black

However, I'd imagine the paper would be printed in grayscale, which means it will look like this:

Grayscale of previous image; everything is either black or the same
shade of 50% grey

Manuel changed the grayscale method to HSL (Hue, Saturation, Luminance) so it looks better:

Still grayscale but colors are distinct

2022-10-23 11:00, Mattermost

A few more typos and ambiguities are fixed, but there came another problem: the image Manuel asked students to manipulate, forest.tif, is part of an image processing toolbox, so we switched to corn.tif to be safe.

2022-10-23 17:19, Mattermost

The exam papers are ready for printing.

2022-10-26 13:18, Gitea

I created e1 repos for everyone and drafted an announcement for testtakers to clone it.

2022-10-27 13:50, UEO

Menako got the exam papers in a bag from UEO.

2022-10-27 15:45, exam room

We had 85 students — 78 of which took the exam offline. We had 44 in our exam room, the rest in another.

We unsealed the package of testpapers, and found this thing:

Grayscale image, but now the sun is also black and fused into the
road

As a fix, when part B began we would project the image we intended on the screen.

2022-10-27 16:00, exam room

The bell struck and the exam commenced. Little did they know, they were in for a big surprise. Hands in the room I proctored rose in confusion. "Excuse me," one asked, "this question doesn't look quite right to me."

I asked, "what's the problem with it?"

They replied, "I don't think G is a—"

"Just write down what you think. Manuel's probably thinking the same thing."

Participatory exam: an exam where students are not the only ones taking it; instead, proctors play a major part in maintaining the effect of trick questions. We indeed tried very hard not to spoil it.

It's official folks, exam proctoring is a performance art now.

2022-10-27 16:30, exam room

Time for part B. I walked around, and was amazed by the multitude of laptop models in the modern age. I guess half-tablet half-keyboard C-sides are a thing now?

At least three testtakers got confused halfway through exercise 3, waved at me and asked "what's the corn image?" I shrugged and told them to read on.

2022-10-27 17:35, exam room

One testtaker raised a question:

In exercise 1 (shape interpreter) we provided some sample code to be interpreted. One line goes

square background cyan (0,0) 20 20

Another goes

square road black (0,-5) 10

Obviously they are off by one parameter. Turns out the specification and the second line were changed, but the first one wasn't. We ended up issuing an erratum 10 minutes before the exam ends.

2022-10-27 17:45, exam room

It's time to submit everything to Gitea. I had a flash drive in case someone's antenna melts, but it turned out unnecessary. The process was simple as git add ./; git commit -m 'e1'; git push then opening a release called e1 on Gitea.

We collected and counted the exam papers, then dismissed the exam.

2022-10-27 17:57, exam room

All e1 repos are archived. As our room was mostly empty, we went ahead to the other room which Manuel was a proctor of.

I assigned myself to exercise 2 of part B, because that's the way karma works; I contributed the idea after all. So did the TA who made exercise 1. Menako assigned herself to most of Part A, and expected to begin grading that night.

Discussion rooms in Longbin Building, the official building of Joint Institute, were not open for booking, so we had to use Manuel's office. He handed Menako his key. It was the rarest of in-game items, uncraftable by any means.

2022-10-27 18:37, McDonald's

The rest of the TA group had plans that night so Menako and I had burgers at McD's, then rode off to Longbin Bldg.

2022-10-27 19:00 or something, Manuel's office

Manuel's office is tiny. Crappy monitor, crappy keyboard, but many chairs and a bookshelf of math textbooks.

Exercise 2 was the only one in part B to require answers on paper or the README file, so the first thing I did was to classify the answer sheets based on where they wrote them. That night I graded everything on paper, but wasn't able to read all the README files.

Menako, on the other hand, graded part A with blazing efficiency. What quickly grabbed our attention was how she should grade the AG question. After some discussion, we agreed upon this rubric:

  • If you think G is 16 (or any other number), you get zero points.
  • If you leave this question blank, you get full marks.
  • If you explain that G is not a hexadecimal digit, you get full marks plus a star (no points, but it's a token of prestige).

She finished her part that night.

2022-10-27 23:00 or something, [undisclosed location]

I need to come up with a way to grade the last question (what is 12) without going through the trouble to scan through all 10,239 characters (that's how long it is). And the solution? Checksum.

I grep'd everyone's README.md for >10k-character long sequences of -_., piped them to md5sum, then sorted them. The command is

$ grep -hoE '[-_\.]{10000,}' FILE.md | md5sum

There were 7 different versions:

  • One is empty;
  • One is correct;
  • One is correct if you strip one dot (they wrote it in a markdown ordered list) from the beginning;
  • One is truncated at 10k characters because they copied it from the variable window instead of command window. No point for you, sorry.
  • The other three are incorrect.

Subsequently I spent a dozen minutes committing the grades with a red pen on paper. As this question is worth one point, I just treated it as atomic.

That night I also graded all the README's.

2022-10-28 12:55, Manuel's office

The next day I went back to Manuel's office again, this time to get things done for once and for all. All my colleagues came along (except Menako). The desk was crowded but fortunately I'm mostly done with paper, so I took a corner to grade all the code.

My rubrics are based on four criteria:

  • Base case (2pt)
  • Recursive case (3pt)
  • Coding style (1pt)
  • Your code doesn't crash (1pt)

Yes, if your code is unindented or looks like a mess, I will take away one point.

And there are two special rules:

  • Iterative algorithms get no point
  • Marginally recursive algorithms get 4pt max.

What counts as marginally recursive? Well, consider this Python snippet:

def alien(number, string, target):
    if number == target:
        return string
    string = string[:-1] + "_" + string + "."
    return alien(number + 1, string, target)

print(alien(1, "--..", 3))

Does it work? Yes. Does it yield the correct result? Yes! Is it recursive?

…Maybe?

I mean, it does call itself. But it's not what we meant! Observe how number grows larger and string longer as we go to the deeper level. Recursion as we taught in the lectures was the opposite: breaking down the problem until it falls within the base case(s). Furthermore, this is tail recursion, which is just iteration with extra steps.

2022-10-28 16:42, Manuel's office

Part A is finished for all paper submissions.

2022-10-28 17:09, Manuel's office

Part A is finished for international students also.

2022-10-28 20:21, Manuel's office

Grading finished for the whole exam.

2022-10-28 20:34, Mattermost

We begin discussing curves. Manuel remarked:

no rush to publish grade. you graded too fast!!

and

fastest 101/151 grading ever!!! :partying_face:

We decide to delay the release, at least not until the next weekday.

2022-10-29 10:02, Mattermost

Remember on 2022-10-23 we switched to corn.tif for Part B ex3 "to be safe"? Huge mistake. It turned out, corn.tif wasn't an RGB image as we thought it was — it was an indexed image, which means it comes in two parts:

  • A list of key-value pairs of color indexes and RGB values
  • A matrix of indexes

To convert it to RGB, you need to call ind2rgb. At first this was part of our rubric, but after a while we found it too harsh, so we just awarded points to whoever processed it correctly as if it were RGB.

2022-11-01 09:00, Canvas

Grades are released. Paper checking is scheduled at 2022-11-03 20:20-22:20.

2022-11-03 20:00, meeting room

I arrived at the meeting room reserved for the paper checking session and laid out the testpapers. A few eager students were waiting outside.

As time went on, the room became increasingly crowded. A line appeared by my side, asking for points.

The single most asked question is:

Why did I get zero for "write an algorithm"? I wrote it in my code!

For context, we have two contiguous subquestions:

  • Write an algorithm describing how the conversion works
  • Implement the algorithm in matlab

Both were assigned 7 points, so you see the importance of the former. What I was expecting was:

  • A piece of text
  • Pseudocode
  • Comments in code

Sadly, many assumed "my code is self-documenting, it answers both questions." Sorry, you're misinterpreting what we meant by an algorithm.

There was one case though, I forgot to check someone's README file somehow, and wasn't aware they wrote pseudocode. I read it, and it made all the sense I wanted to see. Ka-ching, 7 points. The same person had their Part B ex1 grade bumped by 6 points (grade looked like 10, but was actually 16). That's 13 points in total. So lucky.

That's a wrap!

This is everything that (a) I feel like sharing and (b) I am allowed to share.