This is a python application, running on a Raspberry Pi, that accepts turtle-like commands from tweets sent to it. These commands are then drawn on a screen to turn simple programs into shapes.
I ran this activity at the KEGS (King Edward Grammar School) DigITFest on Saturday 9th November.
I was contacted by KEGS school a few weeks ago with a view to setting up a stand and perhaps runing some form of technical activity or workshop for the general public, along with many other local exhibitors of interesting technology.
I thought a bit about different activities that I could run, but I wanted something that people could walk up to, have a little dabble with, and perhaps learn something about technology – so I didn’t want a workshop, what I really wanted was an interactive exhibit.
The inspiration came from a good friend of mine, Richard Trussler (@richardtrussler), who I first met a few years ago at a business centre I work at in Harlow. Richard does a lot of marketing and web site design work, but having young children himself, understands the sorts of things that are engaging for children to take part in. Richard and I have worked on some projects together since, and we have become good friends.
Richard came up with the idea here – I take no credit for the idea, [only!] the engineering work that made it happen!
The exhibit basically consists of two parts – a program watches my twitter feed and looks for tweets that match some pattern (e.g. a known hash tag). A second program parses these into instructions for the python turtle module, and draws a shape from this “small program” on the screen.
The exhibit shows two things – first that it is possible to use social media (something that children understand better than adults!) to interact with a real computer system, and secondly that programming computers can be fun!
Twitter turtle command language
I’ll start with the programming side first, as that was the most successful bit of the exhibit, and dig into the twitter interaction side later.
If you haven’t heard of a turtle programming language, or LOGO, please do follow the links in the resources section. But all you really need to know at this stage, is that a turtle can be told to move and rotate, and as it moves it leaves a trace on the screen (or paper) that means you can draw some interesting shapes very easily.
Actually, this part was surprisingly more successful than I had originally hoped. The twitter interaction was where I started, and this created a need for a “very compact command language to control a turtle like entity on the screen”. It was this compact language that won the day I think.
So, like any good engineering design, there are compromises and resource limits to work within, and a number of design compromises to make along the way. Starting from the premis that commands would come in as tweets, that limited me to about 140 characters for a “whole program”. So, there is my resource limit – a program can only take up 140 characters of “memory”. This caused me to define a very compact version of LOGO that consisted of single character commands, each with an optional single numeric argument.
The full command set consists of only 11 commands as follows:
H – move home
F – move forward
B – move backward
U – lift pen up
D – lift pen down
R – rotate right
L – rotate left
N – face north
E – face east
S – face south
W – face west
N,S,E,W are not strictly necessary, but useful sometimes, so I included them. However you could argue that the core language needs only 7 commands.
To draw a square, you use FRFRFRF
To draw a triangle, you use F50 R120 F50 R120 F50
(spaces added for readability, but not required)
The full command set and their optional arguments are defined in the worksheet in the resources section.
The screen consists of two main windows – the left screen shows the present drawing, and the right screen shows a random mosaic of all the drawings done to date.
Teaching programming skills
The LOGO/Turtle concept is a very good starting point for teaching programming skills, and very young children can be taught (and self discover) many core computer science concepts using such a language. Please see the LOGO links in the resources section for a history of this type of language.
I have done some work with children in Raspberry Pi clubs before, starting them with the python turtle – however, very small children take quite a bit of time to type in all of the commands. The interesting discovery about my compact command language, was that I had children as young as about 7 right up to adults who told me they really enjoyed this activity, and were able to write real programs very quickly due to the limited typing required.
The worksheet was designed very carefully to allow experimentation but also to contain all of the information needed to draw real shapes. As I was interacting with visitors and explaining this activity, I found myself explaining the core processes that I use every day in my job as a professional software engineer – first I have an idea or a requirement for something to build. I draw a sketch of this on paper, I learn or use a programming language, I design the program (coding), I enter this code into the computer and “run” it, and look at the results. If the results are not as I expected, I look back at my design, alter the program, and run it again. If the problem gets too big, I break it down into smaller parts and debug each part in isolation before I then put them all back together into a bigger program.
For many of my visitors, whose age range varied somewhere between 7 and 70, everyone “got it” very quickly. They drew a sketch on my worksheet of a shape they wanted to draw, they read my command quick reference, “coded it up” on to the right side of the paper, and entered that into the computer. They “ran it” and looked at the shape it created. If something went wrong, they “debugged it” by splitting their program into smaller parts (often just entering the commands for the first shape), and gradually built the shape up in parts until it worked.
Here was the mosaic picture at the end of the day:
You can see a trend of squares and triangles (as they are relatively easy to draw), but also some larger polygons with different numbers of sides, a bit of a circle, some initials and words, and a few staircases and spirals.
Limitations of the language – a learning opportunity
I had intentionally made version 1 of this language very limiting, partly because I didn’t have time to write all the other commands I wanted, but mainly because I wanted this to be a progressive learning experience. I wanted version 2 of the language to be based on the problems that users reported with version 1.
The core “problem” that users reported, was that it was hard to do repeating shapes – and they said “it would be good to be able to do the same thing lots of times” – “ah, so you would like loops then” I said, and they all agreed. The really nice part about this was that the need for loops came from a specific failing in the version 1 language, and it was actually the users of version 1 who were telling me about the “problem” (no way to repeat things) and also in most cases telling me what the requirement was (“a way to repeat something a number of times”). Some of the children and adults had done a little bit of programming and knew that what I needed was something like a FOR loop.
Interacting via Twitter
This was where I started with while developing this project, and I thought this was going to be the most interesting bit. Some people did type in the commands and tweet them to me, but on the whole people wanted to type their commands into the keyboard as it was a bit more immediate.
This is a good thing, because I made a small error of calculation in my code, and after 15 minutes, I was blocked from the Twitter API and it would no longer read my timeline. There is a bigger story about this which I will explain in a later blog, but basically, twitter “rate limits” you to 15 requests within a 15 minute period. I did write (and test) special code that automatically inserts a timer to ensure that no more than one request a minute is sent to the API, but it looks like accumulated errors in my calculation over a 15 minute period still caused the rate limiting to occur. This wasn’t a real problem as people actually prefered the more immediate nature of the keyboard, but I will fix this in a later release.
A point to note here, is that it’s generally very simple to develop small programs that work once. Developing an industrial class program that is able to work completely unattended for weeks without any interaction from a user is a very different story that requires much careful design and testing. It’s really great that there are so many hobbyists rolling their sleeves up and building great demonstrators, and getting involved with children programming, but my day job as a software engineer reminds me that there is a big gap between “works once” and “always works”, and we do need to be a little cautious and mindful to not give children the impression that coding is just a matter of hacking together 20 lines of code and you have a product.
I will blog about the twitter component another day, as there is not much space here, and I want to talk a bit about the software engineering process I went through to develop this exhibit.
The design of the program
I intentionally split the program into two separate parts – a twitter reader, and a command drawer. The separation between these two is very distinct, to the point that I actually run them as two separate python programs in different terminal windows. I intentionally wanted to build and test them separately, and make them work independently. This made the testing easier, but also gave me a generic twitter reader program that I could easily use for other purposes.
Developing the program
Like in my day job, I performed what we call “dual targeting” – I developed and tested on one platform (the PC), and when that was working, I moved the code over to the target platform (the Raspberry Pi) and re-tested.
There are two reasons why I work this way:
Firstly, it is convenient and fits into my lifestyle. I have a busy day job and I squeeze- in the development of teaching resources in to train journeys and lunchtimes. Working on the PC is more convenient (it’s a pain to use a Raspberry Pi on a train or in McDonalds by the way!) and means I can take advantage of spare time slots between other activities.
Secondly, I often end up in a situation where I write the core software before I have any hardware (this happens all the time in my day-job, it’s called “concurrent development” – the hardware is being designed at the same time as the software). Being able to get most of the program running on the PC allows it to be quite thoroughly tested before it get anywhere near the hardware.
So, I just followed my normal process – I started from a cookbook example for the twitter API (thanks to @charwarz for her Twitter LCD blogs!), then developed this further to add the features I needed.
When everything was working, I copied it over to my Raspberry Pi, and it worked first time. Python on the PC and Python on the Raspberry Pi are very similar, and I have done about 5 projects now this way and they have worked smoothly.
For projects where I have to control hardware, I have a “dummy RPi.GPIO” python module I use on the PC that just prints messages to the console, and I can often test most of the logic of the hardware control on the PC this way.
The other key design decision in this program was that all “state” would be stored in files, rather than in memory, so that the system would be completely recoverable after a crash. As I was building up an on screen mosaic of every turtle trace of every user, I didn’t want to loose this if the program crashed (or as happened lots of times, someone pressed the close-box on the window by accident and the program stopped). I just re-run the program, and it recovers it’s state from tweets and commands stored in text files in the filing system.
The two parts (the twitter reader and the command drawer) exchange data via a commands.txt file, so if there are more tweets yet to be processed, I can recover this list of commands and continue to draw old tweets from history, even if the program crashed.
One of the biggest problems with testing is the rate limiting on the twitter API. If you fetch more than 15 times within 15 minutes (i.e. on average 1 per minute) the API rate limits you and prevents you using the API for an indeterminate period (usually about 15 minutes but I think the API docs say that this could be a randomly increasing time limit). I managed to get rate limited many times, so I wrote a ”RateLimiter.py” that prevents this, by inserting a delay if you try to fetch more than once a minute.
Teething troubles on the day
Well, the RateLimiter seemed to work ok in testing, but it is possible that my testing patterns were not the same as my “run it forever” pattern on the day. After the first 15 minutes on the day, I got rate limited. As I was busy talking to people I didn’t notice this, and it stayed rate limited for some time. I think a small error in my maths meant that it wasn’t quite waiting 60 seconds in all cases, and over 15 minutes this added up and I got rate limited.
As it turns out, people prefered to use the keyboard, but I will build my rate limited twitter reader (with bug fixes) into another exhibit soon and I will blog another day about what I did to fix and to test this.
The original concept for this exhibit from @richardtrussler was to build a real moving robot. I didn’t have time to do this in the available spare slots I was fitting this project into, but I see that @ryanteck has released a motor controller board that looks like quite a good way to build a robot, so I’ll be giving that a go.
The full code that I used on the day is provided in the resources below. Note that if you want to use the twitter watcher code, inside the twitter folder, you will have to sign up for a twitter API key and put your credentials in the Credentials.py in the twitter folder for this to work.
You can also edit the TweetReaderApp.py to change the tag search pattern, which is at the moment configured to look for #test3 on your timeline.
Inside the zip file, for convenience, you will find the code for twython, oauthlib, requests and requests_oathlib. This should not be considered a distribution of these files, please go and get their original sources off of github if you want to use them in something else – they are only provided here so that you can download the zip file and run it as-is without having to go and download dependent packages. All original copyright messages are left in these packages so you can trace them back to their original authors.
You will note that I have written a twitter.Twitter.py, which is a wrapper around the twython library to provide a simpler to use interface for this application (including the integrated version of the RateLimiter.py that I wrote, and other state management features).
The robot folder contains a number of different robot implementations, including a python turtle version, a raw maths version, a print-on-screen version, and also the beginnings of a GPIO motor controller that I plan to link up to two DC motors on a motor control board to build a very simple physical turtle that draws on paper (probably quite inaccurately due to the use of DC motors) – but there are placeholders where you could easily knit this up to stepper motors.
DrawApp.py is the turtle drawing program, and you can enter commands from the terminal window using this and it will draw them.
TweetReaderApp.py will read tweet from your twitter timeline and append them to tweets.txt, filtering out those that look like commands into a file called commands.txt. If you run both programs together, as tweets come in that are recognised as commands, they appear in the drawer console window with a number. Type in “tweet 3″ to then draw the tweet numbered 3 on the actual turtle window. If the program crashes, re-run DrawApp.py and type in “recover” in the terminal window and it will re draw everything (which is stored in done.txt)
Python version 2 is used for both these programs, and both programs have been tested and work on both the PC and the Raspberry Pi.