Home
Python ... Python software ... ... License ... Introduction ... German texts ... ... Einführung ... ... Workshop Python ... ... Perl und Python
Chemical Engineering ... Links
About me ... Publications/Talks |
Programming Python on OS/2
Stefan Schwarzer
2-4 Nov 2001
Warpstock Europe 2001
Abstract
From the Python Language Website:
Python is an interpreted, interactive, object-oriented programming
language. It is often compared to Tcl, Perl, Scheme or Java.
Python combines remarkable power with very clear syntax. It has
modules, classes, exceptions, very high level dynamic data types, and
dynamic typing. There are interfaces to many system calls and
libraries, as well as to various windowing systems (X11, Motif, Tk,
Mac, MFC). New built-in modules are easily written in C or C++. Python
is also usable as an extension language for applications that need a
programmable interface.
The Python implementation is portable: it runs on many brands of UNIX,
on Windows, DOS, OS/2, Mac, Amiga... If your favorite system isn't
listed here, it may still be supported, if there's a C compiler for
it. Ask around on comp.lang.python -- or just try compiling Python
yourself.
Python is copyrighted but freely usable and distributable, even for
commercial use.
Overview
Introduction
Origin
Python (named after the comedy group "Monty Python") was
invented by Guido van Rossum in the early nineties. His goal was
to create a programming language which is easy to learn and to read,
and nevertheless powerful.
Strengths of Python
- easy to install
(OS/2 WarpIN package)
- easy to learn
- easy to read ("executable pseudocode")
and to maintain
- easy to write
- well suited to prototyping
- highly scalable
License
Python is Open Source Software.
It may be
- used and distributed
- in unmodified or modified form
- in open or closed source software
- without having to pay license fees.
Applications
- text processing (including XML)
- system administration (mostly on Unix)
- system integration ("glue language")
- internet programming (HTML, HTTP, FTP, SMTP, CGI, etc.)
- numerics (NumPy, with C extensions)
- image processing (Python Image Library, PIL, with C extensions)
Resources
Links
Books
- A well-written book on Python is
"Learning Python" by Mark Lutz and David Ascher,
published by O'Reilly. Unfortunately, the book covers only
Python 1.5.2 instead of the current version 2.1 [meanwhile 2.2.1].
On the other hand, most or all examples will also work with Python 2.1
[2.2.1].
- Mark Lutz also wrote
"Programming Python". This book deals with Python
applications, mainly text processing, internet programming, and
GUI programming. (The GUI stuff requires the Python GUI framework
Tkinter and thus won't run with the Presentation Manager but
perhaps with XFree/2.) The book's examples are up to
Python 2.0.
- More books are listed on the
"Python Bookstore"
page.
Data Types
There are three groups of data types in Python:
- Scalars have the subtypes integer, long integer (with an
arbitrary number of digits), floating point numbers, complex
numbers, and strings.
i = 1; li = 9999999999L; f = 3.14; c = 3+4j; s = 'Hello'
There is no explicit pointer type.
- Sequences contain any number of arbitrary objects in a
defined order. Sequence types are subdivided into lists and tuples.
Lists are mutable, i. e. can be changed in-place while
tuples cannot.
L = [1, 3]; L.append(7); print L[2]
prints 7, while
T = (1, 3); T.append(7)
results in an error message. Tuples can't be modified after
creation. However, you can build a new tuple from existing ones:
T = (1, 3) + (7,)
- Associative lists (more commonly known as dictionaries)
allow the access to values based on keys. These keys can
be arbitrary but immutable objects. For example,
D = {'b': 'Python', 'a': 5}; print D['a']
prints 5.
- Unlike Pascal, C, C++ or Java, Python is a dynamically
typed language. Thus, the following code is perfectly valid
Python:
a = 7 # 7 (integer)
a = a / 2.0 # 3.5 (float)
a = str(2*a) + ' bytes' # '7 bytes' (string)
Operators
Python has the following operators:
- Arithmetic and bitwise operators
+ - * / % ** ~ << >> & ^ |
- Relational and logical operators
is in < <= > >= == != not and or
- Assignments
= += -= *= /= %= **= <<= >>= &= ^= |=
- Other operators
() [] {} [:] `` . lambda
Compound Statements
- Statements that belong to the same logical group are indented
by the same amount of whitespace:
if a > 0:
b = 1
c = 2
Usually, each statement starts on a new line. You can write
several statements on the same line if you delimit them by
semicolons (like in the section "Data types").
- You don't need special characters (like "{" and
"}" in C) to mark a group of statements; the logical
structure is determined by the indentation.
- A statement is continued by putting a backslash
\ at the end of a line. This isn't necessary if
there are still parentheses (or brackets or braces) open:
my_list = [1, # open bracket, statement continues
['abc', 2], # nested list
-3+6j] # closed outermost bracket, statement ends
print my_list
Conditional Execution
- Python uses
if, elif (not
elsif or elseif), and else
to denote conditional execution of statements. For example,
if a > b:
print 'a is greater than b.'
elif a < b:
print 'a is lower than b.'
else:
print 'a equals b.'
Note the colons and the identation.
- You can use "abbreviated" interval tests:
if 2 <= a <= 7:
print 'a is in the interval [2, 7].'
Loops
- Loops in Python are defined by the keywords
for
and while.
- The following example uses a
while loop to
collect all numbers from 0 to 99 in a list.
numbers = []
i = 0
while i < 100:
numbers.append(i)
i = i + 1 # or i += 1 since Python 2.0
- A similar
for loop looks like
numbers = []
for i in range(100):
numbers.append(i)
- Instead of the expicit loops above also an implicit loop
is possible:
numbers = range(100)
range(100) generates a list of all integers from
0 to 99 (not 100).
- You can use a
for loop to iterate not only over
numbers but also over arbitrary sequences:
for programming_language in [C, Perl, Python, Pascal]:
explain(programming_language)
-
break quits the (next innermost) loop immediately:
found = 0
for entry in entries:
if searched == entry:
found = 1
break # don't iterate further if the
# searched entry has been found
-
continue starts the next iteration of the
next innermost loop:
# squares of the positive numbers in a list
X = [1, -1, 2.4, -5.7]
for num in X:
if num <= 0:
continue
print 'number:', num, ' square:', num**2
prints
number: 1 square: 1
number: 2.3 square: 5.76
Application Example
A file is read, sorted, and written to a file with the additional
extension .sorted.
You could do it with this - rather long - solution:
import sys
# get filename
filename = sys.argv[1] # script name in sys.argv[0]
lines = []
# read file
try:
file = open(filename, 'r')
while 1:
line = file.readline()
if line == '':
break
lines.append(line) # lines + [line]
file.close()
except IOError, msg:
print filename, "is not readable (%s)" % msg
sys.exit(1)
# sort
lines.sort()
filename = filename + '.sorted'
# write file
try:
file = open(filename, 'w')
for line in lines:
file.write(line)
file.close()
except IOError, msg:
print filename, "is not writable (%s)" % msg
You might do it shorter:
import sys
# get filename
filename = sys.argv[1]
# read file
try:
file = open(filename, 'r')
lines = file.readlines()
file.close()
except IOError, msg:
print filename, "is not readable (%s)" % msg
sys.exit(1)
# sort lines
lines.sort()
filename = filename + '.sorted'
# write file
try:
file = open(filename, 'w')
file.writelines(lines)
file.close()
except IOError, msg:
print filename, "is not writable (%s)" % msg
If you don't want to catch errors explicitly, you could even code this
(quick and dirty ;-) ) solution:
from sys import argv
lines = open(argv[1], 'r').readlines()
lines.sort()
open(argv[1]+'.sorted', 'w').writelines(lines)
Note: If an error occurs, this example will fail with a traceback,
not silently.
Subroutines
- You can use the keywords
def or
lambda to define Python subroutines. These are
more commonly known as functions.
- In the definition of a function with
def, the
body of the function is indented.
- Arguments are passed as named variables.
- Any Python object (e. g. a list, a dictionary, or a
list of tuples of class objects) can be returned to the caller via
the keyword
return.
- If there is no
return statement or no value
is given the special value None is returned.
- Default arguments (as in C++) are possible.
- The order of the parameters in the call may be changed if
if you assign them to the appropriate names which appear the
function's argument list.
- The following function returns the index of an item
if it is found in the sequence, or
None
otherwise.
def index(searched, items):
"Look for 'searched' in the sequence 'items'"
for i in range( len(items) ):
if items[i] == searched:
return i
return None # not found, statement
# written for clarity
print index( 3, [1, 2, 3, 4] ) # search 3 in the list
print index( items=[1, 2, 3, 4], # alternative syntax
searched=3 )
Modules
Basics
- Modules are programming units in individual files. This
separation is mainly done to make the code in the module reusable
in other contexts.
- To make a module usable in many contexts, it has to designed
explicitly for this purpose.
- Besides the interpreter and documentation, the Python
distribution contains a large number of modules (about 200).
For example, there are modules for text processing and interfaces
to internet protocols (HTTP, FTP, etc.).
- Module files have the suffix
.py which is the
same as for regular Python "programs". So a module file
can also be passed to the interpreter on the command line to be
executed as a program.
- There is no special statement that marks a file as a
module. The distinction between a module and a program is
based on its usage, not on its code.
- An example for a very simple module is
# a_module.py
an_integer = 1
a_list = [2, 3]
def square(x):
return x**2
- In other files the module is loaded and thus made available
via the
import statement.
- Names which are defined in the imported module are prefixed
with the module's name and a dot, e. g.
# main program
import a_module
test = a_module.an_integer # test = 1
test = a_module.square(7) # test = 49
Commonly Used Python Modules
- The
sys and os modules are used
for basic interactions with the operating system.
import sys
import os
print sys.argv[1:] # print command line arguments
os.system('dir') # show an OS/2 directory
-
math deals with certain mathematical functions.
import math
print math.sin(1.0) # 0.841470984808
-
re works with regular expressions.
import re
pattern = re.compile(r'[A-Za-z]+')
text = 'Fri 26 June 2001, 26Jun2001'
print pattern.findall(text) # ['Fri', 'June', 'Jun']
- The
time module contains date and time
related functions.
import time
# print the currect date in the format 2001-11-02
print time.strftime( '%Y-%m-%d', time.localtime() )
Object-oriented Programming (OOP)
Basics of OOP
- Objects provide variables (state) and functions
(methods) which work on these variables. As an example,
consider an oven which is described by the variables
- temperature (in °C)
- flap open/closed
and has the functions
- open_flap (no parameters)
- close_flap (no parameters)
- fill_with (parameter: material)
- heat_to (parameter: desired temperature in °C)
- cool_down (no parameters)
- There can exist several objects (instances) of the
same kind which are independent of each other. For example, there
could be many ovens with their individual state.
- The interface between the object and the code that uses it
should only reveal what is done by the object but not
how it is accomplished internally. The latter remains
private to the object.
-
Object types (classes) can form a basis for
similar but specialized types. The derivation of new classes
from existing ones is called inheritance.
In the context of the above example, you could define a new class
CirculationAirOven which is a special kind of an oven. This new class
could contain a new state variable which represents if the
circulation is on or off, and an additional method to change this
state.
OOP in Python
- A new class is generated with the
class
statement (see below).
- The constructor, named
__init__, builds a
new object. During that, the object can be initialized,
i. e. state variables can be set and methods can be
called.
- A call of a method implicitly passes a reference to the
object as the first argument.
- To derive a new class from an existing one the old class
is specified as a "parameter" in the
class
statement that defines the new class.
- A possible implementation of the mentioned oven class is
# oven.py
class Oven:
def __init__(self):
self.temperature = 20 # room temperature
self.is_open = 0 # flap closed
self.material = None # oven is empty
def open_flap(self):
if self.temperature > 20:
print "Please close the flap before opening the oven."
return
self.is_open = 1
def close_flap(self):
self.is_open = 0
def fill_with(self, material):
if not self.is_open:
print "Please open the oven before attempting to fill it."
return
self.material = material
def heat_to(self, temperature):
if self.is_open:
print "Please close the flap before heating up the oven."
return
self.temperature = temperature
def cool_down(self):
self.temperature = 20
# ----------------------------------------------------------------
# circulating_air_oven.py
import oven
class CirculationAirOven(oven.Oven):
def __init__(self):
oven.Oven.__init__(self)
self.circulation = 0
def circulation_on(self):
self.circulation = 1
def circulation_off(self):
self.circulation = 0
# ----------------------------------------------------------------
# oventest.py
import circulating_air_oven, time
oven = circulating_air_oven.CirculationAirOven()
oven.open_flap()
oven.fill_with('dough')
oven.close_flap()
oven.circulation_on()
oven.heat_to(250)
time.sleep(60*60) # bake one hour
oven.cool_down()
oven.circulation_off()
More Examples
- get an HTML page from a server and print it
import urllib
page = urllib.urlopen('http://www.ndh.net/home/sschwarzer/python/')
print page.read()
page.close()
- compose and send an email
import smtplib
mailhost = smtplib.SMTP('mail.ndh.net')
text = """From: s.schwarzer@ndh.net
To: s.schwarzer@ndh.net
Subject: Demo mail
This is a small demo text."""
mailhost.sendmail('s.schwarzer@ndh.net', [s.schwarzer@ndh.net'], text)
mailhost.quit()
- work with comples numbers (output is shown in bold)
import math, cmath
print math.sin(1.0)
0.841470984808
print math.sin(1+3j)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can't convert complex to float; use e.g. abs(z)
print cmath.sin(1+3j)
(8.4716454543+5.41268092318j)
Summary
- Think before you act. This even applies to Python. ;-)
- Also, in Python, you are able to write code that is hard
to understand, if you are careless.
- The time you save in Python by implementation details
(debugging!) can be invested in better program design and
algorithms.
|