This is my fourth post in a series to quickly introduce Python:
- Python Primer 1
- Python Primer 2 – Lists and Dictionaries
- Python Primer 3 – Loops and Conditions
- Python Primer 4 – Functions (You are here)
I find functions to be convenient and useful, but completely unnecessary to writing a basic program. You can write a really cool program in python that never uses a custom-written function because that’s what a program is, a function. Inevitably though, you’ll probably want to do one or both of the things that I find functions useful for – reusing code or scoping.
Re-using Code
If you write code for long enough, you’ll get to a point where you find yourself copying and pasting code. It’s okay, everybody does it at some point. But you’ll know you’re doing something wrong if it becomes a lot of work, after all that’s what you have a computer for.
Say for example you had a guessing game program that picked a random color out of the “colors” list that we’ve been using in the last few posts:
import random colors = ["red","purple","blue"] guess = 'red' answer = colors[random.randint(0,len(colors)-1)] if guess == answer: print("You guessed right! The answer was "+answer) else: print("Try again! The answer was "+answer)
Line 1 is new. “import” means to pull code in from somewhere else, in this case from the “standard library” which is a bunch of code that the python creators built for you. When you import, you import a “module” which is basically just a file where the code in the module is stored. “random” is specifically a module that gives you more pre-built functions that do random things. You access these new functions using a dot “.” as in “random.randint()” which picks a random number in a range of numbers.
Let me also explain line 4 where the answer is created. Basically it boils down to this:
colors[] #selects one of the items from the colors list
random.randint() #creates a random integer in a range
len(colors)-1 #we get the length of colors minus 1 (starts at 0)
Putting those together ends up selecting a random item from “colors”. If the selected answer matches the guess, it prints “You guessed right!”, if not it prints “Try again!”).
If you write that program on the interactive shell and want to play the game more than once, you’ll be copying and pasting lines 3 – 8 as many times as you want to play. To avoid copying and pasting, we can put 3 – 8 in a function so we can reuse it easily. Functions are “defined” using “def”:
import random colors = ["red","purple","blue"] def guessing_game(guess=''): answer = colors[random.randint(0,len(colors)-1)] if guess == answer: print("You guessed right! The answer was "+answer) else: print("Try again! The answer was "+answer)
Now you can run your new function called “guessing_game” like so:
guessing_game(guess='blue')
Try again! The answer was red
guessing_game(guess='blue')
You guessed right! The answer was blue
The answer will be different every time because it’s selected randomly via the magic in the “random.randint()” function that’s part of the “random” module.
Scoping
The other reason to use a function doesn’t really make itself obvious until you’ve used functions for a little while. But I think it’s important to know so I’ll mention it here. The idea is that “inside” a function, you have a private space for variable names (a “namespace”) that does not affect the global space. Again, the use case for this is a bit hard to see when our program is so small, but I’ll show you how it works.
Let’s say we already have a variable named “answer” in our program before we created the function “guessing_game”. Maybe it was left over from some other function that ran, or your program is just really big. In any case, it’s there, just accept it. These things happen.
import random answer = "magenta" colors = ["red","purple","blue"] def guessing_game(guess=''): answer = colors[random.randint(0,len(colors)-1)] if guess == answer: print("You guessed right! The answer was "+answer) else: print("Try again! The answer was "+answer)
When you run “guessing_game()” again, the “answer” variable that’s created inside the function every time you run it is unaffected by the global “answer” variable. That’s because “inside” the function is a tear in the space time continuum. I like to think of it like the “warp bubble” episode from Star Trek TNG. Everybody knows that one, right? Right?
guessing_game(guess="purple")
Try again! The answer was red
print(answer)
'magenta'
For my next and last post I’ll cover how to actually use python for something cool.