Final Project Guide: Organizing your Code with Modules and Functions

by Elliott Hauser

17 Nov 2022

Tools for Organizing Code: Functions and Modules!

Here’s an example from the text:

Functions really shine in Turtle. You can draw some very complex pictures with relatively simple code.

As you add more and more functions to your code, though, it becomes hard to read! So, a new tool I’m introducing today is the custom module. This is essentially another .py file that contains code that you wrote, keeps it out of your way, and that you can import just like we’ve done, so far, with the build-in modules of the standard library (like random or of course turtle).

To do this:

  • create a new file in Trinket with the + button
  • name it shapes.py
  • cut the lines defining the square function from main.py and paste them into shapes.py
  • in main.py, add a line that says from shapes import square

Voila! The rest of your code operates just as it used to, but your function definition is in a separate file, making main.py easy to read.

More on importing

Now that we’re making our own modules, it’s important to learn a little more about the import keyword in Python.

There are two ways to import things:

import module

and

from module import something

…where module is an actual module name like random or turtle, and something is a function, class, etc.

What’s the difference?

Well, the first method imports things and keeps them in the namespace of the module. This means you need to type the module name to access them. Like this:

import turtle

tina = turtle.Turtle()

That’s more typing! Why would we do that?

Well, from module import * is another pattern you see that lets you not have to type a namespace each time. BUT you run the risk of overwriting the things you imported. For instance, importing * (everything) from turtle will create functions like forward and backward. If you use those names for something else, you’ll overwrite them.

So, while it’s more convenient to import *` sometimes, and especially while just learning, as you become more proficient as a programmer you’ll want to import specific things. Or, just import the module, which gives you access to everything the module provides in a safe namespace that it’s much harder to overwrite.

Tip: if you take my advice and just import specific things when you use from, you can provide a comma-separated list, like this:

from random import choice, randint

That code will let you use the choice and randint functions without prefixing them with the random. namespace. If you keep coding and find you need a thrid function, just add it to the list! That’s also how we accessed the function from our custom module above:

from shapes import square

If you’re going to extensively use a module, like turtle, it’s probably best to just import turtle at the top, and use the namespace. Otherwise, just import what you need using from, and you can always import more

Aliasing with as

Final tip with importing. You can rename a module when you import it with the as keyword. This is common in some third party libraries. With Numpy and Matplotlib, for instance, you’ll often see examples that start like this:

import numpy as np
import matplotlib.pyplot as plt

Honestly, I don’t like this, because the more terse namespaces become hard to read. But it’s become the way many of these community members do things, so I want you to know about it, and if you go into scientific computing or data analysis you might want to do this too, to conform to the style your community of practice uses!

Elliott Hauser is an Assistant Professor at the UT Austin iSchool. He's hacking education as one of the cofounders of Trinket.io. Find Elliott Hauser on Twitter, Github, and on the web.