Random Imports
July 27, 2010 8 Comments
Hungarian: Ya! See-gar-ets! Ya! Uh…My hovercraft is full of eels.
In our last tutorial, we met the concept of functions. It turns out that functions (and another concept called classes, which we haven’t got to yet) are the workhorse of Python. Almost everything you will end up doing with Python will involve the use of functions. The good news is that most of what you do will rely on functions written by other people. Python includes a mechanism for sharing functions with other people, but also with yourself – so if you write a function for one program today, you can use it with a different program tomorrow (the multiply() function we wrote earlier might be useful in many different sorts of programs for example). That mechanism is called the import statement. If you’re unfamiliar with this English word ‘import’ see this definition.
The import statement imports programs which have been saved [into another file – the file is called a module, but we haven’t done saving files yet] into the current program. For the time being we will only be importing modules which other people have written. However, later, when we get to saving programs we may also be importing our own.
You have already used the import statement in the WhyPy tute:
>>> import this [stuff omitted]
It told us about the Zen of Python. What is happening here is that there is a file called ‘this.py’ (and is hidden away in /usr/lib/python2.5/this.py on the computer I am typing this on, but it may be somewhere else on yours). When you import this, Python loads and runs the contents of that file as if the contents of the file were executed at the place where the import statement is – with some caveats (see below). The this.py file contains two for loops and a print statement at the end of it (if you are brave and able, find a copy of the file on your system and read it). When the module is imported Python actually acts on these statements as if you’d typed them in, which is why you get the printout on import.
When there is another function defined in the imported program, it is given a name as a part of the module imported. So if the function multiply() is defined in a file called myModule.py then import myModule (note no ‘.py’) would create a function in your program which is called myModule.multiply(). To the computer this means “look for a function called multiply() in the file myModule.py”. As I mentioned earlier we’re going to look at importing other people’s stuff first. Importing our own stuff will need to wait.
Python comes with a heap of functions built in. That is, they are available when you run the Python interpreter, without having to explicitly import anything further. The range() and int() functions are examples – they are available whenever you run Python. However, a Python installation also comes with other modules which are available for loading, but which are not loaded automatically (loading everything every time would use up time and memory on the computer, and if the module’s functions aren’t being used, that would be wasted effort). The random module is an example.
>>> random() Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name 'random' is not defined >>> import random >>> random() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 'module' object is not callable
Here I have tried to use a function called random() – but Python doesn’t know what I’m talking about. However, after I import the module called random it gives me a different response (it says that it knows about something called ‘random‘, but it isn’t callable – that is, it can’t be treated as a function). The name of the module here is ‘random‘. It also has a function within it called ‘random()‘. So the way we call it is by putting the module name and the function name together, separated by a dot:
>>> random.random()
0.17113600109807192
>>> random.random()
0.82195215747538508
What random.random() does is to give you a random (technically ‘pseudo-random’) number between zero and one, including zero, but not including one. Randomness can be very important in programs which rely on variability. You may not want randomness when you multiply numbers together, but you might want it in a game where aliens appear at random locations on the screen.
Guessing Game
Here’s a quick guessing game, using a function definition and the random() function from the random module (ie random.random()):
>>> import random >>> def guessGame(): ... answer = int(random.random()*10)+1 ... while True: ... spam = raw_input('What is your guess (type a number): ') ... guess = int(spam) ... if guess > answer: ... print 'No, the answer is less than ',guess ... if guess < answer: ... print 'No, the answer is greater than ',guess ... if guess == answer: ... print 'Yes, you guessed correctly! The answer is ',answer ... return ... >>> guessGame( ) What is your guess (type a number): 3 No, the answer is less than 3 What is your guess (type a number): 2 Yes, you guessed correctly! The answer is 2 >>> guessGame( ) What is your guess (type a number): 4 No, the answer is greater than 4 What is your guess (type a number): 6 Yes, you guessed correctly! The answer is 6
Each time you run it, the answer should be different (well, one in ten times it will be the same as the last answer).
Homework:
[This will be a bit tedious. When we know how to save files it will become a little easier]
Change it to a guessing game for numbers from 1 to 100 (or 1000 etc) by changing the 10 to a different number.
Extra points: make the number range dependent upon a value passed into the function – for example, guessGame(17) would choose a number from 1 to 17. In order to do this you should look at the function tutorial – the function’s definition needs to be changed so that it has an argument in the brackets. Give the argument a name, and then use the name of the argument where 10 is above.
Explanation:
The function first initialises an answer by randomly choosing a number between zero and one, multiplying it by 10 (giving a number between 0 * 10 and 1 * 10 – but not including 1*10). It uses the int() function we met earlier to convert it from a decimal (like 3.4) to an integer (like 3). This gives a number between 0 and 9 (because random() won’t return the number 1), so we add one to make the answer between 1 and 10. Then the program falls into a continuous loop which keeps asking you for a guess. If the guess is wrong, it tells you whether you need to guess higher or lower. If you’re right it congratulates you then exits the function through the return statement.
Do you notice that you run the function by putting the name of the function with no arguments-> guessGame(). Did you also notice that you can keep on running the function without having to retype it, just by typing guessGame()? Functions save you a lot of effort in this way.
To show you that the import really has an effect, we can delete the [reference to the] imported module (using del, which I haven’t told you about yet) and show that guessGame() no longer works without it, then re-import it:
>>> del random >>> guessGame( ) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in guessGame NameError: global name 'random' is not defined >>> import random >>> guessGame( ) What is your guess (type a number):
A final Note
On a final note, you might, reasonably, ask how I knew that there was a module called random which was available to import. Unfortunately, there isn’t an easy way to know, other than reading through the Python docs, seeing it mentioned in a book or Googling what you want. We’ll cover some useful imports in some other tutes.