The print Statement and Numeric Operations
Basic expressions are the most central and useful feature of modern programming languages. To see the results of expressions, we’ll use the print statement.
This chapter starts out with Seeing Output with the print() Function (or print Statement), which covers the print statement. Numeric Types and Operators covers the basic numeric data types and operators that are integral to writing expressions Python. Numeric Conversion (or “Factory”) Functions covers conversions between the various numeric types. Built-In Math Functions covers some of the built-in functions that Python provides.
Before delving into expressions and numbers, we’ll look at the print statement. We’ll cover just the essential syntax of the print statement; it has some odd syntax quirks that are painful to explain.
Python 3.0 will replace the irregular print statement with a built-in print() function that is perfectly regular, making it simpler to explain and use.
In order to use the print() function instead of the print statement, your script (or IDLE session) must start off with the following.
from __future__ import print_function
This replaces the print statement, with it’s irregular syntax with the print() function.
The print statement takes a list of values and, well, prints them. Speaking strictly, it does two things:
Generally, standard output is the console window where Python was started, although there are ways to change this that are beyond the scope of this book.
Here’s a quick summary of the more important features of print statement syntax. In short, the keyword, print, is followed by a comma-separated list of expressions.
print expression 〈 , ... 〉
This syntax summary isn’t completely correct because it implies that the list of expressions is terminated with a comma. Rather than fuss around with complex syntax diagrams (that’s what the Python reference manual is for) we’ve shown an approximation that is close enough.
The , in a print statement is used to separate the various expressions.
A , can also be used at the end of the print statement to change the formatting; this is an odd-but-true feature that is unique to print statement syntax.
It’s hard to capture this sublety in a single syntax diagram. Further, this is completely solved by using the print() function.
One of the simplest kind of expressions is a quoted string. You can use either apostrophes (') or quotes (") to surround strings. This gives you some flexibility in your strings. You can put an apostrophe into a quoted string, and you can put quotes into an apostrophe’d string without the special escapes that some other languages require. The full set of quoting rules and alternatives, however, will have to wait for Strings.
For example, the following trivial program prints three strings and two numbers.
print "Hi, Mom", "Isn't it lovely?", 'I said, "Hi".', 42, 91056
Multi-Line Output. Ordinarily, each print statement produces one line of output. You can end the print statement with a trailing , to combine the results of multiple print statements into a single line. Here are two examples.
print "335/113=", print 335.0/113.0 print "Hi, Mom", "Isn't it lovely?", print 'I said, "Hi".', 42, 91056
Since the first print statement ends with a , it does not produce a complete line of output. The second print statement finishes the line of output.
Redirecting Output. The print statement’s output goes to the operating system’s standard output file. How do we send output to the system’s standard error file? This involves some more advanced concepts, so we’ll introduce it with a two-part recipe that we need to look at in more depth. We’ll revisit these topics in Components, Modules and Packages .
First, you’ll need access to the standard error object; you get this via the following statement.
Second, there is an unusual piece of syntax called a “chevron print” which can be used to redirect output to standard error.
print >> file , 〈 expression , ... 〉
Two common files are sys.stdout and sys.stderr. We’ll return to files in Files.
Here is an example of a small script which produces messages on both stderr and stdout.
#!/usr/bin/env python """Mixed output in stdout and stderr.""" import sys print >>sys.stderr, "This is an error message" print "This is stdout" print >>sys.stdout, "This is also stdout"
When you run this inside IDLE, you’ll notice that the stderr is colored red, where the stdout is colored black. You’ll also notice that the order of the output in IDLE doesn’t match the order in our program. Most POSIX operating systems buffer stdout, but do not buffer stderr. Consequently, stdout messages don’t appear until the buffer is full, or the program exits.
Python 3 replaces the relatively complex and irregular print statement with a simple and regular print() function.
In Python 2.6 we can use this new function by doing the following:
from __future__ import print_function
This statement must be one of the first executable statements in your script file. It makes a small – but profuound – change to Python syntax. The Python processor must be notified of this intended change up front.
This provides us with the following:
This will convert each object to a string, and then write the characters on the given file.
The separator between objects is – by default – a single space. Setting a value for sep will set a different separator.
The end-of-line character is – by default – a single newline. Setting a value for end will set a different end-of-line character.
To change output files, provide a value for file.
Multiline Output. To create multiline output, do the following:
from __future__ import print_function print( "335/113=", end="" ) print( 335.0/113.0 ) print( "Hi, Mom", "Isn't it lovely?", end="" ) print( 'I said, "Hi".', 42, 91056 )
Redirecting Output. The print statement’s output goes to the operating system’s standard output file. How do we send output to the system’s standard error file? This involves some more advanced concepts, so we’ll introduce it with a two-part recipe that we need to look at in more depth. We’ll revisit these topics in Components, Modules and Packages.
First, you’ll need access to the standard error object.
Second, you’ll provide the file option to the print() function.
from __future__ import print_function import sys print( "This is an error message", file=sys.stderr ) print( "This is stdout" ) print( "This is also stdout", file=sys.stdout )
Adding Features. You can – with some care – add features to the print() function.
When we look at function definitions, we’ll look at how we can override the built-in print() function to add our own unique features.
A program produces a number of kinds of output. The print() function (or print statement) is a handy jumping-off point. Generally, we’ll replace this with more advanced techiques.
The print statement (or print() function) is a very basic tool for debugging a complex Python program. Feel free to use print statements heavily to create a clear picture of what a program is actually doing. Ultimately, you are likely to replace print statements with other, more sophisticated methods.
Python provides four built-in types of numbers: plain integers, long integers, floating point numbers and complex numbers.
Numbers all have several things in common. Principally, the standard arithmetic operators of +, -, *, /, % and ** are all available for all of these numeric types. Additionally, numbers can be compared, using comparison operators that we’ll look at in Comparisons. Also, numbers can be coerced from one type to another.
Plain integers are at least 32 bits long. The range is at least -2,147,483,648 to 2,147,483,647 (approximately ± 2 billion).
Python represents integers as strings of decimal digits. A number does not include any punctuation, and cannot begin with a leading zero (0). Leading zeros are used for base 8 and base 16 numbers. We’ll look at this below.
>>> 255+100 355 >>> 397-42 355 >>> 71*5 355 >>> 355/113 3
While most features of Python correspond with common expectations from mathematics and other programming languages, the division operator, /, poses certain problems. Specifically, the distinction between the algorithm and the data representation need to be made explicit. Division can mean either exact floating-point results or integer results. Mathematicians have evolved a number of ways of describing precisely what they mean when discussing division. We need similar expressive power in Python.We’ll look at more details of division operators in Division Operators.
Binary, Octal and Hexadecimal. For historical reasons, Python supports programming in octal and hexadecimal. I like to think that the early days of computing were dominated by people with 8 or 16 fingers.
A number with a leading 0 (zero) is octal, base 8, and uses the digits 0 to 7. 0123 is octal and equal to 83 decimal.
A number with a leading 0x or 0X is hexadecimal, base 16, and uses the digits 0 through 9, plus a, A, b, B, c, C, d, D, e, E, f, and F. 0x2BC8 is hexadecimal and equal to 11208.
A number with a leading 0b or 0B is binary, base 2, and uses digits 0 and 1.
When using Python 2.6, watch for leading zeros in numbers. If you simply transcribe programs from other languages, they may use leading zeros on decimal numbers.
In Python 3, the octal syntax will change. Octal constants will begin with 0o to match hexadecimal constants which begin with 0x.
0o123 will be octal and equal to 83 decimal.
One of the useful data types that Python offers are long integers. Unlike ordinary integers with a limited range, long integers have arbitrary length; they can have as many digits as necessary to represent an exact answer. However, these will operate more slowly than plain integers.
Long integers end in L or l. Upper case L is preferred, since the lower-case l looks too much like the digit 1. Python is graceful about converting to long integers when it is necessary.
Python 3 will not require the trailing L. It will silently deduce if you need an integer or a long integer.
How many different combinations of 32 bits are there? The answer is there are ; 2**32 in Python. The answer is too large for ordinary integers, and we get the result as a long integer.
>>> 2**32 4294967296L >>> 2**64 18446744073709551616L
There are about 4 billion ways to arrange 32 bits. How many bits in 1K of memory? bits. How many combinations of bits are possible in 1K of memory? .
I won’t attempt to reproduce the output from Python. It has 2,467 digits. There are a lot of different combinations of bits in only 1K of memory. The computer I’m using has bytes of memory; there are a lot of combinations of bits available in that memory.
Python offers floating-point numbers, often implemented as “double-precision” numbers, typically using 64 bits. Floating-point numbers are written in two forms: a simple string of digits that includes a decimal point, and a more complex form that includes an explicit exponent.
.0625 0.0625 6.25E-2 625E-4
The last two examples are based on scientific notation, where numbers are written as a mantissa and an exponent. The E (or code:e) , powers of 10 are used with the exponent, giving us numbers that look like this: and .
The last example isn’t properly normalized, since the mantissa isn’t between 0 and 10.
Generally, a number, n, is some mantissa, g, and an exponent of c. For human consumption, we use a base of 10.
Internally, most computers use a base of 2, not 10.
This differece in the mantissa leads to slight errors in converting certain values, which are exact in base 10, to approximations in base 2.
For example, 1/5th doesn’t have a precise representation. This isn’t generally a problem because we have string formatting operations which can make this tiny representation error invisible to users.
>>> 1./5. 0.20000000000000001 >>> .2 0.20000000000000001
Besides plain integers, long integers and floating point numbers, Python also provides for imaginary and complex numbers. These use the European convention of ending with J or j. People who don’t use complex numbers should skip this section.
3.14J is an imaginary number = .
A complex number is created by adding a real and an imaginary number: 2 + 14j. Note that Python always prints these in ()’s; for example (2+14j).
The usual rules of complex math work perfectly with these numbers.
>>> (2+3j)*(4+5j) (-7+22j)
Python even includes the complex conjugate operation on a complex number. This operation follows the complex number separated by a dot (.). This notation is used because the conjugate is treated like a method function of a complex number object (we’ll return to this method and object terminology in Classes).
>>> 3+2j.conjugate() (3-2j)
We can convert a number from one type to another. A conversion may involve a loss of precision because we’ve reduced the number of bits available. A conversion may also add a false sense of precision by adding bits which don’t have any real meaning.
We’ll call these factory functions because they are a factory for creating new objects from other objects. The idea of factory function is a very general one, and these are just the first of many examples of this pattern.
There are a number of conversions from one numeric type to another.
Generates an integer from the object x. If x is a floating point number, digits to the right of the decimal point are truncated as part of creating an integer. If the floating point number is more than about 10 digits, a long integer object is created to retain the precision. If x is a long integer that is too large to be represented as an integer, there’s no conversion. Complex values can’t be turned into integers directly.
If x is a string, the string is parsed to create an integer value. It must be a string of digits with an optional sign (+ or -).
>>> int("1243") 1243 >>> int(3.14159) 3
Generates a float from object x. If x is an integer or long integer, a floating point number is created. Note that long integers can have a large number of digits, but floating point numbers only have approximately 16 digits; there can be some loss of precision. Complex values can’t be turned into floating point numbers directly.
If x is a string, the string is parsed to create an float value. It must be a string of digits with an optional sign (+ or -). The digits can have a single decimal point (.).
Also, a string can be in scientific notation and include e or E followed by the exponent as a simple signed integer value.
>>> float(23) 23.0 >>> float("6.02E24") 6.0200000000000004e+24 >>> float(22)/7 3.14285714286
Generates a long integer from x. If x is a floating point number, digits to the right of the decimal point are truncated as part of creating a long integer.
>>> long(2) 2L >>> long(6.02E23) 601999999999999995805696L >>> long(2)**64 18446744073709551616L
Generates a complex number from real and imag. If the imaginary part is omitted, it is 0.0.
Complex is not as simple as the others. A complex number has two parts, real and imaginary. Conversion to complex typically involves two parameters.
>>> complex(3,2) (3+2j) >>> complex(4) (4+0j) >>> complex("3+4j") (3+4j)
Note that the second parameter, with the imaginary part of the number, is optional. This leads to a number of different ways to call this function. In the example above, we used three variations: two numeric parameters, one numeric parameter and one string parameter.
Python has a number of built-in functions, which are an integral part of the Python interpreter. We can’t look at all of them because many are related to features of the language that we haven’t addressed yet.
One of the built-in mathematical functions will have to wait for complete coverage until we’ve introduced the more complex data types, specifically tuples, in Tuples. The divmod() function returns a tuple object with the quotient and remainder in division.
The bulk of the math functions are in a separate module, called math, which we will cover in The math Module . The formal definitions of mathematical built-in functions are provided below.
Round number to ndigits beyond the decimal point.
If the ndigits parameter is given, this is the number of decimal places to round to. If ndigits is positive, this is decimal places to the right of the decimal point. If ndigits is negative, this is the number of places to the left of the decimal point.
>>> print round(678.456,2) 678.46 >>> print round(678.456,-1) 680.0
The string conversion functions provide alternate representations for numeric values. This list expands on the function definitions in Numeric Conversion (or “Factory”) Functions.
Create a hexadecimal string representation of number. A leading ‘0x’ is placed on the string as a reminder that this is hexadecimal.
>>> hex(684) '0x2ac'
Create a octal string representation of number. A leading ‘0’ is placed on the string as a reminder that this is octal not decimal.
>>> oct(509) '0775'
Create a binary representation of number. A leading ‘0b’ is placed on the string as a reminder that this is binary and not decimal.
>>> bin(509) '0b111111101'
Generates an integer from the string x. If base is supplied, x must be a string in the given base. If base is omitted, the string x must be decimal.
>>> int( '0775', 8 ) 509 >>> int( '0x2ac', 16 ) 684 >>> int( '101101101101', 2 ) 2925
The int() function has two forms. The int(x) form converts a decimal string, x, to an integer. For example, int('25') is 25.
The int(x,b) form converts a string, x, in base b to an integer. For example, int('25',8) is 21.
Generate a string representation of the given object. Generally, this is the a Python expression that can reconstruct the value; it may be rather long and complex.
The str() and repr() functions convert any Python object to a string. The str() version is typically more readable, where the repr() version is an internalized representation. For most garden-variety numeric values, there is no difference. For the more complex data types, however, the resultsof repr() and str() can be very different. For classes you write (see Classes), your class definition must provide these string representation functions.
These are several built-in functions which operate on simple collections of data elements.
Return the largest value.
>>> max(1,2,3) 3
Return the smallest value.
>>> min(1,2,3) 1
There are two sets of exercises. The first section, Basic Output and Functions, covers simpler exercises to reinforce Python basics. The second section, Numeric Types and Expressions, covers more complex numeric expressions.
Print Expression Results. In Command-Line Exercises, we entered some simple expressions into the Python interpreter. Change these simple expressions into print statements.
Be sure to print a label or identifier with each answer. Here’s a sample.
print "9-1's * 9-1's = ", 111111111*111111111
Here’s an example using the print() function.
from __future__ import print_function print( "9-1's * 9-1's = ", 111111111*111111111 )
Evaluate and Print Expressions. Write short scripts to print the results of the following expressions. In most places, changing integers to floating point produces a notably different result. For example (296/167)**2 and (296.0/167.0)**2 . Use long as well as complex types to see the differences.
Numeric Conversion. Write a print statement to print the mixed fraction as a floating point number and as an integer.
Numeric Truncation. Write a print statement to compute (22.0/7.0)-int(22.0/7.0). What is this value? Compare it with 22.0/7.0. What general principal does this illustrate?
Illegal Conversions. Try illegal conversions like int('A') or int( 3+4j ). Why are exceptions raised? Why can’t a simple default value like zero or None be used instead?
Evaluate and Print Built-in Math Functions. Write short scripts to print the results of the following expressions.
Why do the last two produce different results? What does the difference between the two results tell us about the number of digits of precision in floating-point numbers?
Evaluate and Print Built-in Conversion Functions. Here are some more expressions for which you can print the results.
Stock Value. Compute value from number of shares × purchase price for a stock.
Once upon a time, stock prices were quoted in fractions of a dollar, instead of dollars and cents. Create a simple print statement for 125 shares purchased at . Create a second simple print statement for 150 shares purchased at plus an additional 75 shares purchased at .
Don’t manually convert to 0.25. Use a complete expression of the form 2+1/4.0, just to get more practice writing expressions.
Convert Between |deg| C and |deg| F. Convert temperatures from one system to another.
Conversion Constants: 32 °F = 0 °C, 212 °F = 100 °C.
The following two formulae converts between °C (Celsius) and °F (Fahrenheit).
Create a print statement to convert 18 ° C to ° F.
Create a print statement to convert -4 ° F to ° C.
Periodic Payment on a Loan. How much does a loan really cost?
Here are three versions of the standard mortgage payment calculation, with m = payment, p = principal due, r = interest rate, n = number of payments.
Don’t be surprised by the sign of the results; they’re opposite the sign of the principle. With a positive principle, you get negative numbers; you are paying down a principle.
Mortgage with payments due at the end of each period:
Mortgage woth payments due at the beginning of each period:
Use any of these forms to compute the mortgage payment, m, due with a principal, p, of $110,000, an interest rate, r, of 7.25% annually, and payments, n, of 30 years. Note that banks actually process things monthly. So you’ll have to divide the interest rate by 12 and multiply the number of payments by 12.
Surface Air Consumption Rate. SACR is used by SCUBA divers to predict air used at a particular depth.
For each dive, we convert our air consumption at that dive’s depth to a normalized air consumption at the surface. Given depth (in feet), d , starting tank pressure (psi), s, final tank pressure (psi), f, and time (in minutes) of t, the SACR, c, is given by the following formula.
Typical values for pressure are a starting pressure of 3000, final pressure of 500.
A medium dive might have a depth of 60 feet, time of 60 minutes.
A deeper dive might be to 100 feet for 15 minutes.
A shallower dive might be 30 feet for 60 minutes, but the ending pressure might be 1500. A typical c (consumption) value might be 12 to 18 for most people.
Write print statements for each of the three dive profiles given above: medium, deep and shallow.
Given the SACR, c , and a tank starting pressure, s, and final pressure, f, we can plan a dive to depth (in feet), d, for time (in minutes), t, using the following formula. Usually the is a constant, based on your SACR and tanks.
For example, tanks you own might have a starting pressure of 2500 and and ending pressure of 500, you might have a c (SACR) of 15.2. You can then find possible combinations of time and depth which you can comfortably dive.
Write two print statements that shows how long one can dive at 60 feet and 70 feet.
Force on a Sail. How much force is on a sail?
A sail moves a boat by transferring force to its mountings. The sail in the front (the jib) of a typical fore-and-aft rigged sailboat hangs from a stay. The sail in the back (the main) hangs from the mast. The forces on the stay (or mast) and sheets move the boat. The sheets are attached to the clew of the sail.
The force on a sail, f, is based on sail area, a (in square feet) and wind speed, v`w` (in miles per hour).
For a small racing dinghy, the smaller sail in the front might have 61 square feet of surface. The larger, mail sail, might have 114 square feet.
Write a print statement to figure the force generated by a 61 square foot sail in 15 miles an hour of wind.
Craps Odds. What are the odds of winning on the first throw of the dice?
There are 36 possible rolls on 2 dice that add up to values from 2 to 12. There is just 1 way to roll a 2, 6 ways to roll a 7, and 1 way to roll a 12. We’ll take this as given until a later exercise where we have enough Python to generate this information.
Without spending a lot of time on probability theory, there are two basic rules we’ll use time and again. If any one of multiple alternate conditions needs to be true, usually expressed as “or”, we add the probabilities. When there are several conditions that must all be true, usually expressed as “and”, we multiply the probabilities.
Rolling a 3, for instance, is rolling a 1-2 or rolling a 2-1. We add the probabilities: .
On a come out roll, we win immediately if 7 or 11 is rolled. There are two ways to roll 11 (2/36) or 6 ways to roll 7 (6/36).
Write a print statement to print the odds of winning on the come out roll. This means rolling 7 or rolling 11. Express this as a fraction, not as a decimal number; that means adding up the numerator of each number and leaving the denominator as 36.
Roulette Odds. How close are payouts and the odds?
An American (double zero) roulette wheel has numbers 1-36, 0 and 00. 18 of the 36 numbers are red, 18 are black and the zeroes are green. The odds of spinning red, then are 18/38. The odds of zero or double zero are 2/36.
Red pays 2 to 1, the real odds are 38/18.
Write a print statement that shows the difference between the pay out and the real odds.
You can place a bet on 0, 00, 1, 2 and 3. This bet pays 6 to 1. The real odds are 5/36.
Write a print statement that shows the difference between the pay out and the real odds.
Spaces are used sparingly in expressions. Spaces are never used between a function name and the ()’s that surround the arguments. It is considered poor form to write:
The preferred form is the following:
A long expression may be broken up with spaces to enhance readability. For example, the following separates the multiplication part of the expression from the addition part with a few wisely-chosen spaces.
b**2 - 4*a*c