Posts

Using Simpy and Python

I recently completed a discrete-event simulation model using SimPy. This was my first foray into Python programming and the first time I used a non-graphical discrete-event simulation package (most of my previous experience was using Witness).

The model tracks the utilisation of wagons on trains. Key constraints include availability of staff, availability of a path through the network for movement of trains and wagons, and availability of a spare locomotive to make ancillary wagon movements. Maintenance activities are simulated as are wagon faults and repairs.

The rail network is represented using a .dot file; our brilliant computer scientist, Loki, devised a mechanism to find a path through the network using the pygraph minmax module (pydot is used to parse the .dot file).

Although the learning curve was quite steep for me, I found that I really enjoy working with both Python and SimPy. It was liberating not fiddling with graphics which must be placed precisely on the screen or manipulated to get element iteractions to work perfectly. The use of a .dot file to represent the rail network means that it can be changed at will without requiring a vast amount of re-work to fix graphics (the initial network is a high-level representation of the actual network which will be refined in the future). As an added bonus, Graphviz can be used to view and modify the .dot files. SimPy doesn’t come loaded with pre-configured entities (like machines, staff, tracks, forklifts, etc.). However, you can create any entity you desire and define it’s behaviour using the Python programming language. Since SimPy is open source all code is freely available and can be modified to provide further functionality. This provides far greater flexibility than I’ve experienced with other packages since I was not limited by behaviours defined by the package developers and the use of a package-specific macro language. As with other simulation packages I’ve used, I created variables to track important information and then created both .txt and .csv output files on which extensive analysis can be performed.

While the cost of using Python and SimPy was a significant learning curve (for me) I feel that it was definitely worth it. We’ll be looking to use SimPy on future projects!

Special thanks to Klaus Muller for his patience in answering my questions and assistance!

Generating KML Thematic Maps


The Biarri workbench now has a tool for showing the frequency of an event per postcode. The colourised map (funkier name Choropleth map) is generated as KML from postcode regions that are stored in a postgis database. This just requires a little bit of sql and python:


dict_cur.execute("select p.gid, p.poa_2006, ST_AsKML(the_geom) as \
                  polygon, frequency, (frequency - stats.min) / (stats.max - \
                  stats.min)::float as scaled_frequency from "+table+" c, \
                  postcode_regions p, (select max(frequency), min(frequency) \
                  from "+table+") as stats where p.poa_2006 = c.postcode")
return my_lookup.get_template("thematic_kml.mako").render(rows=dict_cur.fetchall())

The sql just normalises the column we want as our colour intensity and returns the KML for each postcode region.

The mako template:




    
    Thematic Map
        generated with the Biarri workbench
    % for row in rows:

 
 ${row['poa_2006']}
 
 ${row['frequency']}
 
 #${row['gid']}
 ${row['polygon'].replace(" ", '\n')}
 
 % endfor
 

<%!
import webcolors
import colorsys

def intensity(frequency):
#frequencies are already scaled between 0 and 1
 return 'cc' webcolors.rgb_to_hex(tuple((int(a * 256) for a in colorsys.hsv_to_rgb(0.134, frequency, 0.90)))).strip('#')
%>

The mako template is quite easy to read if you notice the % sections are actually python code. The only challenge I had was that ST_AsKML produces kml with the co-ordinates space separated. Google earth is fine with this but the kml viewer we’re using, web map lite, only likes them newline separated. My colour function just changes the intensity of the colour. A gradient between blue and red would probably be more appropriate.

Loki

The Wonders of Python

I recently wrote a little code generator in Python that takes in a schema file in XML format and expands out specially marked up tags inside C++ code. It was my first real industrial strength use of Python and (for this C++ veteran at least) I was amazed at how much I could accomplish in just 300 lines of code. In particular I liked:

  • Not having to compile!
  • List comprehensions
  • String slicing and dicing
  • Returning multiple arguments from a function
  • Some really nice constructs:
return “True” if (self.Type not in self.VariableTypes) else “False”
This one sure does flow like natural language.

Dynamic typing sometimes feels like a free for all, but I’ll gladly pay that price for the many powerful features it enables. I sure am writing “self” a lot though 🙂

I think the real epiphany moment was realising that there is essentially no real complexity inherent in the language – this is very liberating compared to C++ where you have to constantly steer clear of C++’s many dark corners (about which entire books have been written, e.g. C++ Gotchas by Stephen Dewhurst). Programming really does become less of a struggle.

A somewhat tangential link musing over Python vs C++ in the context of unit testing is this blog post, which describes approaching building a Sudoku solver. Those interested in the Sudoku-solving ability of Python should also be sure to check out this impressive presentation on AI, puzzles, and the use of ‘itertools’ in Python.