Keeping Code

Well, so far we’ve learnt about storing data (either “flat” in file, or as an object which Python does in pickles which are also data in files, but with some structure) but we don’t know anything about storing the code we are typing. This means that we need to go through the tedium of typing stuff in all the time (or cutting and pasting I guess).  It  is especially tedious when we mistype something.

In order to do some more complex things in Python we really need to be able to store our code somewhere so that typing mistakes we make don’t mean we have to re-type the whole kit and kaboodle. We could, if we really wanted to, open a file from within our Python prompt and write code to the file (as a flat file):

 >>> f = open('textfile.py','w')
 >>> f.write("print 'This is some python code stored in a file'")
 >>> f.close()
 >>> import textfile
 This is some python code stored in a file

What has happened here is that we’ve open()ed a file called ‘textfile.py’ (again, we’ve taken the chance that there isn’t already such a file, because open()ing it would delete the existing contents).  We’ve then written the following to the file: print ‘This is some python code stored in a file’

We can tell what’s in the file by opening it and reading it back:

>>> f = open('textfile.py','r')
>>> print f.read()
print 'This is some python code stored in a file'
>>> f.close()

Then, when we imported the file, the contents of the file were executed [1].  We can execute this file from the command line (not the Python prompt) using the python command:

>python textfile.py
This is some python code stored in a file

Note only one >, not three.

Why did we put double quotes? See note 2 below.

Now, using Python to write Python code to a file would be incredibly tedious.  Moreover, it wouldn’t solve the problem we have with the ease of editing.  So now we’re going to talk about text editors.  You may need a responsible adult to help you here.

Text editors are programs which are designed to, well, edit text.  They are generally nothing like word processors, and, for our purposes, you can’t use a word processor as a text editor (see note [3]).  There are way heaps lots of text editors.  Everyone is welcome to list their favourite in comments if they feel inclined.

When you use a text editor, there is a different cycle of work.  To date, feedback has been instant because our code has been typed directly into the Python interpreter.  However, when using a text editor your code must first be saved to a file, then you need to execute the file using the python command.  However, once you’ve saved a file you can easily modify it and re-run it.  If you mistyped a single character, then you can use the text editor to navigate to that character and change just it, then save the file and run it through the Python interpreter again.

For the following tutes you need to complete these exercises:

Exercise: See if a text editor is already installed on your computer (try Notepad on Windows, Linux systems should have Gedit and/or Kate)

Exercise: If you don’t have a text editor installed, get the permission of a responsible adult, go find a text editor and install it on your computer.

Exercise: Learn how to use it to open files (usually ctrl+O), and save files (usually ctrl+S).

Exercise: using your new found text editor skills, open a new file and save the following to it:

print "Hello world!"

Then, open a command line, cd to the directory in which you saved the file, then run the file by typing python <name of file>.  Find a responsible adult to help if you can’t work out the cd command.

Hints:

A text editor that I like is called Kate.  Kate needs a windowing system to run, but is available on all popular operating systems. One of the neat things about Kate is that it will do Python syntax highlighting for you.  That is, it will use different colours to show (eg) what are strings, what are commands etc.  Kate also has a command line within the editor, which may make life a little easier for you.  Kate will also automatically indent your code.  This is a useful feature to have and saves you typing in tab characters or spaces to line up code blocks.  This is what the file we saved earlier looks like in Kate, showing code highlighting (the red part shows a string, the black part a command):

A basic editor which works on the command line is called nano.

If you want to make life hard for yourself, but want to be able to swagger as if you were a Real Programmer(tm) try emacs or vi.  Warning: don’t try emacs or vi unless you are brave, neither is for the faint hearted.

There is a text editor which often accompanies Python distributions (it is called idle).  However, at the moment I don’t want to use idle, because it may cause problems down the track.

Notes:

[1] Python has its own function to execute strings as if they were instructions.  It’s called exec(), and that’s happened. Example:

>>> a = "print 'This is some python code stored in a file'"
>>> a
"print 'This is some python code stored in a file'"
>>> exec(a)
This is some python code stored in a file

Warning: there are security issues with using exec() don’t try this at home.
[2]  That is a bit subtle.  We had to put what was written into a string in order to write it.  We’ve had to use double quotes to make the command we want stored into a string.  Had we left the double quotes out we would have had a problem:

 >>> f = open('textfile.py','w')
 >>> f.write(print 'This is some python code stored in a file')
 File "<stdin>", line 1
 f.write(print 'This is some python code stored in a file')
 ^
 SyntaxError: invalid syntax

When we put the double quotes in, it’s not a command anymore, it’s just a string, and we can write strings to files.  However, we wanted to write an actual command to the file – the print command, and for that we needed to use single quotes.  We needed to use double quotes so that the single quotes would be made part of the string.

[3]  If you are careful to use “save as” and always choose “plain text” as the save format, then you can use a word processor, but they are best avoided.

Dictionaries, Hovercraft, Eels

Tobacconist     What?
Hungarian     (miming matches) My hovercraft is full of eels.
Tobacconist     Matches, matches? (showing some)

Dictionaries, Hovercraft, Eels

Welcome to the new look site (which, due the wonder of CSS, has been retrospectively applied to all the earlier tutes)!  This was chosen because it was the first template I found which allowed you to see the whole of the code snippets.

In our earlier tutes we needed to come up with a way to keep track of questions in our trivia game.  We chose to use a list to do that (because that was the only data structure we knew of), but there was another option open to us – a dictionary:

>>> aDictionary = {}
>>> aDictionary
{}

What this code does is create a dictionary which is empty.  We can use the introspection trick we learned in the second last tute to find out a little about our dictionary:

>>> print aDictionary.__doc__
dict() -> new empty dictionary.
dict(mapping) -> new dictionary initialized from a mapping object's
(key, value) pairs.
dict(seq) -> new dictionary initialized as if via:
d = {}
for k, v in seq:
d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
in the keyword argument list.  For example:  dict(one=1, two=2)

Homework: try dir(aDictionary)

So, a “dictionary” has “(key, value) pairs” apparently.  What are these things?  You can think of dictionaries as a generalisation of lists.  In our earlier examples we got the contents of the lists by a number.  The number 0 was used to store the question in the trivia list (if you’ve forgotten it was in this tute).  In that case the number 0 was the “key”, and the text of the question was the “value”. A list only allows you to use numbers as keys. However, dictionaries don’t limit you in that way.  This means that you can give meaningful names to your keys. Let’s add something to our dictionary:

>>> aDictionary["I would like to buy some matches"] = "My hovercraft is full of eels"
>>> aDictionary
{'I would like to buy some matches': 'My hovercraft is full of eels'}

Here the “key” is the string ‘I would like to buy some matches’.  The value is also a string‘My hovercraft is full of eels’. The print out indicates that the object aDictionary is a dictionary by enclosing the output in curly braces -> {}.  Note also that we use the key to reference a value in the dictionary by using square brackets [] in much the same way as we used square brackets to identify members of the list in earlier tutes.

The key ‘I would like to buy some matches’ is a somewhat unusual key. How about we add another (key, value) pair:

>>> aDictionary['it'] = 'The word the Knights of Ni! cannot stand'
>>> aDictionary['Monty Python'] = "A famous comedy troupe from Britain, most active in the 70s and early 80s and on whom the name of the programming language Python is based."
>>> aDictionary
{'I would like to buy some matches': 'My hovercraft is full of eels', 'Monty Python': 'A famous comedy troupe from Britain, most active in the 70s and early 80s and on whom the name of the programming language Python is based.', 'it': 'The word the Knights of Ni! cannot stand'}

Here, aDictionary is acting how you would normally expect a dictionary (no italics, here I mean the sort of dictionary you’d find on a bookshelf) to operate – give it a word (‘it’), and it gives you a meaning for the word.  You should also note here that there is no necessary ordering of a dictionary*1 – in this case ‘it’ comes after ‘Monty Python’ in the print out even though alphabetically ‘it’ should come first.

Dictionaries allow us to set up a direct relationship between the key and the value. In theory, dictionaries give you a speed advantage for looking up values, especially for a large number of keys (this is a result of how dictionaries are implemented).  The reason I use dictionaries is that they usually give me a better way to remember what I am talking about.  So for example, we used sampleQuestion[1] to refer to the correct answer in our list. However, why should ‘1’ identify the correct answer?  If it was a dictionary, rather than a list, we could, instead, have written sampleQuestion['correctAnswer'].  This takes more typing, but in the long run is better because it is clearer what is going on with the code.

That said, lists can be massaged to address this readability issue.  One defines constants with a meaningful name, and then refers to elements by the constants:

CORRECT_ANSWER = 1
sampleQuestion[CORRECT_ANSWER]  # (Same as sampleQuestion[1])

By convention, if a variable is to be used as a constant (ie with a value which does not change) it is given a name consisting of all UPPERCASE LETTERS, as we have done here.  If all the letters are uppercase, there’s no ability for a change in case to indicate a separate word in the name, so we use underscores _ to add meaning.

However, dictionaries still provide some other advantages.  If you ever needed to change your data structure, you would be affected by the ordering of the list. In the data structure we’ve adopted for our trivia game, you could not, for example, include an alternative correct answer because there is literally nowhere to put it in the list*2 – the first entry is the question, the second entry is the right answer and the third and subsequent entries are wrong answers.  You can’t put it at the end, because that’s where wrong answers go and there’s nowhere else left up front.  However, if sampleQuestion was a dictionary, you just add another (key,value) pair (the key might be “alternativeCorrectAnswer”).  Importantly this would not break any existing code which processed a dictionary with existing data.<- in bold because it’s important!  Existing code would look for one of the existing keys, but would not be troubled by the existence of a new key.

That said, the main reason I use dictionaries is not explicitly for this flexibility or for the potential speed advantage.  Rather, I find the concept easy to understand in the first place, and I also find it more easy to understand code which I have written previously if I’ve used a dictionary.

You can get a list of keys in a dictionary (and a list of values):

>>> aDictionary.keys()
['I would like to buy some matches', 'Monty Python', 'it']
>>> aDictionary.values()
['My hovercraft is full of eels', 'A famous comedy troupe from Britain, most active in the 70s and early 80s and on whom the name of the programming language Python is based.', 'The word the Knights of Ni! cannot stand']
>>>

More freaky however, is that you can iterate over all of the keys if you want to:

>>> for k in aDictionary.keys():
...     print "The key is ->",k,"\nand its associated value is ->",aDictionary[k]
...
The key is -> I would like to buy some matches
and its associated value is -> My hovercraft is full of eels
The key is -> Monty Python
and its associated value is -> A famous comedy troupe from Britain, most active in the 70s and early 80s and on whom the name of the programming language Python is based.
The key is -> it
and its associated value is -> The word the Knights of Ni! cannot stand

Is that cool?  In this code each key in aDictionary is assigned in turn to the variable k, so the value corresponding to that key can be accessed by aDictionary[k].

I think it’s way cool.

Homework: make a dictionary which has the name of your friends as keys, and the name of the friend’s favourite game as the value of the key.  Hint: the .__doc__ printout above shows a fast way to create a dictionary populated with keys eg: faveGames = dict(Arthur=”chess”,Hildegard=”Cortex Command”)

PS:

Here’s a site which translates “my hovercraft is full of eels” into various languages

Notes:
*1 Python has another object which will give you an ordered dictionary, but we don’t need it at the moment.

*2 You could, if you were desperate, but it would take a bit of effort, and/or not work with (ie ‘break’) your existing data.

Follow

Get every new post delivered to your Inbox.

Join 69 other followers