I gave a talk at the second python user group in leeds on Wednesday. It was called “Anatomy Of A Python Program - How Much Can You Do In 0.1 KLOC?”. It is based on Peter Norvigs Sudoku solver. I had been thinking about doing it for WYLUG, possibly as a second talk after an intro to python. The slides were the same, but instead of looking at cool features of python that make the code so concise we critiqued it a bit and spoke about the style and possible speedups. The slides for the talk is here, but as I did not add any notes, you would be better off just reading Norvigs article (though the Javascript slideshow is cool, press t to toggle views)

The slideshow was made using rst2s5 and I am amazed how well it works. Restructuredtext is from Pythons Docutils and is a simple markup language designed to be readable as plain text, see here for details. Below is part of the code for my presentation

==============================================================
Anatomy Of A Python Program - How Much Can You Do In 0.1 KLOC?
==============================================================

:Author: Tom Hall
:Date: 11pm Tues Dec 4th

The Problem - Sudoku
====================

::

+----------+----------+----------+
| A1 A2 A3 | A4 A5 A6 | A7 A8 A9 |
| B1 B2 B3 | B4 B5 B6 | B7 B8 B9 |
| C1 C2 C3 | C4 C5 C6 | C7 C8 C9 |
+----------+----------+----------+
| D1 D2 D3 | D4 D5 D6 | D7 D8 D9 |
| E1 E2 E3 | E4 E5 E6 | E7 E8 E9 |
| F1 F2 F3 | F4 F5 F6 | F7 F8 F9 |
+----------+----------+----------+
| G1 G2 G3 | G4 G5 G6 | G7 G8 G9 |
| H1 H2 H3 | H4 H5 H6 | H7 H8 H9 |
| I1 I2 I3 | I4 I5 I6 | I7 I8 I9 |
+----------+----------+----------+

Setting The Scene
=================

::

def cross(A, B):
return [a+b for a in A for b in B]

rows = 'ABCDEFGHI'
cols = '123456789'
digits   = '123456789'
squares  = cross(rows, cols)
unitlist = ([cross(rows, c) for c in cols] +
[cross(r, cols) for r in rows] +
[cross(rs, cs) for rs in ('ABC','DEF','GHI') for cs in ('123','456','789')])
units = dict((s, [u for u in unitlist if s in u])
for s in squares)
peers = dict((s, set(s2 for u in units[s] for s2 in u if s2 != s))
for s in squares)

Taking in problems
==================

::

def parse_grid(grid):
"Given a string of 81 digits (or . or 0 or -), return a dict of {cell:values}"
grid = [c for c in grid if c in '0.-123456789']
values = dict((s, digits) for s in squares) ## To start, every square can be any digit
for s,d in zip(squares, grid):
if d in digits and not assign(values, s, d):
return False
return values

The second talk went a bit over my head but was interesting, a declarative metaclass pattern. The chat after was great, everyone is interesting and excited about similar things to me.

I used Python the next day in work when our FTP server (a crappy windows app that I have disliked all the time I have been here) decided to recreate its password list as a 0 byte file and left us with no FTP. I took the time to do an upgrade to Filezilla and wrote a little python script to create entries in Filezillas xml config for all the users (though I had to manually create a .csv with all the usernames/passwords in). Simple things like this are another reason I like Python, it’s great tool for a SysAdmin to get those annoying little jobs done.

import md5

%s

0
0
0
1

0

1
1
1
1
1
1
1
1
1
0

"""