Categories
CPAN

Timeline Diagrams with Perl

Two weeks ago, I introduced you to my new module SVG::TrafficLight and hinted that there were more SVG-based modules to follow. Today, I’d like to talk about the next one – SVG::Timeline.

It all started over a year ago when I was looking through some of the more ridiculous religious questions on Quora when I came across one asking why Adam wasn’t mentioned in the Bible after the first couple of books in Genesis. As part of my answer I wanted to illustrate just how long a time Genesis 5 covers.

I knew that SVG would be the best approach and it only took half an hour or so to whip up the image you can see in my answer (and there’s a newer version, generated with the current version of the code, at the top of this page). It’s important to note that  I didn’t hand-craft SVG that drew the diagram – I wrote code that generated the diagram from an input file.

I then realised that this could be a more generally useful tool, so I set about making the code more generic. It languished on Github for a year or so before I decided it was useful enough to clean it up and release it to CPAN. Let’s take a quick look at how it works.

As you can see from the example above, a timeline is made up of a number of events. An event has a start date, an end date and some text. So you can start a timeline diagram with code like this:

And once you have added all of your events, you can produce the timeline using:

That code writes the SVG document is written to STDOUT, so you’ll probably want to redirect that to a file.

That will draw a timeline of your events using all of the default settings (which, in most cases produce a useful diagram). There are plenty of options that you can pass to the object constructor to tweak things. The most useful are probably the aspect ratio (if your diagram is going to be particularly long or thing – the default is 16/9) and the number of years between gridlines in  the output (the default is ten and you might want to change that if your timeline covers a particularly large or small number of years – like the Genesis example above).

The default behaviour is to colour all of the events the same colour (which can be changed from the default in the constructor for the SVG::Timeline object). But you can also change it for each individual event by adding an optional “colour” parameter to the add_event() call.

But that’s all a lot of work for the simple case. So the distribution also includes a command line program called timeline which does all of that for you. It reads a datafile and produces a timeline diagram based on  the contents.

Each record in the input file has three or four fields separated by tabs. The fields are the parameters for the add_event() call in the order: text, start, end and (optionally) colour.

There are example data files in the distribution for producing some of the timelines I’ve talked about in this article – along with shell scripts showing how to produce timeline diagrams using the command line program.

There are a few things I’d like to add. Support for events with unknown dates (perhaps fading the colour towards the unknown end). Diagrams that go vertically instead of horizontally and support for events that begin and end in the same year (currently, they are zero size and just vanish – I discovered that when I added Paul McGann and Christopher Eccleston to the Doctor Who example).

I find the program… well, if not exactly useful, it’s still fun to play with.

Please let me know if you produce any interesting timelines with it.

Categories
CPAN

Drawing Traffic Lights With Perl

For a thing (that you may hear more about at some point in the future) I needed diagrams of traffic lights. But Google Image Search didn’t really have what I was looking for. Everything was either too realistic or not CC-licensed so I couldn’t use the images how I wanted.

So I decided to do it myself. But I’m not exactly artistic. I far prefer it when I can get computers to draw images for me. I’ve dabbled with SVG before and it seemed like the perfect tool for the job. And there’s a module from CPAN that makes it simple to create SVG images from Perl.

It only took an hour or so before I was drawing images like the one above – which was exactly what I was looking for.

Initially, I shared my code as a Gist, but since then I’ve extracted the useful bits into a module which I’ve uploaded to CPAN as SVG::TrafficLight. I’ve tried to make it as configurable as possible, so you should be able to use it for all your traffic light drawing needs as well.

Starting to use it is pretty simple.

The default sequence of lights shows the UK’s standard traffic light sequence (green,  amber, red, red and amber, green) but it’s simple enough to produce a different sequence (even one that you would never see on the roads).

If you read the documentation, you’ll see how you can customise pretty much anything in the diagram – the size of the lights, the padding between them, even the colours used.

Let me know if you find it all at useful. SVG is fun. I’ll think I’ll investigate it some more.

 

Categories
Programming

Shaving Last.FM Yaks

Long-time readers might remember that I once had a bit of an obsession with aggregating web feeds on sites that I called “planets”. I wrote Perlanet to make this job easier and I registered the domain theplanetarium.org to host these planets.

The planets I built were of varying levels of usefulness – but of all of them, planet davorg was the vanity project. It was simply a way to aggregate all the web feeds that I produced. There were feeds from various blogs along with things like Flickr, Twitter and CPAN.

One of the things I liked about planets was that they were self-maintaining. Once you’ve configured a planet, it will just keep on running (well, as long as the cron job is running). If the web feeds they are aggregating have new content, the planet will have new content. And many of the feeds that powered planet davorg were still running.

But last weekend I found a couple of  problems with it. Firstly, it looked like it was designed by an idiot. Which, to be fair, it was. Web design was never my strong point. But we have Bootstrap now, so there’s no excuse for web sites to look that bad. So that’s how I spent the first hour or  so – slapping a bit of Bootstrap paint onto the site. I think it now looks acceptable.

The second problem was that not all of the feeds were still running some of them (Delicious, for example) were just dead. I can’t remember the last time I posted anything to Delicious – can you? So I spent some time tweaking and fixing the feeds (replacing CPAN with MetaCPAN, for example). Most of this was easy.

However, one feed was a problem. My Last.fm feed was dead. For over ten years I’ve been “scrobbling” ever song I’ve listened to and one of the feeds I was aggregating was that list. According to this page on their web site, my feed is supposed to be at http://ws.audioscrobbler.com/1.0/user/davorg/recenttracks.rss – and that was the URL in my Perlanet configuration. But it doesn’t work. It returns a 404 error.

I tried to contact someone at Last.fm to find out what was going on, but I haven’t got any kind of response. It looks like they’ve been running on a skeleton staff since CBS took them over and they don’t seem to have the time to support their users (not, I suspect, a recipe for long-term success!)

But there was one possibility. You can get the same data through their API. And some quick experimentation, revealed that their API hasn’t been turned off.

And CPAN has Net::LastFM which will make the API calls for me. Ok, so it hasn’t been updated since 2009, but it still works (I’ve just noticed that there’s also Net::LastFMAPI which is a little more recent).

So it just took a small amount of work to write a little program which grabs uses the Last.fm API to get some JSON that contains the information that I want and convert it to an Atom feed. In case this is useful to anyone else, I’ve put the code on Github. Please let me know if you do anything interesting with it.

And if anyone from Last.fm reads this. Please either turn the web feeds back on or remove the documentation that still claims they exist.

Categories
CPAN

Version Numbers

Last week I mentioned how I had uploaded a new version of Symbol::Approx::Sub. Because there were pretty major changes to the inner workings of the module (although the interface still looked the same) I decided that I would move it from version 2.07 to version 3. At the same time, I decided that I would switch to a semantic versioning scheme.

Later in the week, I released minor updates to a few more of my modules. And I decided to apply semantic versioning to those as well. But as I was only making minor packaging fixes to these modules, I didn’t increment the major version number. For example, Array::Compare went from 12.2 to 12.2.1.

It turns out that was a mistake.

Well, I don’t really think it was a mistake. I think it was the right thing to do. But it appears that my opinion is at odds with what some parts of the Perl toolchain think.

Last night I got this bug report. It seems that by switching to three-part semantic versions, the version number can (in some quite common circumstances) appear to decrease.

To my mind, a version number is a dot-separated sequence of numbers. So 12.2 is smaller than 12.2.1. Any sane version number comparison will separate the two strings on dots and compare the individual components. Any missing components (12.2 is, for example, one component shorter than 12.2.1) should be assumed to be zero.

But that’s not what the Perl toolchain does. Observe:

When the version number with two components (2.12) is split into components, the second component is bizarrely treated as a three-digit number so it becomes 120 instead of 12 and when it is compared with the second component of the three-component version, 120 is obviously larger than 12 and any tool which relies on this behaviour to work out which version of a module is the most recent will get the wrong answer.

This leads to other “interesting” effects. In my head, versions 1.1, 1.01 and 1.001 are all the same version. The leading zeroes mean nothing. But under this scheme, they are very different version numbers.

I know that versioning isn’t as easy as it should be and I know that some people use bizarre versioning systems. And I’m pretty sure that no matter how bizarre a versioning system is, you’ll almost certainly find an example of it on CPAN. So I suppose that this behaviour was a “least worse” scenario that was chosen to make the most sense given CPAN’s wide range of versioning schemes.

Personally, I see it as a bug in version.pm. But I’m not going to report it as such as I’m sure the Perl toolchain gang know what they’re doing and have very good reasons for adopting this seemingly broken behaviour.

I just need to remember to be more careful when switching my modules to semantic versioning. Using a minor or patch level version change when switching to semantic versioning is likely to lead to confusion and bug reports. Only a major level change (as I did with Symbol::Approx::Sub) is guaranteed to work.

And, I suppose, I’ll need to release Array::Compare 3.0.0 to CPAN pretty soon.

Categories
Programming

Hacking Symbol::Approx::Sub

In October, for (I think) the second year, Digital Ocean ran Hacktoberfest – a campaign encouraging people to submit pull requests to Github repos in exchange for free t-shirts.

A few of us thought that this might be a good way to do a small bit of easy Perl advocacy, so we tagged some issues on Perl repos with “hacktoberfest” and waited to see what would happen.

I created a few issues on some of my repos. But the one I concentrated on most was symbol-approx-sub. This is a very silly CPAN module that allows you to make errors in the names of your subroutines. I wrote it many years ago and there’s an article I wrote for The Perl Journal explaining why (and how) I did it.

Long-time readers might remember that in 2014 I wrote an article for the Perl Advent Calendar about Perl::Metrics::Simple. I used Symbol::Approx::Sub as the example module in the article and it showed me that the module had some depressingly high complexity scores and I planned to get round to doing something about that. Of course, real life got in the way and Symbol::Approx::Sub isn’t exactly high on my list of things to do, so nothing happened. Until this October.

Over the month, a lot of changes were made to the module. I probably did about half of it and the rest was pull requests from other people. The fixes include:

  • Better tests (and better test coverage – it’s now at 100%)
  • Using Module::Load to load module
  • Using real exceptions to report errors
  • Updating the code to remove unnecessary ampersands on subroutine calls
  • Fixed a couple of long-term bugs (that were found by the improved tests)
  • Breaking monolithic subroutines down

And I’m pretty happy with how it all went. The work was mostly completed in October and this morning I finally got round to doing the last couple of admin-y bits and version 3.0.0 of Symbol::Approx::Sub is now on the way to CPAN. You still shouldn’t use it in production code though!

Thanks to everyone who submitted a pull request. I hope you did enough to earn a free t-shirt.

If you want to get involved in fixing or improving other people’s code, there’s the 24 Pull Request Challenge taking place over Advent. Or for more Perl-specific code, there’s the CPAN Pull Request Challenge.

p.s. In the Advert Calendar article, I linked to the HTML version of the results. For comparison, I’ve also put the new results online. It’s a pretty good improvement.