Simple Numeric Expressions and Output

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.

Seeing Output with the print() Function (or print Statement)

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.

Note

Python 3.0

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() Function

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:

print([object, ...][, sep=' '][, end='n'][, file=sys.stdout])

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.

Numeric Types and Operators

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.

More sophisticated math is separated into the math module, which we will cover later. However, a few advanced math functions are an integral part of Python, including abs() and pow().

Integers

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.

Important

Leading Zeroes

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.

Important

Python 3

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.

Long Integers

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.

Important

Python 3

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}; 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? 1024 \times 8 bits. How many combinations of bits are possible in 1K of memory? 2^{1024 \times 8}.

print 2L**(1024*8)

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 512 \times 1024K bytes of memory; there are a lot of combinations of bits available in that memory.

Python will silently convert between ultra-fast integers and slow-but-large long integers. You can force a conversion using the int() or long() factory functions.

Floating-Point Numbers

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: 6.25 \times 10^{-2} and 625 \times 10^{-4}.

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.

n = g \times 10^c

n = h \times 2^d

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

Complex Numbers

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 = 3.14 \times \sqrt{-1}.

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).

For example:

>>> 3+2j.conjugate()
(3-2j)

Numeric Conversion (or “Factory”) Functions

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.

Numeric Factory Function Definitions

There are a number of conversions from one numeric type to another.

int(x) → integer

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
float(x) → float

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
long(x) → long

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
complex(real[, imag]) → complex

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.

Built-In Math Functions

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.

Built-In Math Functions

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.

abs(number) → number
Return the absolute value of the argument, \lvert x \rvert.
pow(x, y[, z]) → number
Raise x to the y power, x^y. If z is present, this is done modulo z, x^y \mod z.
round(number[, digits]) → float

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.

Examples:

>>> print round(678.456,2)
678.46
>>> print round(678.456,-1)
680.0

String Conversion Functions

The string conversion functions provide alternate representations for numeric values. This list expands on the function definitions in Numeric Conversion (or “Factory”) Functions.

hex(number) → string

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'
oct(number) → string

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'
bin(number) → string

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'
int(string[, base]) → integer

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.

str(object) → string
Generate a string representation of the given object. This is the a “readable” version of the value.
repr(object) → string

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.

For the numeric examples we’ve seen so far, the value of repr() is generally the same as the value of str().

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.

Collection Functions

These are several built-in functions which operate on simple collections of data elements.

max(value, ...) → value

Return the largest value.

>>> max(1,2,3)
3
min(value, ...) → value

Return the smallest value.

>>> min(1,2,3)
1

Additionally, there are several other collection-handling functions, including any(), all() and sum(). These will have to wait until we can look at collection objects in Data Structures.

Expression Exercises

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.

Basic Output and Functions

  1. 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 )
    
  2. 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.

    • 355/113 * ( 1 - 0.0003/3522 )
    • 22/17 + 37/47 + 88/83
    • (553/312)**2
  3. Numeric Conversion. Write a print statement to print the mixed fraction 3 \frac{5}{8} as a floating point number and as an integer.

  4. 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?

  5. 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?

  6. Evaluate and Print Built-in Math Functions. Write short scripts to print the results of the following expressions.

    • pow( 2143/22, 0.25 )
    • pow(553/312,2)
    • pow( long(3), 64 )
    • long( pow(float(3), 64) )

    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?

  7. Evaluate and Print Built-in Conversion Functions. Here are some more expressions for which you can print the results.

    • hex( 1234 )
    • int( hex(1234), 16 )
    • long( ‘0xab’ )
    • int( ‘0xab’ )
    • int( ‘0xab’, 16 )
    • int( ‘ab’, 16 )
    • cmp( 2, 3 )

Numeric Types and Expressions

  1. 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 3 \frac{3}{8}. Create a second simple print statement for 150 shares purchased at 2 \frac{1}{4} plus an additional 75 shares purchased at 1 \frac{7}{8}.

    Don’t manually convert \frac{1}{4} to 0.25. Use a complete expression of the form 2+1/4.0, just to get more practice writing expressions.

  2. 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).

    F = 32 + \frac{212 - 32}{100} \times C

C = (F - 32) \times \frac{100}{212 - 32}

    Create a print statement to convert 18 ° C to ° F.

    Create a print statement to convert -4 ° F to ° C.

  3. 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.

    m = p \times \left( \frac{r}{1 - (1+r)^{-n}} \right)

    Mortgage with payments due at the end of each period:

    m = \frac{-r p (r+1)^n}{(r+1)^n - 1}

    Mortgage woth payments due at the beginning of each period:

    m = \frac{-r p (r+1)^n}{[(r+1)^n-1](r+1)}

    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.

  4. 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.

    c = \frac{33 (s - f)}{t(d + 33)}

    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 33(s-f)/c is a constant, based on your SACR and tanks.

    \frac{33(s-f)}{c} = t(d+33)

    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.

  5. 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).

    f = w^2 \times 0.004 \times a

    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.

  6. 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: 1/36+1/36 = 2/36 = 1/18.

    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.

  7. 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.

Expression Style Notes

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:

int (22.0/7)

The preferred form is the following:

int(22.0/7)

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