In this article, I’ll show you a toy example to learn the XOR logical function. My objective is to make it as easy as possible for you to to see how the basic ideas work, and to provide a basis from which you can experiment further. In real applications, you would not write these programs from scratch (except we do use numpy for the low-level number crunching), you would use libraries such as Keras, Tensorflow, SciKit-Learn, etc.
What do you need to know to understand the code here? Python 3, numpy, and some linear algebra (e.g. vectors and matrices). If you want to proceed deeper into the topic, some calculus, e.g. partial derivatives would be very useful, if not essential. If you aren’t already familiar with the basic principles of ANNs, please read the sister article over on AILinux.net: A Brief Introduction to Artificial Neural Networks. When you have read this post, you might like to visit A Neural Network in Python, Part 2: activation functions, bias, SGD, etc.
This less-than-20-lines program learns how the exclusive-or logic function works. This function is true only if both inputs are different. Here is the truth-table for xor:
a
b
a xor b
0
0
0
0
1
1
1
0
1
1
1
0
Main variables:
Wh & Wz are the weight matrices, of dimension previous layer size * next layer size.
X is the input matrix, dimension 4 * 2 = all combinations of 2 truth values.
Y is the corresponding target value of XOR of the 4 pairs of values in X.
Z is the vector of learned values for XOR.
# XOR.py-A very simple neural network to do exclusive or.
import numpy as np
epochs = 60000 # Number of iterations
inputLayerSize, hiddenLayerSize, outputLayerSize = 2, 3, 1
X = np.array([[0,0], [0,1], [1,0], [1,1]])
Y = np.array([ [0], [1], [1], [0]])
def sigmoid (x): return 1/(1 + np.exp(-x)) # activation function
def sigmoid_(x): return x * (1 - x) # derivative of sigmoid
# weights on layer inputs
Wh = np.random.uniform(size=(inputLayerSize, hiddenLayerSize))
Wz = np.random.uniform(size=(hiddenLayerSize,outputLayerSize))
for i in range(epochs):
H = sigmoid(np.dot(X, Wh)) # hidden layer results
Z = sigmoid(np.dot(H, Wz)) # output layer results
E = Y - Z # how much we missed (error)
dZ = E * sigmoid_(Z) # delta Z
dH = dZ.dot(Wz.T) * sigmoid_(H) # delta H
Wz += H.T.dot(dZ) # update output layer weights
Wh += X.T.dot(dH) # update hidden layer weights
print(Z) # what have we learnt?
Walk-through
We use numpy, because we’ll be using matrices and vectors. There are no ‘neuron’ objects in the code, rather, the neural network is encoded in the weight matrices.
Our hyperparameters (fancy word in AI for parameters) are epochs (lots) and layer sizes. Since the input data comprises 2 operands for the XOR operation, the input layer devotes 1 neuron per operand. The result of the XOR operation is one truth value, so we have one output node. The hidden layer can have any number of nodes, 3 seems sufficient, but you should experiment with this.
The successive values of our training data add another dimension at each layer (or matrix) so the input matrix X is 4 * 2, representing all possible combinations of truth value pairs. The training data Y is 4 values corresponding to the result of XOR on those combinations.
An activation function corresponds to the biological phenomenon of a neuron ‘firing’, i.e. triggering a nerve signal when the neuron’s inputs combine in some appropriate way. It has to be chosen so as to cause reasonably proportionate outputs within a small range, for small changes of input. We’ll use the very popular sigmoid function, but note that there are others. We also need the sigmoid derivative for backpropagation.
Initialise the weights. Setting them all to the same value, e.g. zero, would be a poor choice because the weights are very likely to end up different from each other and we should help that along with this ‘symmetry-breaking’.
Now for the learning process:
We’ll make an initial guess using the random initial weights, propagate it through the hidden layer as the dot product of those weights and the input vector of truth-value pairs. Recall that a matrix – vector multiplication proceeds along each row, multiplying each element by corresponding elements down through the vector, and then summing them. This matrix goes into the sigmoid function to produce H. So H = sigmoid(X * Wh)
Same for the Z (output) layer, Z = sigmoid(H * Wz)
Now we compare the guess with the training date, i.e. Y – Z, giving E.
Finally, backpropagation. This comprises computing changes (deltas) which are multiplied (specifically, via the dot product) with the values at the hidden and input layers, to provide increments for the appropriate weights. If any neuron values are zero or very close, then they aren’t contributing much and might as well not be there. The sigmoid derivative (greatest at zero) used in the backprop will help to push values away from zero. The sigmoid activation function shapes the output at each layer.
E is the final error Y – Z.
dZ is a change factor dependent on this error magnified by the slope of Z; if its steep we need to change more, if close to zero, not much. The slope is sigmoid_(Z).
dH is dZ backpropagated through the weights Wz, amplified by the slope of H.
Finally, Wz and Wn are adjusted applying those deltas to the inputs at their layers, because the larger they are, the more the weights need to be tweaked to absorb the effect of the next forward prop. The input values are the value of the gradient that is being descended; we’re moving the weights down towards the minimum value of the cost function.
If you want to understand the code at more than a hand-wavey level, study the backpropagation algorithm mathematical derivation such as this one or this one so you appreciate the delta rule, which is used to update the weights. Essentially, its the partial derivative chain rule doing the backprop grunt work. Even if you don’t fully grok the math derivation at least check out the 4 equations of backprop, e.g. as listed here (click on the Backpropagation button near the bottom) and here because those are where the code ultimately derives from.
The X matrix holds the training data, excluding the required output values. Visualise it being rotated 90 degrees clockwise and fed one pair at a time into the input layer (X00 and X01, etc). They go across each column of the weight matrix Wh for the hidden layer to produce the first row of the result H, then the next etc, until all rows of the input data have gone in. H is then fed into the activation function, ready for the corresponding step from the hidden to the output layer Z.
If you run this program, you should get something like:
[[ 0.01288433]
[ 0.99223799]
[ 0.99223787]
[ 0.00199393]]
You won’t get the exact same results, but the first and last numbers should be close to zero, while the 2 inner numbers should be close to 1. You might have preferred exact 0s and 1s, but our learning process is analogue rather than digital; you could always just insert a final test to convert ‘nearly 0’ to 0, and ‘nearly 1’ to 1!
Here’s an improved version, it has no (or linear) activation on the output layer and gets more accurate results faster.
# XOR.py-A very simple neural network to do exclusive or.
# sigmoid activation for hidden layer, no (or linear) activation for output
import numpy as np
epochs = 20000 # Number of iterations
inputLayerSize, hiddenLayerSize, outputLayerSize = 2, 3, 1
L = .1 # learning rate
X = np.array([[0,0], [0,1], [1,0], [1,1]])
Y = np.array([ [0], [1], [1], [0]])
def sigmoid (x): return 1/(1 + np.exp(-x)) # activation function
def sigmoid_(x): return x * (1 - x) # derivative of sigmoid
# weights on layer inputs
Wh = np.random.uniform(size=(inputLayerSize, hiddenLayerSize))
Wz = np.random.uniform(size=(hiddenLayerSize,outputLayerSize))
for i in range(epochs):
H = sigmoid(np.dot(X, Wh)) # hidden layer results
Z = np.dot(H,Wz) # output layer, no activation
E = Y - Z # how much we missed (error)
dZ = E * L # delta Z
Wz += H.T.dot(dZ) # update output layer weights
dH = dZ.dot(Wz.T) * sigmoid_(H) # delta H
Wh += X.T.dot(dH) # update hidden layer weights
print(Z) # what have we learnt?
Output should look something like this:
[[ 6.66133815e-15]
[ 1.00000000e+00]
[ 1.00000000e+00]
[ 8.88178420e-15]]
Part 2 will build on this example, introducing biases, graphical visualisation, learning a math function (sine), etc…
This Quick Introduction to Python 3 aims to teach you just enough Python, so that you can get started in computer programming, and try out some of the example codes on this site!
First, you’ll want to install Python 3. If you have Python installed, you can use any text editor to start with (but do not use a word processor). You might find it useful to start up the Python interpreter and type in the examples as we go.
The Python Interpreter
Experienced programmers in any other language can pick up Python very quickly, and beginners find the clean syntax and indentation structure easy to learn. – Python.org
Do you have the Python interpreter already installed on your computer? To find out, open a command line and type “python” (without the quotes). Hopefully you’ll get something like this:
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Python 2 is almost always readily available on Linux; probably Macs too; Windows I don’t know. If your computer doesn’t have it then go to https://www.python.org/ and get the latest version (3.4.3 at this time). Follow the instructions to install it. You’ll also want to do this if your installed version is less than 3.
The traditional first program in Python (and other programming languages) is “Hello world!”:
print "Hello world!"
Type this after the ‘>>>’ prompt in your interpreter. If it’s version 2 it’ll obligingly print ‘Hello World!’, but version 3 will complain:
Version 3 changed the print statement to being a function call (more on that later) which requires parentheses around the thing to be printed (as well as the quotes). In your Python 3 interpreter (invoked as python3 if necessary) type print (“Hello World!”), and hopefully it will! You can also get the same result by just typing in “Hello World!” (with the quotes), without the print function call. Try typing in some arithmetic, like ‘2*3′. No need to say print! However outside the interpreter you’ll need the print function.
Statements & Expressions
The line of text in our first program is called a statement. It’s like a sentence in English (sort of). The statement usually appears on a line of its own, and comprises ‘smaller’ bits like identifiers (names for things such as data), keywords (reserved words that tell Python what to do), operators (like arithmetic symbols) etc. You can think of it as an instruction for the computer to do something, like print some text. We’ll meet various kinds of statement, like assignment and conditional statements. An expression is a part of a statement where a little bit of computation is required, e.g. x = 2 * 3
Assignment Statements
A program is a set of instructions (‘algorithm‘) and some data that tell a computer how to perform a task, for example, to convert a temperature in Centigrade, to Fahrenheit. This data could take many forms, but for now we’ll assume it’s a set of numbers. And we’ll need some working storage (‘memory‘) where we can save intermediate results. When we put these results in the memory, we’ll give them names and let the computer take care of figuring out where they are in the memory. You can store data in memory using assignment statements.
The first text, before the ‘=’, is the name or identifier you have chosen for your item of data; it’s often called a variable because (normally) your program may change it later. An identifier is a name used to identify a variable, function, class, module or other object. It starts with an uppercase or lowercase letter, or an underscore (_) followed by zero or more letters, underscores and digits (0 to 9). The ‘=’ assigns a value (e.g. 100) to the variable. Data values have particular types, e.g integers, floats, strings, boolean, complex etc.
Arithmetic
Calculations are simple with Python, and expression syntax is straightforward: the operators +, -, * and / work as expected; parentheses () can be used for grouping. – Python.org.
Python can do arithmetic such as add, subtract, multiply, and divide, using these operators: + – * / We can write arithmetic expressions as you’d expect to see them in mathematics, with some small exceptions, e.g. y = m * x + c You can’t write variables next to each other to signify multiplication; all operations must be explicit. Operands must be one of:
Integer: whole numbers, zero, positive, or negative, e.g. 1, 2, -3, 0
Floating Point: numbers with decimal point, e.g. 3.14, -0.8
If x is 2, and y is 3, then:
Operator
Description
Example
+
Add
Adds the values on either side of the operator.
x + y -> 5
–
Subtract
Subtracts right side operand from left side operand.
x – y -> -1
*
Multiply
Multiplies values on either side of the operator
x * y -> 6
/
Divide
Divides left side operand by right side operand
x / y -> 0.666…
%
Modulus
Divides left side operand by right side operand and returns remainder
x % y -> 0
**
Exponent
Raise left operand to power of right operand
x ** y -> 8
//
Floor Division
Division where the result is rounded away from zero (towards negative infinity)
7//2 = 3 and 7.0//2.0 = 3.5
A Programming Example
Let’s have an example. Let’s convert a temperature given in Centigrade degrees,°C, to Fahrenheit,°F. From Physics, we know that there’s a simple formula: F = C * 9 / 5 +32. That is, multiply the value in Centigrade by 9, divide that by 5, and then add 32. So what is 0°C in F? It’s 32. The freezing point of water is 0° in C, but 32° in F. How about 100°C? The order of operations in C * 9 / 5 isn’t important, so let’s divide 100 by 5 first. That’s 20. Now multiply by 9; that’s 180. Now add 32. That’s 212°, the boiling point of water in Fahrenheit.
Note that in the following, I’m a bit carefree about integers and floats; I use integers for simplicity, but in serious applications you might do better to use floats if they better represent the real-world values!
C = 50
F = C * 9 / 5 + 32
print(F)
Our program (let’s call it C2F.py) is a sequence of instructions, executed one after the other, starting with the first one, C = 50:
Set the variable C to the integer value of 50 (If you prefer, you can write ‘.0’ after each number.)
Multiply C by 9, divide the result by 5, and add 32 to that
Print the answer
String Theory
In our “Hello, World!” example, we wrote it one time with “double quotes”, and one time with ‘single quotes’: ‘Hello, World!’. Text, when enclosed in quotes (either kind) is called a string. Strings are very useful not only for greetings, but also for programs to tell you the results of computations, or to tell you what input is needed next, or for storing information like people’s names, or for labelling graphs, etc. Note that if you need a string to contain quotes, you must either use the other style of quote (single or double) to enclose it, or ‘escape’ the internal quote with a backslash: “This is Freddie’s cat” or ‘This is Freddie\’s cat’.
You can do a limited amount of ‘arithmetic’ on strings – you can add or multiply them! So if a contains ‘a’, and b contains ‘b’, then a + b is ‘ab’ (this is called concatenation), and a * 3 is ‘aaa’. You can’t subtract or divide them however.
Input & Output
Outputting a result can be done with print() as we’ve just seen. We could make it a little more helpful if we write it like this: print(“The temperature is “, F, “F”).
This is all well and good, whenever we want to convert 50°C to F. But it’d be much more useful if we could somehow tell it any value of C! We can do this just by replacing the first line, C = 50, with: C = input(“Enter the Centigrade temperature:”) It prints out “Enter the Centigrade temperature:” (without the quotes) and waits for the user to type in something.
But if we try to do arithmetic on C, Python will complain about ‘unsupported operand type(s)’. This is because input() delivers the user’s input as a string of characters – it doesn’t know that we want it as a number. So we feed that string into int() (for integer) or float() (for decimal-pointed numbers). When it has that number it does the arithmetic, and prints out the result.
Branching Conditions
In Python, like in C, any non-zero integer value is true; zero is false. The condition may also be a string or list value, in fact any sequence; anything with a non-zero length is true, empty sequences are false. The test … is a simple comparison. The standard comparison operators are written the same as in C:<(less than),>(greater than),==(equal to),<=(less than or equal to),>=(greater than or equal to) and!=(not equal to). – Python.org
Conditional statements are features of a programming language which perform different computations or actions depending on whether a programmer-specified boolean condition evaluates to true or false. If the condition is true, one path of code is taken, but if not, another path is taken. For example:
x = 3
if x > 0:
print("x is positive")
else:
print("x is zero or negative")
Let’s meet another data type:
Boolean: True or False. For example, 4 > 3 is True, 2 > 3 is False, 2 == 2 is True, 3 == 2 is False.
Boolean has only 2 values: True or False. Usually the result of a comparison, e.g. x > 3 is True if x is 4, but False if x is 2. It can also result from testing for equality, e.g. x == 3 is True if x is 3, False otherwise. Note the double equals! You will ( I repeat, will) at some point in your Python programming career, write x = 3 when you want to know if x is 3!
Here are the comparison operators that you can use in boolean expressions:
== equality
!= not equal
> greater than
>= greater than or equal
< less than
<= less than or equal
If Statements
Python knows the usual control flow statements that other languages speak — if, for, while and range — with some of its own twists, of course. – Python.org
What if we want to convert temperatures in the other direction – F to C? Well the formula is C = (F – 32) * 5 / 9. Why don’t you re-write the previous program and call it F2C.py Whenever we want to convert Fahrenheit to Centigrade, we’ll use this one. So whenever you have a temperature conversion to do, you’ll reason something like this:
If I want to convert C to F then
run C2F.py
otherwise (I want to convert F to C)
run F2C.py
Now we have 2 programs that look very similar and have the same physical constants in them (9, 5, and 32). We could simplify things a bit, if we could combine them into one! But how will the computer know which conversion we want? Sounds like we need another input()!
which = input("Is your temperature C or F?").lower()
value = int(input("What is its value? "))
if which == 'c':
result = value * 9 / 5 + 32
elif which == 'f':
result = (value - 32) * 5 / 9
else:
result = 'Please enter C or F'
print(result)
Indentation is Python’s way of grouping statements. At the interactive prompt, you have to type a tab or space(s) for each indented line. In practice you will prepare more complicated input for Python with a text editor; all decent text editors have an auto-indent facility. When a compound statement is entered interactively, it must be followed by a blank line to indicate completion (since the parser cannot guess when you have typed the last line). Note that each line within a basic block must be indented by the same amount. – Python.org
Let’s assume that the user types a ‘C’ or an ‘F’; .lower() converts to lowercase (so it doesn’t matter if the user types ‘C’ or ‘c’); this goes into the variable ‘which’
‘if‘ test the value of the following Boolean expression, which == ‘c’. Note the ‘:’ at the end of the line. If the expression is True then the following block is run:
–> compute the Fahrenheit value, put it in result variable
else if ‘which’ contains ‘f’:
–> compute the Centigrade value, put it in result variable
otherwise:
–> store ‘Please enter C or F’ into result
print the result
There can be zero or more elif parts, and the else part is optional. The keyword ‘elif‘ is short for ‘else if’, and is useful to avoid excessive indentation. An if … elif … elif … sequence is a substitute for theswitchorcasestatements found in other languages. – Python.org
Looping
A loop is a sequence of statements which is specified once but which may be carried out several times in succession. The code “inside” the loop (the body of the loop) is obeyed a specified number of times, or once for each of a collection of items, or until some condition is met, or indefinitely.
While Loops
Suppose that we have several temperatures that we want to convert. Well, we could run the appropriate program (C2F.py or F2C.py) several times. But it would be nicer if the program could ‘start over’ by itself, till I indicate I’m done:
done = False
while not done:
C = int(input("Temperature in C:"))
F = C * 9 / 5 + 32
print(F)
done = input("Another?") != 'y'
done is a boolean variable, initialised to ‘False’
while means “repeat the following block as long as the test (‘not done’) is True:
–> get the user’s value of C
–> compute F
–> reset the boolean done: if the user answers with ‘y’ then it’s True, otherwise False
For Loops
The “for” statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence. – Python.org
while isn’t the only looping construct in Python; perhaps better-known is the for-loop, which repeats the enclosed block a fixed number of times:
for i in range(10):
print(i)
The built-in function range() iterates over a sequence of numbers, generating arithmetic progressions. In this example, it generates integers from 0 to 9.
Compound Data
Sometimes you need several items of data together, representing multiple measurements or different facets of the world; such as arrays, records, files, data bases etc.
Lists
Lists (known as arrays in other languages) are one of the compound data types that Python understands. Lists can be indexed, sliced and manipulated with other built-in functions. – Python.org
Alternatively, instead of asking the user to supply all the values, we could put them straight into the program. Maybe you’re just writing a quick little program to do some number crunching, so you don’t need the fancy prompts! Well, we can put the data in a list (‘array’ in other languages, and math).
temps = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
for temp in temps:
print(temp, "C is ", temp * 9 / 5 + 32, "F")
Lists might contain items of different types, but usually the items all have the same type. Also, lists can contain lists (aka, 2D arrays)!
Files
Lists are very handy, but you might prefer sometimes to process data that’s in a file rather than right there in your program. We can do this very easily, with very little change to our program:
temps = open('Temperatures.C')
for temp in temps:
_ = int(temp)
print(_, "C is ", _ * 9 / 5 + 32, "F")
Instead of the list, we now have open(‘Temperatures.C’) (or whatever name your file has if not Temperatures.C). What is read from the file, each time the for loop iterates, is a string, hence the _ = int(temp). The _ is just some anonymous variable that we needn’t bother giving a name to – but you can, if you prefer (e.g. because it helps document the code).
Looping Around Conditionals
A very common pattern in programming is to loop over some data while testing it for some condition so as to process it accordingly. The simplest example is probably where some abnormal value of the data is used to signal the end of the data, e.g. if we’re calculating average height, zero or negative indicates end of data:
sum = 0.0
num = 0
done = False
while not done:
height = float(input("Enter a height or 0 to finish: "))
if height <= 0:
done = True
else:
sum += height
num += 1
print ("Average height is ", sum / num)
There is an error in this program. What is it, and how would you fix it?
Comments
Another important thing to know about is ‘comments’. You can put text in your program that isn’t Python code, such as explanations about how the code works. Anything between triple quotes (single or double, so long as they’re the same) will be ignored. Anything after ‘#’ on the same line will be ignored.
''' Test the first N numbers for primality.
Count up to N, dividing by primes known so far.
Add this number to the list of primes if none divide into it.
'''
N = 1000 # N is how many numbers to test
primes = [] # List of primes so far
for n in range(2,N+1): # For each number from 2 to N:
for p in primes: # For each prime so far:
if n % p == 0: break # If it divides into it, it's not prime
else: # No primes divided into it so
primes.append(n) # Add it to the list
print(primes)
When range() has 2 arguments, the first one is the starting number, and the second one is the next number after the end of the range! So we have to add 1 if we want the range to include the Nth number. The ‘%’ operator is modulus, i.e. the remainder left by dividing the first operand by the second. It’s very useful to tell if one number is evenly divisible by another, because if it is, the remainder is 0.
Error Handling
What happens when things go wrong? They will! The user might enter a value that isn’t right, such as a value out of range, or ‘K’ when we wanted ‘C’ or ‘F’. In simple cases like that you can just have an ‘else’ clause to catch the values that are ‘none of the above’, and print out an error message. For more difficult cases, e.g. a number has invalid digits, you can use Python’s exception handling. It looks like this:
try:
number = int (string)
except:
print(string, "isn't a valid number")
So Python will try to convert string to an integer, but if it can’t, it will perform the except block, otherwise execution continues after the except block.
Here’s a better version of our temperature converter:
''' Temperature Convertor.
to illustrate minimal Python
'''
done = False
while not done: # Repeat until the done flag gets set
which = 'x' # Give which a value that isn't c or f
while which not in 'cf': # repeat until user gives good value:
which = input("Is your temperature C or F? ").lower() # lowercase it
try: # we want a floating point number
value = float(input("What is its value? "))
except: # but didn't get one :()
print("Not a number")
continue # continue loop from beginning
if which == 'c': # Centigrade -> Fahrenheit
result = str(value * 9 / 5 + 32) + 'F'
elif which == 'f': # Fahrenheit -> Centigrade
result = str((value - 32) * 5 / 9) + 'C'
else:
pass # Cannot possibly get here !
print(result)
done = input("Another? ").lower() != 'y' # != is 'not equal'
print("Done!")
Functions
The core of extensible programming is defining functions. Python allows mandatory and optional arguments, keyword arguments, and even arbitrary argument lists. – Python.org
A function is a piece of code ‘wrapped up’ in a way that enables us to use it like we used the range() function – it gets a name and some arguments that supply its input values. So if we wanted, for example, to make our temperature conversions re-usable, we could declare these functions:
“def” declares that a function definition is coming. First, the name, then in parentheses, the value or values. The line ends with a colon indicating that an indented block of code will follow. There is then an optional comment, called a docstring, which may be used by tools to automatically document your code. When the function is called, the conversion is calculated, and the result appears in the place where the function was called.
Functions are an extremely important addition to your programming repertoire! They enable:
Unit testing, like the above prints of known correct values;
Modularisation, dividing your code into easier to understand pieces;
Object-oriented programming which further improves code modularity;
Reusability, either in the same program, or in others by use of modules (files which can be imported);
Recursion, where a problem can be solved by repeatedly breaking it down into smaller instances until a trivial base case is reached.
This article introduces the idea of importing Python modules that manage many common and/or special tasks that you would otherwise have to write programming code for. IDLE is featured in this article because of some of its handy features, but you can follow the examples in other ways as well.
The material in this article directly supplements the official Python Tutorial, and pretty much assumes you have at least skimmed over it or gotten the same information elsewhere. This article is intended to help you “get busy coding” right away and show you a few essential tricks.
WHAT A MODULE IS:
The short answer is that a module is a text file containing one or more Python statements and/or definitions (of functions and classes). Most modules also contain comments.
A statement is pretty much one or more lines of Python code that give Python orders. (The classic example of a first statement for programming students to write is to tell Python to print “Hello world”, but statements can be quite a bit more sophisticated.)
When you import a module, statements not included within the definitions of functions and classes are executed. These statements may even involve importing other modules in order to work.
IMPORTING BASICS:
Importing a Python module is usually more simple than you might think. For instance, if you want to use the module named “time” in your program, you merely enter the line:
import time
If you wanted to import everything the time module has to export, but not import the time module itself, you could simply type:
from time import *
If you only wanted to import isleap() from the calendar module, all you would need to do is to type: from calendar import isleap
See if you can follow what’s happening in the following code:
One difference between the two approaches is that by importing * from the time module, you are importing each of the resources of the time module for individual use, so you don’t have to qualify them by tacking “time.” onto the front. Sometimes this is a good idea, but you want to make sure not to have two objects “by the same name in the same place”, in a manner of speaking. Spend some time experimenting with different modules, and see if you can find out for yourself what that means.
SEVERAL WAYS TO LEARN YOUR WAY AROUND MODULES:
Python Documentation is usually bundled with Python when it is installed on your computer. It may also be found online at http://python.org/doc/ for the current release of Python as well as archives going back several years. Here you can find the official Python Tutorial, Module Index, Library Reference, and more.
You may also find handy utilities like pydoc (which may be labeled “Module Docs” or similar) either included in your distribution or available through other sources. Using such a utility, you can search for modules on your local machine just like you would use a search engine such as google.com on the web.
Opening Modules in IDLE or your preferred text editor can expose many details not described elsewhere. Remember, modules are saved as text files, so you can read them without the use of special tools. Open them in the usual way with your favorite text editor/viewer, or select File>Open module from IDLE (the *Python Shell*). Just remember to open the files ending in extensions other than .pyc, because .pyc files are not plain text files, but files compiled for execution.
And fiddling with example code is definitely one of the best ways to learn what you can do with specific modules and the tools they offer. You should do as much code tinkering as you can in order to keep learning. This fiddling is the heart and soul of Useless Python!
Once you have imported a module into your program (including an interactive interpreter session, such as IDLE), you can perform dir() on it to list the names of the module’s contents. Just remember this will not work until after you have imported the module.
Many modules contain enough items that dir() will unattractively dump a listing that will be very little fun to read. In the following example, also note how dir() is correctly used to display the contents of the calendar module at the IDLE prompt:
Not too pretty, eh? Even worse, it really isn’t easy to read and comprehend in this form. Fortunately, it is extremely easy to print this information out in a format that is both appealing and easy to follow with a simple “for” loop: >>> for thingy in dir(calendar): .......print thingy
Among its many uses, dir() can be a great quick-look-up tool to refresh your memory when you find yourself on the hunt for just the right module or function.
But if you think that’s impressive, help() should really blow you away! You don’t have to use any fancy “for” loops with help(), because help() provides a wealth of descriptive information about the module and its contents. Try help() for plenty of information in a flash.
>>> import socket >>> help(socket)
This is an example of help() usage, but it provides so much information that I encourage you to experiment with it in your own favorite setting to see the output.
A simple demonstration of using Java Swing from the Jython interactive interpreter.
The following is an example of using the Jython interactive interpreter from the Windows 2000 command prompt. On this page, we demonstrate several Jython basics, including:
use of the jython interpreter from the MS Windows 2000 command prompt
collection of user input with javax.swing.JOptionPane.showInputDialog()
conversion of strings to integers, and integers to strings, plus simple addition
display of output with javax.swing.JOptionPane.showMessageDialog()
Please note that your web browser will probably wrap some longer lines of code.
In our example, Jython is installed in the \bin\ folder of a fairly typical Java installation. My comments are interjected into the session, indicated by the traditional #.
C:\j2sdk1.4.0\bin>jython
Jython 2.1 on java1.4.0 (JIT: null)
Type "copyright", "credits" or "license" for more information.
>>> import javax.swing as sshwing
>>> firstNum = sshwing.JOptionPane.showInputDialog("Enter an integer: ")
>>> secondNum = sshwing.JOptionPane.showInputDialog("Enter an integer: ")
Each of the two previous lines of code caused a separate swing dialog box asking the user for an integer.
The user’s input is stored as a string, not dynamically determined to be an integer. This is easily demonstrated as follows:
Another Python built-in handily converts the sum on-the-fly to a string:
>>> sum12 = str(num1 + num2)
>>> sum12
'3'
Output of the sum in a swing message box is relatively painless. But in Jython, you use “None” in place of the more Java-esque “Null” in the following examples:
>>> sshwing.JOptionPane.showMessageDialog(None, "The sum of your integers is " + sum12)
The same output may be tweaked to show the box with a label “Sum” and with a more generic look:
>>> sshwing.JOptionPane.showMessageDialog(None, "The sum of your integers is " + sum12, "Sum", sshwing.JOptionPane.PLAIN_MESSAGE)
A little tweak adds a “.” to the end of the Sum dialog statement.
>>> sshwing.JOptionPane.showMessageDialog(None,"The sum is " + sum12 + ".", "Sum", sshwing.JOptionPane.PLAIN_MESSAGE)
Easy as Py! And, of course, using the interactive prompt is only one option. Save a .py source file and run it without a separate compile step.
Writing computer programs to distribute is a process, but it can be a simple one. This article follows our hero Joe Useless on his journey from wanting a simple problem solved to giving his friends the answer in a program they can use over and over. This article is a work in progress, and helpful suggestions are welcome.
Step 1: Have a problem to solve. (You can also think of this step as “Think of something you want to do.”)
Joe Useless has taken a job working as a clerk at ACME, and enjoys his job for the most part. But clerks in his department have to do a lot of something that Joe hates. They have to compare obscure lines of text, and his supervisor insists that there is no room for error.
Fortunately for Joe, ACME takes the enlightened approach of allowing him to run Python on his PC. “Whatever gets the job done right,” insists his supervisor.
Step 2: Find a way to do it at all.
Joe has used Python before and feels certain he remembers a simple way to do comparisons, so after spending a few minutes with the Library Reference, he turns on IDLE and tries out the cmp() built-in function:
It looks like this might do the trick for some of their more common and tedious comparisons. Joe gets into the habit of keeping IDLE running in the background to double-check some of his work for a while just to make sure.
Step 3: Tweak it until you have code that consistently does it the way you like.
This little trick works well enough that Joe finds he has largely automated the most annoying part of his job, to the envy of his co-workers. But Joe isn’t a Computer Scientist, and he finds that the “1/0/-1” values returned by cmp() leave him feeling nervous that he might make accidentally mistake “1” for “-1” and mess up the job. He doesn’t want to have to look up the meaning of the values cmp() returns, so he decides to write a function to dress-up the output.
>>> def compare(firstArg, secondArg):
if cmp(firstArg, secondArg) == -1:
print str(firstArg) + " is less than " + str(secondArg)
elif cmp(firstArg, secondArg) == 0:
print str(firstArg) + " is equal to " + str(secondArg)
else:
print str(firstArg) + " is greater than " + str(secondArg)
This is much better. Joe’s function takes the output from cmp() and displays the result in plain English (by clerk standards, anyway), like so:
>>> compare('Harrelson, Adrienne', 'Harrelson, Adrianne')
Harrelson, Adrienne is greater than Harrelson, Adrianne
>>>
Joe decided to use terms like “greater than” and “less than” in the program’s output, because this seemed like a familiar way of thinking about it, especially since the same function can be used to compare the values of numbers.
Step 4: Package it to be used repeatedly.
Joe’s co-workers are beginning to take notice now, especially since the management is becoming less tolerant of mistakes. Joe decides to make the function into a module that other workers can run on their own workstations. (By this point, Joe is also becoming something of a Python zealot and wants to see more people using it.) He adds a few lines of code to the text file where he keeps his comparison function, turning it into a program the clerks can start from the command line.
def compare(firstArg, secondArg):
if cmp(firstArg, secondArg) == -1:
print str(firstArg) + " is less than " + str(secondArg)
elif cmp(firstArg, secondArg) == 0:
print str(firstArg) + " is equal to " + str(secondArg)
else:
print str(firstArg) + " is greater than " + str(secondArg)
if __name__ == '__main__':
import sys
compare(sys.argv[1], sys.argv[2])
Joe was surprised to discover how little effort he had to put into making his handy little function into a full-fledged program. In Programming Python by Mark Lutz, he found out that if a Python script is run as a program, a built-in variable called “__name__” is assigned a special string called “__main__”, and that you can check for this with a simple “if” statement like the one he added. (He even thinks he half-way understands what this means!).
Now if his file is started from the command line as a program instead of imported into an interactive interpreter such as IDLE, the clerk who starts the program can enter the two strings needing to be compared after the program name. (This is sometimes referred to as “calling a program with arguments”. The first of the two strings entered is the first argument, which the program sees as sys.argv[1], and the second string is the second argument, or sys.argv[2].)
The two command-line argument strings are passed to the compare function in the last line of the program. So compare() starts up with sys.argv[1] as firstArg and sys.argv[2] as secondArg. It then calls cmp() and passes firstArg and secondArg to it, then prints a statement to the screen about how the two strings compared.
Step 5: Make it bullet-proof.
Joe’s fellow clerks keep making minor mistakes when running the program, and the department uses a lot of temporary workers. Joe doesn’t want to spend too much time showing people how to use the program, so he decides to have the program itself remind the user of the right way to use it when the most common mistakes are made.
def compare(firstArg, secondArg):
if cmp(firstArg, secondArg) == -1:
print str(firstArg) + " is less than " + str(secondArg)
elif cmp(firstArg, secondArg) == 0:
print str(firstArg) + " is equal to " + str(secondArg)
else:
print str(firstArg) + " is greater than " + str(secondArg)
if __name__ == '__main__':
import sys
if len(sys.argv) != 3:
print '''********************\n
Usage suggestion:\n
python comparison.py argument1 argument2\n
\n
For example:\n
C:\Python22\python comparison.py "Jolie, Angelina" "Useless, Joe"\n
********************'''
else:
compare(sys.argv[1], sys.argv[2])
Now, if a user gives the program too many or too few arguments, the program suggests an example of correct usage instead of producing an error message. For example, if the user enters only one name to compare:
Joe hopes that this will be enough of a reminder for people that he will only be have to spend a few minutes with them at first to train them in how to use the program meaningfully.
Step 6: If you haven’t already done it, comment your code.
Useless Joe’s supervisor is happy, as is the supervisor’s manager. The clerks are happy. And Joe wants this trend to continue, so he takes a little time to sit down and add comments to the source code of the program he has written. Even though this is a simple program, it would not make a lot of sense to someone who has never seen source code. If someone needs to change the code later (maybe even himself), he wants the code to look good and make sense without anyone having to waste much time figuring it out. Joe decides to add some comments describing what the different parts of the program are instead of describing every little technical detail. He also comments the date the program was last edited, so if the program is updated at some point, it will be easy to tell which version is in use on any given clerk’s PC.
#!/usr/bin/python
#
# comparison.py by Joe Useless for ACME clerks
# This is the function that does all the work.
# Arguments sent to the program are compared with the
# Python built-in function cmp()
def compare(firstArg, secondArg):
# This if/elif/else block reformats cmp() output
# so clerks can make out the meaning with fewer mistakes
if cmp(firstArg, secondArg) == -1:
print str(firstArg) + " is less than " + str(secondArg)
elif cmp(firstArg, secondArg) == 0:
print str(firstArg) + " is equal to " + str(secondArg)
else:
print str(firstArg) + " is greater than " + str(secondArg)
# This is the main method, which makes it possible to run the
# comparison as a top-level program instead of just by calling
# the compare function from within another program, such as
# a python interactive interpreter.
if __name__ == '__main__':
import sys
# If a clerk calls the program with the wrong number of
# arguments, print an example of correct usage.
if len(sys.argv) != 3:
print '''********************\n
Usage suggestion:\n
python comparison.py argument1 argument2\n
\n
For example:\n
C:\Python22\python comparison.py "Jolie, Angelina" "Useless, Joe"\n
********************'''
# If the clerk calls the program correctly, perform the
# compare function with the arguments provided by the clerk.
else:
compare(sys.argv[1], sys.argv[2])
Now Joe Useless feels satisfied with the program. He feels the comments are okay for a program this small, and by putting his program in the hands of other clerks, he is beginning to get an idea of how the program can be improved some more.