Monday, January 14, 2013

Erg Amigo is Born!

A couple of posts ago (that's simply, "Couple posts ago" to any Americans reading) I mentioned that I had found a way to get data from my Concept 2 rowing erg using a Python script called PyRow. Since then I have started making a little application to make erg training more fun and yesterday I christened it Erg Amigo and set up a repository on GitHub.

Whilst it's currently not a lot more than a tool to log workout data from the erg and draw little graphs, I plan to expand it into a proper application that can run real-time logs of multiple connected ergs and perhaps add racing functionality. It will almost certainly never be as functional as the official RowPro software that Concept 2 sell on their website, but at least it will work on non-Windows systems.


Here's the first mind-blowing screenshot of my progress showing a plot of multiple force curves overlaid on top of one another. The erg monitor already displays single force curves, along with a host of other information, but I want to make interactive logs so that the user can see how consistent their strokes are and how close to an ideal curve they are hitting throughout their session. When I add a graph to show other variables, such as strokes per minute, power and pace over the course of an entire session, the ability to view force curves for any point in time and overlay them should be quite useful.

Python is pretty fun by the way. I recommend giving it a whirl with some small project to see how you like it. There are built in libraries for just about everything, so it's a huge difference from using something like c++, where you have to write everything yourself, or find, download, configure and compile existing ones. I doubt you are going to write God of War in Python, but for little projects where raw performance and the ability to do extremely custom or low-level stuff are not important, it's ideal.

Saturday, January 12, 2013

Python Script to Convert MP4 Video to MP3 Audio

Earlier today, at around midday, I was going to do some exercise, but since I don't like to use my rowing erg without something to listen to, I thought I'd listen to some TED Talks via iPod Touch to Bluetooth headset. Unfortunately, I couldn't get the damned headphones to connect to my laptop, iPod or Nexus 7, though they were detected by all. The Nexus connected, but the playback cut out every few seconds, the iPod connected, but didn't work after that, and my laptop was only able to find my Nexus 7 and not the headphones.

This was really annoying as the headphones used to work fine with my iPod. I don't know what happened, but I expect that the headphones just decided to stop working today for the hell of it, despite them being fine just recently.

So I decided to go old skool and use my ancient iPod Nano instead. Unfortunately, due to my own inability to calmly handle minor problems, the fact I couldn't quickly filter downloaded Podcasts in Banshee from those I had yet to download, made me so angry I started to look for other solutions. That I had downloaded video podcasts in the belief that they were audio only podcasts just made me angrier and I started to find other ways to get audio only TED Talks.

In the end, I got so pissed off that I spent hours writing a Python script to convert the video podcasts into mp3 audio. It took so long partly because I am stupid, but also partly because I spent a lot of that time learning new things in Python and digging through the magnificent Stack Overflow for help.

Here is the script for anyone it might help. Note that you need to have mplayer, lame and python 2.x installed for this script to work.
sudo apt-get install mplayer
sudo apt-get install lame
sudo apt-get install python2.7
Then simply run
python mp4tomp3.py [input_directory [output_directory]]
This will convert all mp4 files in the input directory into an mp3 file in the output directory, ignoring any files that have been previously converted. The input and output directories are optional; Input will default to the current directory and output will default to the same as input.

So now I have a folder full of mp3 audio only TED Talk podcasts. I still don't know how I'm going to get them on my iPod though. There must be something similar to Sharepod available for Linux. I guess finding that is my next task.

I'm never going to buy another fucking iDevice again.

Update: Once I'd converted the videos to mp3s, I imported them into Banshee and from there it was quite trivial to get them onto my iPod. I think the main problem I had was that there was no filter for downloaded files. Also, I discovered that my 3rd generation Nano can play mp4 videos, so I just wasted half a day fucking around wisely spent half a day learning new things.

Sunday, January 6, 2013

Learning Some Python

I was bored last night and for some reason the site Learn Python The Hard Way was open on my laptop. I think I'd found it a while ago, and like most things I find on the net, I thought "this looks interesting. I look at it later and maybe learn some stuff!", pinned the tab and then forgot about it. Last night I was just bored enough to try the first few exercises. Next thing I know, I'm at exercise 32, and well on my way to having a working knowledge of Python!

Also, I managed to finally get my ass on my rowing erg to finally do my first workout of the new year (got to get in shape for naked man festival) and since my body is basically fucked at the moment, I only did 2000m and it took a whopping 7 minutes 45 seconds. Still, I've got time to improve.


So what do rowing and Python have in common? Well, Concept 2, the company that made the erg has logging software that allows you to record your time and lots and lots of other stats such as the force you are applying each stroke, your speed throughout the entire workout etc. Unfortunately, this software is only available for Windows. I have a laptop with Windows XP on it, but it's depressing having to fire up XP just to log some stats, which might explain why I've only ever done it once and completely forgotten all my Concept 2 site login details...

I Googled to see if I could find any software for Linux, but I didn't have much luck. However, I did find this thread on the Concept 2 forums, containing a link to a utility that makes it possible to access data from the erg via the standard USB connection using Python. OMG! New mini project! As if I don't have enough stupid things to distract me from actually finishing any one thing, now I have a new project, and a bit more motivation to keep up with the erg training.

So the past hour or two I've been just playing around getting PyRow and the required USB to Python interface set up using pyusb, and testing it out to make sure it works with my erg. So far it's all good!

Since I was looking at QT5 recently, I am thinking I might see if QT and Python are a good match and try and make a simple logging application for recording my workouts. WxPython (very tasteful site) would be another option worth investigating for making a GUI with graphs and stuff.

By the way, if you want to learn some Python, I can recommend Learn Python The Hard Way. If you have any programming experience whatsoever you should breeze quickly through the exercises, and if you have none, then you are the target audience and it should be a perfect tutorial to get started with. I was also reading through the Python chapter in the recently released Raspberry Pi Education Manual. This manual deals specifically with programming in Python on a Raspberry Pi using IDLE (whatever the fuck that is... The LPTHW guy is constantly saying "Don't use IDLE"), and is aimed at children with little to no programming experience, but it seemed well written and had some entertaining projects such as a simple ski-free style game using PyGame, a simple web server and a section on using the GPIO interface to make real world objects do stuff.

Wednesday, January 2, 2013

A Gameboy Tetris Clone in Javascript

Like many children of the 90s, I had a Gameboy, and like just about everyone else that had a Gameboy, I had a copy of the insanely addictive puzzle game Tetris. The Gameboy version of Tetris was not the original version, but due to its insane popularity and catchy theme tune, a version of which  hit the UK Charts  in 1992*, it remains the one with which most people are familiar.


One of the small projects I worked on last year was to figure out how Tetris worked and write my own version in Javascript. There are already billions of Tetris clones (including this version, which fits into 1k of Javascript), but I didn't care, because like most of the people writing these clones, the purpose was simply for programming practice and fun. Because I remembered the Gameboy version of the game being so damned addictive, and also because it is one of the simplest, with no smooth movement or aftertouch on placed blocks or other recent "enhancements" to the original game, I thought I would try to clone it as closely as possible. This went as far as looking up details on scoring, game speed and other small details on the Tetris wiki, and of course, the dubious practice of ripping as much sound and graphics as possible from screenshots and videos of the game available on the internet.

The Github repository is here. You can play it for yourself by clicking this link (note that it might not load especially quickly).

Although a very simple project to handle, there were a few elements to the project that I found interesting to code, such as the randomiser, which must avoid giving the player the same shape too many times, or not enough of another shape, which are potential problems with selecting a Tetrimono completely at random each time a new one is required.

To solve this problem, I used a simple randomiser that stores all the valid shapes in an array, and an index into the array. Each time a new shape is required, the randomiser just returns the current shape in the array and increments the index. When the index reaches the end of the array, the randomiser randomly reorders the shapes and the index resets to zero. This way, the maximum number of times any shape can appear in a row is  twice - in the case it happens to be the last item in the array, and then the first after the array is reordered. This means that you always know that eventually the straight piece will arrive, but also that you are guaranteed to have an S and a Z for every one of them!


The entire randomiser code is here. Feel free to use it, or any of the other code in your own projects. Note that it's kind of badly written, so you'll probably need to rewrite it to support different sizes and get rid of some of the weird stuff like the way I pass this.bag as an argument to some of the functions instead of just doing var bag = this.bag at the beginning of the function. Have fun!

*Written by Andrew Lloyd Webber under the Pseudonym "Doctor Spin"

Tuesday, January 1, 2013

Happy New Year!

It seems that we made it through 2012 alive. Thankfully, the Mayan long count calendar's lack of support for dates greater than 21st December 2012 did not cause anyone significant harm. Since I am still alive, I thought now would be a great time to start blogging about some of the random stuff I am interested in.

To begin with, however, I'm just going to write up a short list of the things I want to achieve this year.

Do the things I want to do instead of just thinking about doing them. I have many amazing world-changing ideas that are going to make me a billionaire. The only reason I'm not currently blogging from the top of Palmer Tower, which would be built right next to Trump Tower and just slightly higher, in order to block the best views from Donald Trump's offices is that when I have good ideas, I don't try and do anything about them.
Target :  Talk to more people. Spend less time thinking about things and more time doing them. Less giving up. Less self-discouragement. Doing this will ensure I can do anything on this list.

Daily exercise. In preparation for the Saidaiji naked man festival, I need to shake off my Winter fat soon. One might imagine that fat would help keep me warm, but I figure that it's going to be more embarrassing to trot out my mostly naked white arse in the freezing cold if said arse is wobbling more than need be. I also need to make more use of that rowing machine that I bought last year in order to stay in shape in the Winter, that I haven't been using because it's too cold. DOH!
Target : No belly fat and down to overall body weight of 74kg by February. Continue exercise throughout the year.

Finally win the battle against my toe dwelling fungal nemesis. Although athlete's foot is not a particularly troublesome affliction - especially when you have a very mild case, it is bloody annoying, and extremely difficult to get rid of completely.
Target : No fungus by summer.

Finish all the Quake levels I started. I like making Quake levels. I've been doing this as a hobby for about 16 years now, and it helped me get a job in the gaming industry. However, I would like to stop eventually and concentrate on other interests such as programming. I already made some positive steps toward this aim by finishing a level I started a long time ago, and releasing another two that are part of a deathmatch to single-player remake series. However, I still have a lot more work to do, as there are four levels remaining.
Target : Release all remaining DM#RMX maps before the end of June.

Release an Android game. Game programming (for simple games) is not that difficult. I've shown to myself through various home projects in 2012 that I can do it, and I'm doing more programming at work than ever (note, I am a designer/artist normally), so I would like to focus on one simple game project and release it. Don't fuck about reinventing the wheel with tech, even though a lot can be learned this way. Just use Unity!
Target : Release a game sometime in the year.

Other targets: Study more, save more money, buy house (no evil loans), write more about what I'm doing and share things I've learned with others (this blog), do more baking.

Hopefully by writing this blog I'll also get better at writing English, which somewhat embarrassingly, is my native language :)