In Meaningful Chunks and Modules, we’ll digress to look at the extension libraries. This is because the bulk of the math functions are in a separate module or library, called math. We’ll look at parts of it in The math Module – Trig and Logs. We’ll also look at the random number generators in The random Module – Rolling the Dice.
For those who will be using Python for financial and other fixed-point calculations, we’ll look at fixed-point math, also. However, we’ll defer this until Fixed-Point Numbers : Doing High Finance with decimal because it is a bit more advanced than using the built-in types of numbers.
Python’s use of modules is a way to break the solution to a problem down into meaningful chunks. We hinted around about this in Core Coolness. There are dozens of standard Python modules that solve dozens of problems for us. We’re not ready to look at modules in any depth, that comes later in Modules : The unit of software packaging and assembly. This section has just a couple of steps to start using modules so that you can make use of two very simple modules: math and random.
A Python module extends the Python language by adding new classes of objects, new functions and helpful constants. The import statement tells Python to fetch a module, adding that module to our working environment. For now, we’ll use the simplest form: import.
import m
This statement will tell Python to locate the module named m and provide us with the definitions in that module. Only the name of the module, m, is added to the local names that we can use. Every name inside module m must be qualified by the module name. We do this by connecting the module name and the function name with a .. When we import module math, we get a cosine function that we refer to with “module name dot function name” notation: math.cos().
This module qualification has a cost and a benefit. The cost is that you have to type the module name over and over again. The benefit is that your Python statements are explicit and harbor no assumptions. There are some alternatives to this. We’ll cover it when we explore modules in depth.
Another important thing to remember is that you only need to import a module once to tell Python you will be using it. By once, we mean once each time you run the Python program. Each time you exit from the Python program (or turn your computer off, which exits all your programs), everything is forgotten. Next time you run the Python program, you’ll need to provide the import statements to add the modules to Python for your current session.
An Interesting Example. For fun, try this:
import this
The this module is atypical: it doesn’t introduce new object classes or function definitions. Instead, well, you see that it does something instead of extending Python by adding new definitions.
Even though the this module is atypical, you can still see what happens when you use an extra import. What happens when you try to import this a second time?
The math module defines the common trigonometry and logarithmic functions. It has a few other functions that are handy, like square root. The math module is made available to your programs with:
import math
Since this statement only adds math to the names Python can recognize, you’ll need to use the math prefix to identify the functions which are inside the math module.
Here are a couple of examples of some trigonometry. We’re calculating the cosine of 45, 60 and 90 degrees. You can check these on your calculator. Or, if you’re my age, you can use a slide rule to confirm that these are correct answers.
>>> import math
>>> math.cos( 45 * math.pi/180 )
0.70710678118654757
>>> math.cos( 60 * math.pi/180 )
0.50000000000000011
>>> math.cos( 90 * math.pi/180 )
6.123233995736766e-17
>>> round( math.cos( 90*math.pi/180 ), 3 )
0.0
Tip
Debugging Math Functions
The most common problem when using math functions is leaving off the math to qualify the various functions imported from this module. If you get a “NameError: name 'cos' is not defined” error message, it means you haven’t included the math qualifier.
The next most common problem is forgetting to import math each time you run IDLE or Python. You’ll get a “NameError: name 'math' is not defined” error if you forgot to import math.
The other common problem is failing to convert angles from degrees to radians.
The math module contains the following
trigonometric functions. The trig functions all use radians to measure
angles. If your problem uses degrees, you’ll have to convert from degrees
to radians. If your trigonometry is rusty, remember that
radians are
360 degrees.
Here are some trig function definitions. We don’t provide all of them, because they’re on the Python web site. See http://docs.python.org/library/math.html for the complete list of available functions.
Returns the arc sine of x.
Returns the arc tangent of x.
Returns the arc tangent of y / x.
Returns the cosine of x radians.
Returns the sine of x radians.
Returns the tangent of x radians.
Additionally, the following constants are also provided.
| pi: | The value of , 3.1415926535897931 |
|---|---|
| e: | The value of e, 2.7182818284590451, used for the exp() and log() functions. |
Here’s an example of using some of these more advanced math functions. Here is a trig identity for the cosine of 39 degrees. We use 39*math.pi/180 to convert from degrees to radians. We also use the square root function (sqrt()).
>>> import math
>>> math.sqrt( 1-math.sin(39*math.pi/180)**2 )
0.77714596145697101
>>> math.cos( 39*math.pi/180 )
0.7771459614569709
Here are some more of these common trigonometric functions, including logarithms, anti-logarithms and square root.
>>> math.exp( math.log(10.0) / 2 )
3.1622776601683795
>>> math.exp( math.log(10.0) / 2 )
3.1622776601683795
>>> math.sqrt( 10.0 )
3.1622776601683795
Logarithm Function Definitions.
Returns the Euclidean distance,
sqrt( x*x + y*y ) (
), length of the
hypotenuse of a right triangle with height of
y and length of x.
Returns the logarithm (base 10) of
x (
), inverse of
.
Returns x**y (
).
The following batch of functions supplement the basic round() function with more sophisticated computations on floating-point numbers. You can probably guess from the names what ceiling and floor mean.
>>> math.ceil(2.1)
3.0
>>> math.floor(2.999)
2.0
The math module contains the following other functions for dealing with floating-point numbers.
Other Floating-Point Function Definitions.
Returns the next larger whole number. math.ceil(5.1) == 6, math.ceil(-5.1) == -5.0.
Returns the absolute value of the x as a floating-point number.
Returns the next smaller whole number. math.floor(5.9) == 5, math.floor(-5.9) == -6.0.
Some of the math functions only work for a limited domain of values. Specifically, square root is only defined for non-negative numbers and logarithms are only defined for positive numbers. What does Python do when we violate these rules?
Try the following expressions:
math.sqrt(-1)
math.log(-1)
math.log(0)
You’ll see one of two kinds of results. The details vary among the operating systems.
Both results amount to the same thing: the result cannot be computed.
The random module defines functions that simulate random events. This includes coin tosses, die rolls and the spins of a Roulette wheel. The random module is made available to your program with:
import random
Since this statement only adds random to the names Python can recognize, you’ll need to use the random prefix on each of the functions in this section.
The randrange() is a particularly flexible way to generate a random number in a given range. Here’s an example of some of the alternatives. Since the answers are random, your answers may be different from these example answers. This shows a few of many techniques available to generate random data samples in particular ranges.
>>> import random
>>> random.randrange(6)
5
>>> random.randrange(1,7)
6
>>> random.randrange(2,37,2)
6
>>> random.randrange(1,36,2)
13
. The number will be between 0
and 5, inclusive.
. The number will be between 1
and 6, inclusive.
. The range function
is defined by start, stop and step values. When the step
is 2, then the values used are
.
. The number will be
between 1 and 35, inclusive. Here, we start from
1 with a step of 2; the values used are
.The random module contains the following functions for working with simple distributions of random numbers. There are several more sophisticated distributions available for more complex kinds of simulations. Casino games only require these functions.
Chooses a random value from the sequence sequence. Example: random.choice( ['red', 'black', 'green'] ).
Creates a random floating-point number,
r , such that
.
Note that random() doesn’t require any
arguments, but does require the empty ()s to alert
Python that it is really the name of a function. We use it like
this: random.random().
Chooses a random element from range( start, stop , step ). We’ll revisit this in Built-in Functions for Lists. For now, we’ll stick with the following examples:
randrange(6) returns a number,
n, such that
.
randrange(1,7) returns a number,
n, such that
.
randrange(10,100,5) returns a number,
n, between 10 and 95 incremented by 5’s,
.
Creates a random floating-point number,
r , such that
.
Evaluate These Expressions.
The following expressions are somewhat more complex, and use functions from the math module.
math.sqrt( 40.0/3.0 - math.sqrt(12.0) )
6.0/5.0*( (math.sqrt(5)+1) / 2 )**2
math.log( 2198 ) / math.sqrt( 6 )
Tossing a Coin.
There are several ways the random module can be used to simulate tossing a coin. Write expressions that use choice() and randrange().
Additionally, using something like int(random()*X), for some value of X, you can simulate a coin toss. If we use zero for heads and 1 for tails, what is an appropriate value for X? What if we use round() instead of int()? What about ceil() and floor()?
Can you also use uniform() to simulate a coin toss? Do you need to also use int()?
There are two reasons for keeping math (or random or decimal) in separate modules.