Thursday, 6 August 2009

Understanding Python Error Messages

Understanding runtime errors and (uncaught) exceptions in any programming language can be a pain, especially if your code is complex or the error message is obscure. The usual way to deal with this situation is either to use a full blown debugger to step through the code, or to add as many print statements as necessary to uncover the source of the error. However, Python provides a third solution which is pretty neat -- use a disassembler. The dis module takes a Python bytecode object (as generated by the builtin compile function or the py_compile module) and prints out a listing of the bytecode instructions "in" that object. However, dis also has another use -- calling the disassembler with no arguments prints out the bytecode instructions generated during the last traceback.

For example, if you import dis in the interactive interpreter and generate a traceback, like this:

>>> 'foobar' * 2.5
Traceback (most recent call last):
 File "", line 1, in 
TypeError: can't multiply sequence by non-int of type 'float'
>>>

You can then run the dis.dis() method to examine the error:

>>> dis.dis()
 1           0 LOAD_CONST               0 ('foobar')
             3 LOAD_CONST               1 (2.5)
   -->       6 BINARY_MULTIPLY
             7 PRINT_EXPR
             8 LOAD_CONST               2 (None)
            11 RETURN_VALUE
>>>

The arrow on the left (-->) points to the bytecode instruction which caused the TypeError. The number 0 on the left before load_const shows the line number of the source which generated the load_const bytecode instruction. On the right hand side in brackets are the constants loaded into the interpreter.

Sunday, 12 July 2009

Shift LIfe

Sam Moore, Eugene Ch'ng, Dew Harrison, Mat Murray and I have been working on a pervasive interface for an artificial life simulation. At the recent Shift-Time festival in Shrewsbury we exhibited an artificial life simulation of an fictional ecosystem, projected onto a sand pit. People could change the behaviour of the creatures in the ecosystem by changing the environmental conditions of the system. They could make the sun shine more or less by playing with a lamp, increase the humidity or change the pH by pouring in water, vinegar or soda mix from watering cans or cause an earthquake by hitting the side of the sand pit with a toy hammer. We had really good feedback from the people who came to see us. One family came back on the second day because their three children were talking about it "all night". Typical comments from kids were "I think it's cool" and one kid left saying "well, you've got to be impressed with that", which made us laugh. More info and an interview with Dew can be found here: [Event listing] http://www.shift-time.org.uk/events/shift-life.shtml [Interview] http://www.shift-time.org.uk/video/video-shift-life.shtml

Saturday, 13 September 2008

Leeds University at PyConUK 2008

Tony Jenkins and Nick Efford from Leeds University gave an excellent talk at PyConUK on their experiences of teaching Python as an introductory programming language which seems to be very similar to our efforts at Coventry. Tony and Nick managed to raise pass rates, inspire some fantastic coursework, have fun and generally kick ass. Great news for Python and even better news for a future generation of students. You can see some more of their work in ITALICS.

Saturday, 17 March 2007

Programming skillz and games degrees

Bob found a really interesting article on What Game Companies Want From Graduates. Interesting, for a number of reasons, but the one sentence that stands out for anyone teaching programming is this:

Currently for EA, the majority of "open positions for new graduates are software engineering and technical artist roles," though "both require substantial programming abilities."


Programming is, EA say, important both for programmers and non-programmers alike, no doubt for a bunch of reasons ranging from needing to communicate effectively with the whole team to needing to script and extend modelling and animation tools.

It's an important point because applications to core CS and Soft Eng degrees are falling world-wide, with interest in degrees such as Creative Computing and Games Technology rising. With fewer students opting to take A Levels in Maths and the physical sciences the need to develop core technical skills needs to be clearly seen as fun, important and leading to jobs in a way that was never needed by those of us who grew up hacking the Amstrad6128.

Thursday, 28 December 2006

How to learn a new (programming) language

Pretty much every programmer that I've ever met learns new languages by writing a number of small programs in the new language, that should show up the major features of the language and enable the transference of skills from known languages to new ones. Here's a list of my favourite small problems:

The basics: choice, iteration, recursion

Factorial function
Factorials are easy, but the trick here is to deal with all the various boundary conditions, preferably using exceptions.

Fibonacci sequence
Generating the next Fibonnaci number has a simple recursive solution and a slightly more complex iterative solution which can show up features such as simultaneous assignment.

The first n primes
Print the first n primes using the
Sieve of Eratosthenes. This is an interesting one -- it has nice solutions both iteratively and recursively. Also, you can do neet things with exceptions to give a solution.

Files and other I/O


Caesar cipher
Read in an ASCII sentence and encipher it with the Caesar cipher (add a key to each letter) and print out the enciphered text. Write the converse function to decipher.

Count the occurances of letter 'a' in a file
Read a file name in on the console, open the file for reading and count the occurances of 'a' in the file. Print the result (and close the file!).

Linear data structures: arrays and so on


Binary search
Look for a value in a sorted structure -- iterative or recursive solutions are both interesting to try out.

Bubble sort
The simplist sorting algorithm, but it should give a reasonable idea of how to manipulate mutable structures, or deal with immutable ones if that's all the language has available.

Modularity: modules, classes, objects, etc.

Sets data structure
Sets are a simple data structure to implement, they're easy to test and a good instroduction to polymorphism. Union, difference, intersection, etc. all make useful methods and you can play about with mutable or immutable sets and see the difference.

Wednesday, 11 October 2006

Why Linux is such a great choice for multimedia computing

All about Linux has a great post on the use of Linux in the film industry. Check it out!

Sunday, 1 October 2006

GUI programming basics 1/3

This is the first of three posts on the basics of GUI programming. This post covers the most fundamental of GUI concepts with some example code to illustrate them. The next post will cover some more complex issues (in particular, layout managers) and the final post in this series will contain an extended example -- a simple text editor.



GUI programming is a bit of a black art. It sits on the interface of prgramming and HCI and usually requires careful planning (for usability) and relatively, but not very, sophisiticated programming techniques (meaning we don't teach it in the first year). Generally, GUI toolkits make good use of objects and to learn a new toolkit you need to understand a whole bunch of GUI jargon. Conceptually, there's not a lot new to learn when it comes to writing GUIs. If you already know about objects, OOP and event loops then you've learned most of what you need, the rest is just jargon and libraries. So, first to the jargon, then we'll look at some code. The following is a brief glossary of GUI concepts, in alphabetical order:




Binding:

Binding is the process of associating an event (such as a key press or mouse movement) with a callback or event handler. For example, we might bind the key accelerator Ctrl-S with the callback onSave.


Callbacks (or Event Handlers):

A callback or event handler is a piece of code (usually a function or method) which is executed when an event occurs. For example, an callback called 'onQuit' may be run when the key accelerator Alt-F4 is pressed by the user. Note that callbacks are written by the GUI programmer but scheduled to run by the toolkit -- i.e. you don't usually have to write your own event loop!


Containers:

A container widget may have other widgets embedded within it. For example, a top-level container for an application may contain a menu, statusbar, toolbar and so on.


Events:

An event is usually some form of input or interaction that occurs externally to a GUI but can be detected by the GUI toolkit. Examples include keyboard key presses, mouse movements and button presses, drag'n'drop, and so on. Most events will be uninteresting (e.g. mouse movements) but some require a response from the GUI (such as button presses and key accelerators).


Event Loop:

A loop which is used to dispatch callbacks in response to events. Usually the event loop for a GUI is provided by the toolkit and doesn't need to be written from scratch.


Widgets:

A widget is a single element in a GUI and in OOP languages is usually an object. Example widget types are: label, button, text entry field, canvas (to display graphics), list box, scroll bar, radio button, etc.



Simple GUIs with Tkinter and Python



Tkinter is the cross-platform GUI toolkit which ships with Python. It's based on the Tcl/Tk system and it's popular because of it's simplicity. Other toolkits are a bit more sophisitcated (like, wxPython, based on the C++ toolkit wxWidgets) but are also more complex. So, Tkinter is a good place to start if you haven't writen GUIs before, but you might want to look around at other libraries when you're a bit more confident of the basics.



What follows is a very simple series of 'Hello World!' scripts which introduce the very basic concepts of GUI programming by producing minimal GUIs. The next post on GUI programming will introduce some more complex practical concerns -- various widget types, layout (geometry managers), and so on.



Hello World! (1)



This script is absolutely minimal. It simply creates an empty application window (called root) and instructs Tkinter to start it's event loop.




#!/bin/env python2.4

"""
Hello World! with Python's Tkinter GUI toolkit.
"""

from Tkinter import *

__author__ = 'Sarah Mount'
__date__ = 'October 2006'

root = Tk()
root.mainloop()



Hello World! (2)



An empty application window isn't much use! The next script creates a single widget, a label. Labels are holders for text. They generally don't do anything (unlike, say, buttons) so they are really the simplest widget around. In our case, we just want to create a label, pack it (meaning, arrange it on the main application window) and start the Tkinter event loop.




#!/bin/env python2.4

"""
Hello World! with Python's Tkinter GUI toolkit.
"""

from Tkinter import Label

__author__ = 'Sarah Mount'
__date__ = 'October 2006'

# Create a widget
widget = Label(None, text='Hello World!')
# Arrange widget in application window
widget.pack()
# Start GUI event loop
widget.mainloop()


Hello World! (3)



Our third version of Hello World! introduces callbacks. Here, we use a button widget rather than a label. When we create the button, we need to give Tkinter a reference to a function which can be called to handle mouse click events.




#!/bin/env python2.4

"""
Hello World! with Python's Tkinter GUI toolkit.
"""

from Tkinter import *
import sys

__author__ = 'Sarah Mount'
__date__ = 'October 2006'

def quit():
print 'Quitting...'
sys.exit()

widget = Button(None, text='Quit Hello World!', command=quit)
widget.pack()
widget.mainloop()


Hello World! (4)



This last script is essentially the same as the last, but makes use of a lambda expression in the callback. This is a common technique and although it's rather pointless in such a simple script, lambdas are a great way to cut down the size of your code whenever you need a simple function call in an event handler.




#!/bin/env python2.4

"""
Hello World! with Python's Tkinter GUI toolkit.
"""

from Tkinter import *
import sys

__author__ = 'Sarah Mount'
__date__ = 'October 2006'

def quit(msg):
print msg
sys.exit()

widget = Button(None, text='Quit Hello World!', command=lambda: quit('Quitting...'))
widget.pack()
widget.mainloop()


Further reading