In this post about coding for predictions, I wrote a sentence that got edited out of the final draft, but that’s played on repeat in my head ever since.
Students don’t need simple examples. They need clear ones.
I’m realizing that this catchy little antithesis is essentially my whole teaching philosophy rolled up into one line.
Before we get too much further, I need to introduce some vocabulary to you that I’ve come to rely on. I borrowed the word “pseudocontext” from master teacher and founder of Desmos, Dan Meyer, who in turn borrowed it from education researcher Jo Boaler.
You should absolutely go and read their more-thoughtfully crafted definitions of the word pseudocontext, but if you’re in a rush, I’ll share my favorite example.
The following word problem is from a section of the textbook called “real-world connections” but I’ll let you decide how “real-world” it is:
In January of the year 2000, I was one more than eleven times as old as my son William. In January of 2009, I was seven more than three times as old as him. How old was my son in January of 2000?
I’ve complied non-comprehensive list of complaints I have for this real-world problem’s narrator:
I could go on, but you get my drift.
From this example, we can derive a working definition of Pseudocontext that we can use to examine CS tasks.
So here’s the hot take of this article: Any time your code snippets for students use non-meaningful placeholders like “foo” or “bar”, you’ve created pseudocontext.
Looking at the definition of pseudocontext, we can reverse engineer its antonym.
You may notice that by this definition, real context doesn’t actually require using intricate technical best practices — it just requires thinking about whether or not the user is being asked to do something that they might, even without your direction, still choose to do out of curiosity.
So now that we’ve got our working definition in place, let’s examine some code snippets.
In theory, a code snippet is an example of the concept “in action,” and so a lot of learn-to-code guides imagine that simply seeing a code snippet counts as real-world context. But if those code snippets still include strings like "foo"
and "bar"
or variable names like my_str
or my_list
, then that’s a good sign that this code lacks any real context.
All of the following example code snippets are taken from well-respected online guides and resources intended for beginners — names withheld because I don’t intend to call anyone out, I just have ideas for how to improve them before using them in class.
If you ever write “foo” or “bar” in your code, you’ve messed up.
Here’s an example:
str1 = "foo"
str2 = "bar"str3 = str1 + str2
print(str3)
The structure of this example is actually really wonderful. You’re showing concatenation in action. But because we’ve stripped this example of all its context, there’s no reason a first-time learner would intuit what’s happening here.
Here’s the revision:
first_name = "Ada"
last_name = "Lovelace"full_name = first_name + last_name
print(full_name)
You’ve shown the EXACT same mechanical operation as before, only now you’re allowing your students to apply their intuition about the external world to their programming.
This isn’t making things easier — it’s making them clearer.
If you find yourself using the name my_function
you’ve definitely missed the mark.
Here’s an example from a really well-respected online Python guide:
def my_function():
print("Hello from a function")my_function()
This is a function in its most atomic form, and so it makes sense as the starting point, but starting here means that a first time learner can’t figure out why this would ever be useful. From their perspective, we’ve just written three lines of code to print a string — something we could already do in a single line of code.
I’m not just being critical; I made this exact mistake. When I used say_hello()
as my introduction the first time I taught functions, my beginners started to suspect that functions don’t add any utility: “This seems like print statements with extra steps…”
Layering in functionality after that took about 10 different examples, and about 45 minutes, and that’s just simply too long to make using functions feel helpful.
Here’s a revision that adds some context:
def get_permissions(name, age):
permissions = ["G", "PG"]
if age > 12:
permissions.append("PG-13")
if age > 17:
permissions.append("R")
print(f'Permissions granted for {name}')
return permissionsuser1_permissions = get_permissions("Yessenia", 17)
user2_permissions = get_permissions("Grace", 14)print(user2_permissions)
I think that this setup is complicated, but not prohibitively so. If students have some working knowledge of lists, they’re ready to tackle this example with the support of some scaffolded questions:
How many times am I defining
get_permissions
? How did you know?
How many times am I calling(using/running)get_permissions
?In this example, how old is Yessenia? Which movies should she be allowed to see?
What’s the name of the variable where I’m storing Yessenia’s permissions?When I run
get_permissions
for Grace, which movies should be in her list?Why, when I run this code, will I see Grace’s list, but not Yessenia’s?
After we run this example, I find it helpful to play with it a bit more: “Okay, Javi, do you want us to do yours? You’re 18, correct? We’ll make you user 3.”
After that, students may not have recognized the full extent of how powerful functions can be, but they will have a really firm grasp of how get_permissions
works, and they’ll be ready to pin down important vocabulary like functions, calls, arguments, parameters, and returns in a far more meaningful way.
And then we can conclude this intro with a conversation about how we could do this without using a function, and why this approach is far more efficient.
I think in general, OO is an interesting topic to examine, because we’ve already improved so much as a community. I haven’t seen this specific example in a while, but it still sticks out to me pretty vividly.
class Foo: def __init__(self, bar):
self.bar = bar
foo = Foo("Bar")print(foo.bar)
The wildest part: this example is simultaneously too broad and too specific. It’s using the same two placeholders foo
and bar
as FIVE different things: a class, a variable, a string, a parameter, and an instance variable, and the very specific mapping of a string to an identically-named instance variable means that a student has no opportunity to draw that connection themselves.
Instead, what about this?
class User:
def __init__(self, name, email):
self.name = name
self.email = emailuser1 = User("Jeff", "Jj123@gmail.com")
user2 = User("Beyonce", "TheBoss@beyonce.com")print(user2.email)
We’ve named our instance variables something intuitive, and we’ve passed in strings that the student can parse really easily. Furthermore, by using two instances instead of one, and using variable names user1
and user2
, we’ve already hinted at the idea that the User class serves as a blueprint/archetype from whence to create instances, even without explicitly using those terms.
(updated 1/30)
I got some excellent feedback on this post from Jesse Farmer (and about 5 other people thereafter) about something I do, but didn’t mention: after a few good examples, show something absurd so that students start to recognize the value of naming variables well.
I usually hit this topic really hard on day 1, and then touch on it more briefly later, so I’ll reuse the string example from above, and change the variables
x = "Ada"
y = "Lovelace"
z = x + y
print(z)
Usually I ask “will this still work?”
Students make predictions, we run the code, and draw some conclusions. Even still, since this draws a tiny bit on math prior knowledge, I’m worried that students may still have a limited understanding of what variables can be called, so I usually follow up with this example:
pineapple = "Ada"
mango = "Lovelace"
fruit_salad = pineapple + mango
print(fruit_salad)
“Will this still work?”
“Well then out of all these options, first_name
, x
, and pineapple
, if they all work, which one should we use? Why?”
Students almost always answer in a way that proves they have, in one 90-second example, grasped both the full extent of the freedom they have with variables, as well as the rationale for naming them well.
Later on, we talk about language-specific nuances & no-nos like capital letters and 1st_favorite_food
when these issues pop up in student work. Generally, though, students are more likely to over-match the teacher’s conventions rather than under-match them, so these issues tend to be the exception, not the rule.
When you’re working with beginners, “Foo”
and “Bar”
should be red flags that your examples need reworking. Their less sinister but more pervasive counterparts s
, c
, i
, and arr
should also be signals that your code lacks context.
That said, I don’t mean to imply that Beyonce’s fake email or my function to get movie permissions belong on w3schools or in official Python documentation — these examples are specific to me and to my students, and those more formal resources have to be useful for audiences of all ages, the world over.
I do think that if you’re lifting your code snippets directly from documentation or learning guides without modifying them to leverage your students’ existing working knowledge of the world around them, you may be missing opportunities to make students feel powerful and intellectually satisfied.
Students don’t need simple examples, they just needs clear ones. They need examples that let them use their intuition instead of asking them to check it at the door.
http://slkjfdf.net/ – Ubiceriwe Avuxat iti.pwuu.etechworld.in.lkk.jy http://slkjfdf.net/