Python Beginner Mistakes

Tips for writing code like a veteran Pythonista

ยท

4 min read

As a Python trainer, I get to work with pynewbies across the spectrum. It doesn't matter whether they are from college or years into the industry when learning Python. The simplest language on the earth is not that intuitive. Things get even more challenging when they are well versed in a Typed-Object-Oriented-Language

During my Python Bootcamp, we get to work on a lot of Python exercises. Here are some common mistakes that my students make that seem to repeat across the board.

Checking Type

As the students get a place of type checking, they use the following snippet.

if type(value) == int:

vs

isinstance(value, int)

Part of the problem is with us, the instructors. When teaching types, we introduce type(<object>) to find the variable type, which nudges them to use the function irrespective of the use case.

Why use one over the other?

type(value) == int will work for all basic type checking. Making this a practice will backfire once you start writing your types, aka Classes.

Assume you have two classes,

class Parent:
    pass


class Child(Parent):
    pass

Let's create a child instance.

c = Child()
isinstance(c, Parent) # True

vs

type(c) == Parent # False
type(c) is Parent # False

type(c) is Child # True
type(c) == Child # True

List Creation

If you are coming from an object-oriented or strictly typed language, you have to unlearn many things when it comes to Python. Infact the simplicity will throw you off a bit.

When asked to write a program that returns area_of_square given a list of sides, the following is the code written by a college student. Coming from C/C++, the immediate instinct is to declare a list of elements to store the result.

def calculate_area_of_square_with_list(lengths):
    results = [None] * len(lengths)
    for index, length in enumerate(lengths):
        if type(length) == int:
            results[index] = length ** 2
        else:
            results[index] = INVALID_INPUT
    return results

Whereas Python makes our life much easier. You can create an empty list and keep appending to it as long as you want

def calculate_area_of_square_with_list(lengths):
    results = []
    for length in lengths:
        if isinstance(length, int):
            results.append(length ** 2)
        else:
            results.append(INVALID_INPUT)
    return results

Taking it up a notch with one-liners

def calculate_area_of_square_with_list(lengths):
    results = [length ** 2 if isinstance(length, int) else INVALID_INPUT  for length in lengths]

Ternary Operator

Coming from Javascript, one of my students was surprised to see no Ternary operators in Python. A stackoverflow question led down to the following code.

result  = {False:f"{name}\n{email}\n{designation}",
          True:INVALID_INPUT}[name == '' or email == '']

Although there is nothing syntactically wrong with the above code, infact, it is a genius way to play around with dictionaries and boolean. A code like this is not-pythonic and might throw off Pythonista's a bit.

Consistent Code

Take a look at the following snippet. Do you see it? There is nothing wrong with putting the logic return 22.7*(length*length) right into the block. It's always a good idea to keep the code consistent. Don't wrap one set of logic into a function while leaving others hanging as raw code.

What are we achieving by this? Clean and readable code

def calculate_area_of_shape(lengths):
    if shape == "circle":
        return 22.7*(length*length)

    elif shape == "square":
        return area_of_square(length)
    else:
        return INVALID_INPUT

List Slicing

Another relatively simple exercise that seems to throw newbies off guard.

Write a function called middle that takes a list returns a new list that contains all but the first and last element

Example 1

def middle(l):
    l = len(l1)
    l1.remove(l1[l - 1])
    l1.remove(l1[0])
    return l1

Example 2


def middle(l):
    for index in range(len(l)):
        if index == 0 or index == len(l) - 1:
            l.pop(index)
    return l

Python is a simple programming language, there should be a more straightforward way to do this, and there is. It is called list slicing.

def middle(l):
    return l[1:-1]

Wrapped Tuples

An indexed tuple or list makes the code hard to read. Always unwrap it into proper variable names and use them.

for shape in shape_with_length:
    area(shape[0], shape[1])

vs

for shape in shape_with_length:
    area(shape_name=shape[0], length=shape[1])

vs

for shape in shape_with_length:
    shape_name, length = shape[0], shape[1]
    area(shape_name,length)

vs

for shape_name, length in shape_with_length:
    area(shape_name, length)

Using Package names as file names

Whenever I introduce flask to my students, I name the file app.py, and there will be one person in the class who calls it flask.py that will give you an error like Flask not found in module flask.

The error occurs because the Python interpreter searches for the Flask class in the flask.py you created instead of the actual flask package.

Never name your module the same as the package you are trying to use.


While most of these might go unnoticed as we go up the Python ladder, teaching newbies brought out aspects usually overlooked. There are a lot more to the list as to

  1. Understanding Terminal vs. Python shell
  2. How to write REST APIs?
  3. Database design
  4. How to build projects with Python

All of these questions are answered in my #PythonToProject 4 Week Cohort

ย