(contents)

Background and history

Python is a 5th generation language created by Guido van Rossum in the 1990's. Python became popular for scientific computing around 2000

At that time, however, python lacked the right powertools for working with matrices. That was fixed with the release of numpy in 2005, which unified the competing Numeric and upstart numarray modules. Since then, python has continued to develop, with object orientation, functional programing, closures, generators, unicode, coroutines.

Currently, two versions of python are in wide use: Python2.7 and Python3 From the beginners standpoint in english-speaking countries, the differences are minor. We'll use Python2.7 mostly.

References


Python's interpreter

To get a python shell running int the terminal, use the command

$ python

(I'm using the "$" symbol to represent the regular shell prompt -- don't type it, just the "python")

Like any command-line shell, python's interpreter evaluates instructions you enter at the >>> prompt. In this case, the instructions expressed in the python language. Type the following commands into the python prompt and observe the results.

First, python does simple arithmetic like a calculator...

>>> 2+3
>>> 2*3
>>> 2**3
>>> 7^2

Note that ** is used for exponentiation in python, while ^ is used for bit-wise negation (a boolean operation -- if you don't know what it is, do not worry, you do not need to know).

Python uses variables to store things in memory.

>>> x = 13
>>> y = x - 5
>>> print y

Here, we have also introduced the command print, which is one of about 30 reserved words that makes up the python language. Really, it's true, the whole language has only 30 words! Here is a slightly more complicated example of how print can be used with strings and inputs.

>>> print "Hello, World"
>>> name = raw_input("What is your name? ")
>>> print "Hello, %s.  Nice to meet you."%name

In the two cases above, x, y, and name are "variables". Variables in python are "dynamically typed", which means they can store many different kinds of things, and you just have to remember what kind of thing is in each one as you program. Python has a few basic variable types built in, and a simple class system for creating more of your own.

Basic data types and structures

One of the primary features of applied mathematics that differs from pure mathematics is that numbers are seldom pure abstractions. Instead, they usually have attributes, like units, which inform their use and interpretation. (If one number measures temperature in units of degrees Farenheit and another number measures distance in units of miles, we know it makes no sense to add these numbers together, even though there is no mathematical difficulty with the operation.)

Another important attribute of numbers that comes into play in programming is their type, or how they are stored in computer memory. There are many different types we could use for numbers, and these types effect how some algebraic operations work.

The most basic type for a number in python is an int, which is short for integer. An int is an integer, stored in base-2.

>>> x = 3
>>> type(x)

Integers

Numbers stored as int's can be added, subtracted, multiplied, and exponentiated. And since they are stored in binary format, we can also perform elementary boolean logic operations of and (&), or (|), and not (~) on them. For each of the calculations, try to predict what the answer will be before you do it.

>>> x = 2
>>> y = 5
>>> x + y
>>> - x
>>> x - y
>>> x * y
>>> x ** y
>>> x ^ y
>>> x | y
>>> x & y
>>> ~ x

Note that ** is used to represent exponentiation in python, fortran, and some other languages. What logical operation does ^ represent?

In addition to these operations, integers can be divided, but as you learned long ago, integer division is a little more complicated, involving quotients and remainders. Python can calculate both of these; x/y returns the quotient, while the modulus operation x%y returns the remainder.

>>> x, y = 13, 5
>>> x / y
>>> x % y

We can also compare integers using infix notation of common ordering relations; equality ==, less than <, less than or equal to <=, greater than >, greater than or equal to >=, unequal !=.

>>> x == y
>>> x != y
>>> x < y
>>> x >= y

Floating point numbers

The second type we commonly use for numbers is the float type which is short for floating point format, what you probably think of as "decimal numbers". Floating point numbers are typically stored in IEEE format with a sign bit (s), a mantissa (m), and an exponent (e) to represent the number (1)s×m×2e. All your standard calulator operations work like you would expect with floating-point numbers. Logic operations DO NOT work (or even make sense) for floats.

>>> x = 0.2
>>> y = 0.5
>>> x + y
>>> - x
>>> x - y
>>> x * y
>>> x / y
>>> x ** y
>>> # the following logic operations will not work, and will raise an error
>>> x ^ y
>>> x | y
>>> x & y
>>> ~ x

Testing equality is a little trickier with floats because two number that should be equal may differ because of round-off error -- only the largest 16 decimal places of a number can be stored. Because of this, we usually test if two numbers are "close enough" to be considered equal, rather than testing equality directly.

>>> x = (5 ** .5 + 1)/2
>>> y = 2/(5 ** .5 - 1)
>>> x/y
>>> x == y
>>> abs(x-y) < 1e-14
>>> abs(x-y)

Complex numbers

Python also has complex-numbers built-in, which can be very useful for simple 2-d graphics.

>>> x = 1j
>>> x * x
>>> (2-3j) * (2+3j)
>>> a = 2.+4j
>>> b = 1/a
>>> (a, b, a*b)
>>> b.real
>>> b.imag

Operation precedence

Just like in regular algebra, Python assumes certain operation precedence rules that can be overridden using parentheses.

>>> 2 + (3 * 5)
>>> (2 + 3) * 5
>>> 2 + 3 * 5

Catches between float and int in python2

Remember, integers are different from floating-point numbers!

>>> u = 3
>>> v = 3.
>>> type(u)
>>> type(v)
>>> u/2
>>> v/2

Python will "escalate" the type of numbers in a calculation to float (or complex) once they are introduced, but sometimes you have to make that explicit to the interpreter. Adding a decimal point to a number is an easy way to let the interpreter know that you want the answer to be a float rather than an integer. The other way is to explicitly cast the numbers.

>>> 1/5
>>> 1./5
>>> float(1)/5

Be aware that python3 changes how these numerical operations deal with number types. However, the general issues still exist in statically typed languages like C++ and Fortran.

Strings, lists and dictionaries

Python also has more complicated data-types built-in.

Functions

In most modern computer languages, functions are used regularly. A function in python is a piece of code that takes one or more arguments, and returns one or more results. Functions begin with the keyword def and usually finish with the keyword return followed by whichever variables you want to return. The body of each function must be indented 4 spaces in from the beginning of the line. The first line of a function must always end with a colon :.

The basic format of a function definition is

def ...( .... ) :
    ...
    ...
    return ...

Try the following example functions.

>>> def F2C(F):
>>>     C = (5 * F - 160)/9.
>>>     return C
>>> 
>>> def convertF2C():
>>>     temp = raw_input("What_is the temperature (in degrees Farenheit)? ")
>>>     tempInCelcius = F2C(temp)
>>>     print "   That would be %.1f degrees Celcius"%tempInCelcius
>>>     return
>>> 
>>> convertF2C()

There's allot here to absorb. There are two functions, each defined using the def keyword. The lines with def end in a colon. The bodies of each function are delimited using indentation. The python language uses indentation to indicate which parts of a program are inside other parts -- in this case, the indentation indicates which lines of code are inside which functions. Unlike some other languages like C and Perl, the indentation is not optional -- indentation is required. Fortunately, most editors help you stay consistent with automatic indentation.

The variables created inside a function can not be seen by other code and functions -- only the things that are returned can be used. The domains where a name can be used in a language are called its scope. In python, the general scoping rule is that variables created inside functions are forgotten as soon as the function ends unless they are returned by the function. For example, in the functions above, the function F2C can not see or use the variable temp, while the function convertF2C can ot see or use the variable C.

Conditionals

Being able to do simple calculations is good, but often we need to change a calculation to match the situation at hand. That's where conditionals come in. A conditional is the computer-language equivalent of a logical implication, an "IF .... THEN ... " statement. In fact, that's exactly how many languages implement conditionals. Here is an example of a python conditional inside a function.

>>> def isodd(n):
>>>     if n > 0:
>>>         print n, " is a positive number"
>>>     else:
>>>         print n, " is not a positive number"
>>>     return

The conditional begins with if, is follows by a logical expression that evaluates to either True or False, and ends in a colon. If the logical expression is true, then the interpretter executes the indented code making up the conditional's body. Otherwise, the code in else clause is executed. The else is optional -- not all if-statements have an else. Sometime conditionals also use elif closes to test additional situations.

>>> def tellsign(n):
>>>     if n > 0:
>>>         print n, " is a positive number"
>>>     elif n < 0:
>>>         print n, " is a negative number"
>>>     else:
>>>         print n, " is zero"
>>>     return

Looping

The next most important concept in programming is the Loop. A loop is a piece of code that you want to execute repeatedly in some form or other. Inside the computer, loops are executed by combining conditionals with goto statements telling the program to change it's execution location. In a structured language like python, loops are described using the while or for keywords.

>>> t = 0.
>>> print "A simple temperature conversion table"
>>> print "-------------------------------------"
>>> while t < 100:
>>>     print t, F2C(t)
>>>     t = t - 5

Like an if statement, the while loop has a boolean expression, ends in a colon, and has an indented body.

A for loop is a little fancier and more powerful.

>>> for T in range(10):
>>>     print T, F2C(T)
>>>
>>> for T in range(-10,100,5):
>>>      print T, F2C(T)

The range function returns a list, including the first entry but never the last, incrementing by 1 by default.

Combining functions, loops, and conditionals

Together with variables, loops and conditionals are the core components that make a computer language Turing-complete -- any computer program written in a classical language can be translated and computed in any language with loops and conditionals. On the other hand, because of the power of these language constructions, there is no universally applicable way to verify the correctness of your programs.

>>> def gcd(x, y):
>>>     if x > y:
>>>         return gcd(y, x)
>>>     if x < 0:
>>>         return gcd(-x, y)
>>>     while y >= x:
>>>         y = y - x
>>>         if y == 0:
>>>             return x
>>>     return gcd(y, x)

To test if our function works, we can try it with a few examples that we already know the answers to.

>>> gcd(2,3)
>>> gcd(4,6)
>>> gcd(6,4)
>>> gcd(-6,4)
>>> gcd(-6,-4)
>>> gcd(30,100)

You can use Visualize python to follow how the program works -- once you learn to read code, you should be able to do this all in your head.

Homework

  1. Find a better implementation of the gcd algorithm for calculating greatest common divisors. Your program may be better because it is shorter, faster, or more readable.

  2. Estimate the fraction of pairs of positive integers are relatively prime to each other using your gcd function.

  3. Write a function to calculate the least common multiple of two positive integers.