Python Beginners (2 Part Series)
Another year, another set of bright-eyed enthusiastic students.
Now we're coming to the end of the first semester, here is 3 more common mistakes I've come across whilst teaching beginners.
This is a bugbear more than anything; however, it does have some potentially serious side effects. It is slightly different to the classic copying and pasting from a source without understanding what the code is doing
Without fail this crops up every year, a completely random error in perfectly fine looking code.
Take a look at this:
x = 100 print(x)
If I copy and paste that snippet in to Visual Code and try to run it I get:
x = 100 ^ SyntaxError: invalid syntax
Uhhh, what? I'm pretty sure that is how you assign a value to a variable...
So why does it fail...? Because I've added a hidden character to it.
The problem here is I've had new developers sit and stare at their screen in frustration for longer than they care to admit because they can't figure out why this seemingly simple piece of code doesn't run.
Just be careful when copying code from PDFs, online, or wherever because quite often you'll run in to random errors but more importantly you may even end up copying something malicious.
Of course you could end up with someone doing it on purpose like a certain lecturer I had at University to force us to write the code out...
What does this snippet print?
x = 5 def foo(): x = 20 print(x) foo() print(x)
Those that said
5 give yourself a pat on the back.
We had just introduced the concept of functions to the students, and how to use them to eliminate repeated parts of their code, and all of a sudden it was acting weird.
What the above snippet demonstrates is local function v.s. global scope.
x here is defined inside the function as a local variable to that function that shadows the global variable named
Python uses the LEGB (Local, Enclosed, Global, Built-in) rule when resolving variable scope. This is the snippet I use to show students how scope bubbles up:
from math import pi #pi = 10 def foo(): #pi = 20 print("local: ", pi) def bar(): #pi = 30 print("enclosed: ", pi) bar() foo() print("global: ", pi)
local: 3.141592653589793 enclosed: 3.141592653589793 global: 3.141592653589793
Or with the
pi variable declarations uncommented:
local: 20 enclosed: 30 global: 10
So what is the output when I try this next snippet?
x = 5 def foo(): x = x + 2 print(x) foo()
2? No… 7? Nope…
But why? The other example quite happily gave us
10 when just printing!
Nonetheless, the solution to this is adding the
global definition so that Python knows where to find the value of
x before assignment:
x = 5 def foo(): global x x = x + 2 print(x) foo()
This really is a follow on from the previous point about scope and how it can crop up in other places.
... snip... input = ("Continue? (Y/N): ") ... snip...
A fair number of students had this in their code where they had accidentally redefined the input function in the program, then tried to use it later on.
pi example demonstrated what has happened is
input now has the value of that string rather than being the built-in