Python Comprehensions

Wev've had many posts that were mainly pictures; let's have one with some code!

Over last couple of months I've got impression that some people do not regard Python as good, modern language (well it has some of the history to make some people stop and think). As any language it has its good and bad sides along with where it can be used as a really good choice and where maybe not.

Python is quite a high level programming language which had its object orientation added relatively late and some of it reflect in somewhat clumsy syntax. But, there are some other sides of Python that put is at par with other popular languages like Java/C#, Ruby, JavaScript and such. Some of it's syntax sugar is making it even better... And that's what we'll look into here: list and dictionary comprehensions.

The problem

Our code is separated in many small processes which acquire data from sensors, inputs and such, process them and send them by MQTT messages to high level controllers that make decisions and send them to lower level controllers that know how to command wheels, and then from there to wheel controllers that steer and drive them. For simplicity originally we adopted sending messages in plain ASCII - human readable form so debug can be really easy. For instance shell command:

mosquitto_sub -v -t wheels/#

would show required positions and speeds of wheels,

mosquitto_sub -v -t move/#

would show what was required of rover to do - rotate, drive in straight line at angle or steer around some point at some distance form the rover.

Distance sensors do provide similar messages that look like this:

0:1201 45:872 90:563 135:797 180:1622 225:433 270:319 315:478

Solution

To transform it from string like that to a dictionary we can use simple code like this:

But we had another problem to deal with: sometimes we have data passed to us at various parts of the code as just a list without keys given - where keys are understood. For instance logging: we have record containing values that were previously logged (something like [1550348686.8102736,b'fr',b'SK',1.0,32,0.0,0.0,0.03261876106262207,0.0,0.0,0.0,0.0]) and list of fields that were used to create that record. Each field is an python class that has toString(value) and fromString(value)methods. First is to produce csv file and second to create value from csv's column.

So, to create CSV file (which we can use later on for analysing what went wrong) we would like to create a string out of record and back to create a record back of string. But our data and data definitions are in separate arrays. Ordinary solution people would normally go with (and including me before I got fascinated with comprehensions) would go something like this: