Short explanation of Python

[ambient page updated 11 Oct 05] ... [ home ] ... [ garrett@umn.edu ]

At the unix prompt, type "python" (and hit return) and you'll get the
python prompt:

>>>

To _stop_ python and return to the unix prompt, type "Control-D" at
the python prompt.

If python gets stuck in a loop or in a too-long process, "Control-C"
interrupts it and returns you to the prompt.

In its simplest use, the python prompt gives a read-evaluate-print
loop, which has many built-in functions useful for basic computational
number theory. Addition is +, multiplication is *, division is /,
substraction is -, use of parentheses is as usual. A slightly less
standard use is ** for exponentiation, so, for example, 2**5=32. The
python prompt's loop can be used as a simple calculator, by entering
an expression and hitting "return" to evaluate it:

>>> 2*3
6
>>> 4 * 4 
16
>>> 2**10
1024
>>> (3+5) * (1+2)
24
>>> 

Whitespace between operators doesn't matter.

An unusual feature of python is that it has built-in
infinite-precision integers, of arbitrary size. These are denoted by
appending an "L" to the numeral. If the numbers get too large for
ordinary integers, you'll get an overflow error:

>>> 2 ** 100
Traceback (innermost last):
  File "", line 1, in ?
OverflowError: integer pow()
>>> 

But if you use "long" integers it'll be fine:

>>> 2L ** 100
1267650600228229401496703205376L
>>> 

Of course, you can still ask the machine to do tedious and stupid
things, such as

>>> 2L ** 1000000

##  If you do this, for example, the machine will appear to hang. If
##  you realize that you've made a stupid request, you _can_ stop it
##  in the middle without harming anything: do Control-C, and you'll
##  be returned to the prompt.

For use in crypto and other computational number theory, there is a
built-in function which does _modular_exponentiation_: to compute

			x^e % m    (x to the e power reduced modulo m)

do _not_ do

>>> (x**e) % m                ## bad!

but instead do

>>> pow(x,e,m)                ## good

The latter uses a smart algorithm. So, for example, ridiculously large
exponents are ok (as long as the "L" suffix is used):

>>> pow(2L, 10L**100+1, 10L**100+1)
6660888126245688699182136543775795641628347778449324704651411345556300289268422357122875536174966145L

takes an imperceptible amount of time to evaluate. Very good.

#################################################################
#################################################################

There are built-in mathematical functions, too, but preparation for
them requires _importing_ the "math module": do

>>> import math

just once at the beginning of a python session, to import the math
module. Thereafter, the following functions and constants (among
others) are available:

math.log10( )     ## log base 10
math.pi           ## 3.14159265359
math.sqrt( )      ## square root, in floating-point: watch out!
math.acos( )      ## inverse cosine
math.sin( )       ## sine function, in radians
math.atan2(,)     ## = arctan( firstargument / secondargument )
math.exp( )       ## exponentiation base e
math.asin( )      ## arcsine
math.floor( )     ## greatest integer less-than-or-equal-to: the floor function
math.fabs( )      ## least integer greater-than-or-equal-to: the ceiling function
math.log( )       ## natural log
math.e            ## 2.71828182846
math.atan( )      ## arctangent

The usage as set up here requires the prefix "math", as in

>>> math.log10(2)
0.301029995664
>>>

On hazard is that these functions only keep a fixed number of decimal
places of "precision", so

######################################################################

To _replay_ and _edit_ the last command, a nice subset of EMACS
text-editing capabilities is available: among other things, a basic
set of commands is

("C-x" is an abbreviation for "Control-x")
("M-x" is an abbreviation for "Meta-x")

C-f           ;; move forward by one character
C-b           ;; move backward by one character
M-f           ;; move forward by one word
M-b           ;; move backward by one word

C-p           ;; recall previous command (can be iterated further!)
C-n           ;; move to next command

C-a           ;; move to beginning of line
C-e           ;; move to end of line

C-d   ;; delete next character
M-d   ;; delete next word

DEL           ;; delete previous character
M-DEL         ;; delete previous word

C-k           ;; delete from point to end of line

The arrow keys usually work, also.

######################################################################

A related organizational tool (as well as actualy programming
capability) is the possibility of _named_variables_. This can be done
at the python command line loop, using "=" to assign values to
variables.

>>> n = 1001
>>> n
1001
>>> n = n+1
>>> n
1002
>>> 

This allows more coherent treatment of complicated expressions:
>>> n =1001
>>> n
1001
>>> n = n+1
>>> n
1002
>>> n = 1000001L
>>> n        
1000001L
>>> a = pow(2,n,n)
>>> a
210991L
>>> 

######################################################################

"While loops" are easy to write:

>>> i=1
>>> while i<10:      ## hit return at end of line
...     print `i`    ## hit tab at beginning of line, return at end
...     i = i+1      ## hit tab at beginning of line, return at end
...                  ## hit return to close up the block
1
2
3
4
5
6
7
8
9
>>>

Note that the backquotes convert _numbers_ to _strings_

Note that braces are _not_ used. Rather, code blocks are indicated by
_indentation_. Thus, every line in the "while block" must be indented,
conventionally by a tab. Sub-blocks have their own further
indentation:

>>> i = 1                ## hit return
>>> j = 1                ## hit return
>>> while i<5:           ## hit return
...     while j <= i:    ## tab at beginning, return at end of line
...             print `i+j`   ## _two_ tabs at beginning, return at end
...             j = j+1     ## _two_ tabs at beginning, return at end
...     i = i+1             ## _one_ tab at beginning, return at end
...	                      ## just a return, to close the outer block
2
4
6
8
>>> 

######################################################################

"For loops" are similar, and also "if/else" statements are reasonable:

>>> n = 1000001
>>> n % 3
2
>>> n = 1000001
>>> for i in range(1,1001):
...     if n % i == 0:
...             print `i`                          
... 
1
101
>>>

The syntax of the "else" clause is:

Note that the _test_ for equality (as opposed to _assignment_ of
variable values) is a _double_ equal sign.

The "range" thingy tells the variable i to assume all integer values
including the bottom but excluding the top value. It has an optional
argument that tells how much to increment it (the default is 1):

>>> for i in range(1,10,3):
...     print `i`
... 
1
4
7
>>> 

If the range is rather large, it may be more economical to use a
variant construct "xrange", rather than plain "range", which does not
create the whole list in memory at one time:

>>> for i in xrange(1,100000):
...     if i== 12345:
...            print `i`
...	  elif i== 1234501:
...			   print "Hello"
...	  else:
...				pass
12345
'Hello'
>>>

This example also showed how to print a string. It also showed how to
have a "no-operation" occur: the keyword is "pass" 

######################################################################

It is easy to define simple functions to use in the python
command-line loop, using "def" and "return" keywords:

>>> def f(x):                       ## hit return
...     return x*x*x-3*x*x+17*x-1   ## hit tab at beginning of line, return at end
...                                 ## hit return to end definition block
>>> f(1)
14
>>> f(0)
-1
>>> f(-1)
-22
>>> f(2)
29
>>> 

Somewhat more complicated things can also be set up in code blocks,
using "if/else" blocks and "for" or "while" loops:

>>> def f(n):
...     if n == 1:
...             return 1
...     elif n==2:
...             return 2
...     else:
...             return 3
... 
>>> f(4)
3
>>> 

Variable names and function names can be long and descriptive if you
want:

>>> def primality_test(n):
...     bound = int( math.sqrt(n) )
...     for i in range(3,bound+1,2):
...             if n % i == 0:
...                     return `i` + " divides " + `n`
...     return `n` + " is prime "
... 
>>> primality_test(101)
'101 is prime '
>>> primality_test(105)
'3 divides 105'
>>> 

Note that the "+" operator also concatenates _strings_, which can be
delimited by double-quotes.

######################################################################

_List_ syntax is reasonable:

>>> mylist = [1,2,3]
>>> mylist
[1, 2, 3]
>>> mylist.append(101)
>>> mylist
[1, 2, 3, 101]
>>> mylist.append(123)
>>> mylist
[1, 2, 3, 101, 123]
>>> mylist

Lists can be used in _for_loops_:

>>> for i in mylist:
...     print `i`
... 
1
2
3
101
123
>>>

Here's the time to point out a variant form of _print_, which doesn't
insert a newline after each item, but only a space:

>>> for i in mylist:
...     print `i`,
... 
1 2 3 101 123
>>>

That is, the comma after the `i` causes the "print" to only insert a
space rather than newline.

The length of a list is accessible by the "len" function, which also
can compute the length of a _string_:

>>> len(mylist)
5
>>> len("hello")
5
>>> 

The various elements of a list are accessible by typical index
notation, with indices beginning at 0:

>>> mylist[2]
3
>>> mylist[0]
1
>>> 

_Slices_ of lists use a funny but reasonable notation

>>> mylist[0:3]
[1, 2, 3]
>>> mylist[:-1]
[1, 2, 3, 101]
>>> mylist[:-2]
[1, 2, 3]
>>> mylist[0:-2]
[1, 2, 3]
>>> mylist[1:-2]
[2, 3]
>>> mylist[2:-2]
[3]
>>> mylist[3:-2]
[]
>>> myslice = mylist[3:]
>>> myslice
[101, 123]
>>>

######################################################################

When you get tired of retyping at the command-line loop, you can (of
course) put python code into files and _either_ "run" such files on
their own, _or_ use them as "modules" from the python command-line
loop itself.

To load into the command loop files defining
functions/subroutines/methods, these files should end with ".py", like
"myfile.py", _and_ should either be in your current directory (in a
unix sense), or in your python module search path. (At the unix prompt
do "echo $PYTHONPATH" to see the value of this environmental
variable.)

Suppose that myfile.py contains just the two lines (ended by a newline!)

def f(n):
	 return n+1

(Assuming that the python interpreter can find the files, because
they're in the search path), to load myfile.py into the python loop,
do

>>> import myfile

Note that the suffix is not included. Then functions defined in myfile
can be called by

>>> myfile.f(5)
6

If the definition of myfile.f is changed in myfile.py and you want to
"reload", the syntax is

>>> reload(myfile)

To load functions/methods in a manner so that the prefix "myfile." is
not needed, use the syntax

>>> from myfile import f
>>> f(11)
12
>>>

Such Python modules can include auxiliary functions called
internally. Such internal use does not require use of the prefix
naming the module. For example, myfile.py might contain the 3 lines
(with newline at the end)

import math
def mysqrt(n):
	 return math.sqrt(n)

Then
>>> reload(myfile)
>>> myfile.mysqrt(16)
4.0
>>>


Unless explicitly noted otherwise, everything here, work by Paul Garrett, is licensed under a Creative Commons Attribution 3.0 Unported License. ... [ garrett@umn.edu ]

The University of Minnesota explicitly requires that I state that "The views and opinions expressed in this page are strictly those of the page author. The contents of this page have not been reviewed or approved by the University of Minnesota."