I thought of that approach as well, but I picked another answer just because the explanation of why it was correct was simpler. There were a couple like that, where I picked the simplest possible right answer, and didn’t think too hard about the other options.
Yeah, this was a result of some discussions on Ideas, so it leaned a bit more into the esoterica. Maybe I’ll make a quiz aimed at more normal code, but still touching on a few quirks. Would people enjoy that?
14/20. That was a fun quiz, thank you!
I struggled with two of the questions, in particular:
- “Python has more kinds of parameters than arguments”
I thought Python had positional and keyword arguments and parameters, i.e. I answered “The same number of each”. What are the types of parameters that do not have a corresponding argument type?
- f"{{1:1}[1]}"
This one is throwing me for a loop. Why is it not valid? It raises SyntaxError: f-string: single '}' is not allowed
, but I honestly can’t figure out why.
Python has two (2) types of arguments, and three (3) types of parameters. They are: Positional arguments, keyword arguments; positional-only parameters, pos-or-kwd parameters, and keyword-only parameters.
The mismatched numbers of them still correspond with each other, just like the gondoliers and their wives who discovered that two husbands had managed to acquire three wives, which means of course, that there’s two thirds of a husband for each wife. (“My good sir, one can’t marry a vulgar fraction!” “You’ve no right to call me a vulgar fraction!!”)
As for f"{{1:1}[1]}"
… well, you might think that the braces make a dictionary, but they don’t. Actually the opening double brace is not indicating a dictionary inside an expression, but a literal open brace. You can make this valid by inserting some extra space in there: f"{ {1:1}[1] }"
which will make it a dictionary being subscripted. (The space before the close brace isn’t necessary, it’s the one splitting the opening pair that does the trick.) Things are seldom what they seem!
Did you get mine? It looks like you haven’t opened it, and the error is still there.
Huh. Thanks for letting me know. Normally I get a ping when I get a DM, but for some bizarre reason, yours didn’t notify me. It is there though, and I’m reading it now. Discourse, why??
15/20
Learned some things
The question that has 4 correct answers had me confused for the longest. That was mean
Fair’s fair!
I scored 17/20, and really felt like I learned something with this. Thanks!
-
It’s a quite annoying that for questions with multiple correct answers, the quiz doesn’t reveal all of the other correct answers after you finish the quiz (if you selected one of the correct answers).
-
I think that some of the questions with multiple valid answers aren’t marked with
(Multiple correct answers)
like the others. (What can you do with just the standard library? and Which one of these is valid Python code?) -
I think that instead of annotating individual questions with
(Multiple correct answers)
you should just explain the rules in the preamble text. Something along the lines ofSome of the questions have multiple valid answers. In these cases, selecting any one of the correct options will be accepted.
and then not tell us, which of the questions have multiple valid answers.
Agreed. I originally tried to create this quiz on several other sites, but unless I paid them money, they were going to limit me to something crazy (one had “10 questions per quiz, 20 responses per month across all quizzes”). I didn’t feel like implementing my own web site just for this.
Ah, that may be an error on my part, I’ll check back. I would very much have liked for most of that to be automated, but again, limits of the technology I’m using.
One cheap workaround is to setup the quiz as Discourse polls and vote the correct answers yourself but disclose the poll results to answerers only after they vote. The obvious downside is that there will be no automatic scoring though.
For example:
What output will the following code produce?
class A:
def foo():
foo: int
return foo()
foo = lambda: 0
print(A.foo())
- 0
- UnboundLocalError
- RecursionError
- TypeError

One cheap workaround is to setup the quiz as Discourse polls and vote the correct answers yourself but disclose the poll results to answerers only after they vote. The obvious downside is that there will be no automatic scoring though.
Hmm, interesting. How do people know which one’s right? In this case, I know I was right because the only two votes were mine and yours; but short of hovering to see, it would just show the most popular choice.
But worth keeping as an option, anyhow!

How do people know which one’s right? In this case, I know I was right because the only two votes were mine and yours; but short of hovering to see, it would just show the most popular choice.
Yeah I was thinking that people would see who posted the poll and find answers that the poster voted for.
EDIT: By the way I just noticed that people are allowed to change their votes after they see the results, so probably not a good option as a quiz after all.

Yeah I was thinking that people would see who posted the poll and find answers that the poster voted for.
Gotcha. Could get tedious when there are a couple dozen responses, but it’s there.

EDIT: By the way I just noticed that people are allowed to change their votes after they see the results, so probably not a good option as a quiz after all.
Yeah, that would be a critical failure if I were trying to judge people’s knowledge, but if people want to pretend that they totally knew that all along, they’re only cheating themselves
Question: While I understand the “risk” of open(fn).read()
, under what circumstances can I prove that the risk is real? Doesn’t the file always get closed when the file object gets automatically deleted from the reference count becoming 0 after the call to the read
method returns? I’ve even tried calling gc.disable()
first and the result is still the same, that the file gets closed as soon as read()
returns.

Question: While I understand the “risk” of
open(fn).read()
, under what circumstances can I prove that the risk is real? Doesn’t the file always get closed when the file object gets automatically deleted from the reference count becoming 0 after the call to theread
method returns?
Python does not guarantee that reference counting is used. CPython currently does use that, but other Pythons (eg Jython) don’t.
The with
statement guarantees that the file is closed, even if you have other references to it. Example:
f = open(fn)
data = f.read()
print(data)
# file hasn't been closed
print(f)
vs
with open(fn) as f: data = f.read()
print(data)
# file HAS been closed but you still have a reference to it
print(f)

I’ve even tried calling
gc.disable()
first and the result is still the same, that the file gets closed as soon asread()
returns.
Yep. Importantly, that does NOT disable all garbage collection; it disables the optional garbage collecion, which handles cyclic references.
>>> class Loop:
... def __init__(self):
... self.self = self
... def __del__(self):
... print("Bye-bye!")
...
>>> print(Loop())
<__main__.Loop object at 0x7fbbe5d58440>
>>> import gc
>>> gc.collect()
Bye-bye!
7
>>>
This is the downside of reference counting. A mark-and-sweep garbage collector doesn’t care about reference loops like this, but to a refcounter, they’re a problem, and need to be dealt with separately.
Since Python, as a language, doesn’t specify any of this, it is entirely possible for a valid implementation to use either, or any other type of garbage collection (eg “deallocate objects in batches for efficiency”). Thus, if you actually care about disposing of something - when there’s an associated resource to clean up, as with an open file - you need to ask the object to clean itself up, rather than relying on its __del__
method.
Hope that explains it!
That does clear things up. Thanks!
The font makes “Which of these is a valid integer literal?” quite evil
17/20. I have really let my language lawyer skills drop in my old age.

The font makes “Which of these is a valid integer literal?” quite evil
I know, and I thought that I actually had no control over that. Turns out that there IS a way, although it wasn’t obvious (and comes at the cost of making the descriptive text at the top uglier, bt I’m fine with that). Future quiz-takers, this should be a bit better for you. Sorry all!