3 More Common Beginner Python Mistakes
Tags: beginners, python, codenewbie, programming
Published: 2019-12-14 12:01:03

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.

#### Copying and Pasting Code

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:

```python
x ‏‏‎= 100

print(x)
```

If I copy and paste that snippet in to Visual Code and try to run it I get:

```python
    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 <a href="https://security.stackexchange.com/questions/39118/how-can-i-protect-myself-from-this-kind-of-clipboard-abuse">malicious</a>. 

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...


#### Variable Scope

What does this snippet print?

```python
x = 5

def foo():
    x = 20

    print(x)

foo()
print(x)
```

Those that said `20` then `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 <a href="https://en.wikipedia.org/wiki/Variable_shadowing">shadows</a> the global variable named `x`.

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:

```python
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)
```

Which gives

```
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?

```python
x = 5

def foo():
    x = x + 2

    print(x)

foo()
```

2? No… 7? Nope… `UnboundLocalError`? Yep.

But why? The other example quite happily gave us `10` when just printing!

There are some [good](https://nbviewer.jupyter.org/github/rasbt/python_reference/blob/master/tutorials/scope_resolution_legb_rule.ipynb) and [in-depth](https://eli.thegreenplace.net/2011/05/15/understanding-unboundlocalerror-in-python) explanations as to why this is the case and do a much better job of explaining the *why* than I could here.

Nonetheless, the solution to this is adding the `global` definition so that Python knows where to find the value of `x` before assignment:

```python
x = 5

def foo():
    global x
    x = x + 2

    print(x)

foo()
```

#### Redefining Built-in Functions

This really is a follow on from the previous point about scope and how it can crop up in other places.

```python
... 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.

As the `pi` example demonstrated what has happened is `input` now has the value of that string rather than being the built-in `input` function.