How To: Convert Day Number to Month and Day

I needed to convert the day number, that is, what day it is between 1 and 365, into a month and day without using Calendar / DateTime classes and such today, so I knocked up a few simple functions that work assuming it’s not a leap year (i.e. that February has 28 days).

Here they are if they’re of any use to you:

int dateToDayNumber(int month, int day)
{
	// Catch invalid input and return early
	if (month < 1 || month > 12 || day < 1 || day > 31) return 0;
 
	if (month == 1 ) return       day;
	if (month == 2 ) return 31  + day;
	if (month == 3 ) return 59  + day;
	if (month == 4 ) return 90  + day;
	if (month == 5 ) return 120 + day;
	if (month == 6 ) return 151 + day;
	if (month == 7 ) return 181 + day;
	if (month == 8 ) return 212 + day;
	if (month == 9 ) return 243 + day;
	if (month == 10) return 273 + day;
	if (month == 11) return 304 + day;
	return 334 + day;
}
 
int dayNumberToMonth(int dayNumber)
{
	// Catch invalid input and return early
	if (dayNumber < 1 || dayNumber > 365) return 0;
 
	if (dayNumber <= 31 ) return 1;  // Jan
	if (dayNumber <= 59 ) return 2;  // Feb
	if (dayNumber <= 90 ) return 3;  // Mar
	if (dayNumber <= 120) return 4;  // Apr
	if (dayNumber <= 151) return 5;  // May
	if (dayNumber <= 181) return 6;  // Jun
	if (dayNumber <= 212) return 7;  // Jul
	if (dayNumber <= 243) return 8;  // Aug
	if (dayNumber <= 273) return 9;  // Sep
	if (dayNumber <= 304) return 10; // Oct
	if (dayNumber <= 334) return 11; // Nov
	return 12;                       // Dec
}
 
int dayNumberToDayOfMonth(int dayNumber)
{
	// Catch invalid input and return early
	if (dayNumber < 1 || dayNumber > 365) return 0;
 
	if (dayNumber <= 31 ) return dayNumber;       // Jan
	if (dayNumber <= 59 ) return dayNumber - 31;  // Feb
	if (dayNumber <= 90 ) return dayNumber - 59;  // Mar
	if (dayNumber <= 120) return dayNumber - 90;  // Apr
	if (dayNumber <= 151) return dayNumber - 120; // May
	if (dayNumber <= 181) return dayNumber - 151; // Jun
	if (dayNumber <= 212) return dayNumber - 181; // Jul
	if (dayNumber <= 243) return dayNumber - 212; // Aug
	if (dayNumber <= 273) return dayNumber - 243; // Sep
	if (dayNumber <= 304) return dayNumber - 273; // Oct
	if (dayNumber <= 334) return dayNumber - 304; // Nov
	return dayNumber - 334;                       // Dec
}

A touch cheap, but it gets the job done.

The Caliko Inverse Kinematics Library

After around 18 months of work, I’ve finally submitted my first research paper today to the Journal of Open Research Software in the form of a software meta-paper. While the paper outlines what the library is and does, the real crux of the submission is the creation of the Caliko library itself as a ‘software artifact’.

I can’t do anything with the paper until it’s either accepted or rejected (hopefully the former!) – but if you’d like to see what the library is and does – then this video should explain things quite nicely:

And if you’d like to give the whole thing a spin, then it’s merely a click away at:
https://github.com/feduni/caliko

One down, five to go.

Onwards!

Oracle Java Certfication

I passed my 1Z0-803 Java SE 7 Programmer I exam the other day – and it was without doubt the hardest exam I’ve ever taken by a country mile.

The entire thing’s made of trick-questions, corner-cases and large ‘human-compiler’ questions which have you substituting multiple pieces of borderline-legal nonsensical code into large swathes of horribly structured and badly laid out code to mentally determine which ones result in a given set of output. Horrific.

Also, on top of having to race your way through 70 questions in two hours, there are an undisclosed number of “non-assessed questions” which don’t count towards your score – the only possible reason for these I can think of is to burn the clock and artificially inflate the fail rate, thus scoring Oracle ~$300 a pop on resits for people who need an Oracle cert for their work. What a complete and utter rort.

Java-Cert2

Nailed it – but the only way I’d ever do another Oracle certification would be if there was something big like a specific job riding on it. And even then I’d think twice about whether it’d be worth the grief.

Final rating: 0 out of 5 Rubber Chickens. Avoid like leprosy.

How to: Get Minecraft working in Linux

Minecraft Wallpaper

Attempt a quickfix?

If you’re trying to run Minecraft in Linux and it’s failing with errors like:

wrong ELF class: ELFCLASS32 (Possible cause: architecture word width mismatch)

or

Could not find the main class: net.minecraft.Launcher.Frame

Then the chances are you can fix it up by performing the following actions:

  • Set your LD_LIBRARY_PATH variable with:
    export LD_LIBRARY_PATH="the-correct-path-to-your-JRE-java-binary-which-is-NOT-usr/bin"
  • (if needs be) Get rid of OpenJDK and install the official Sun/Oracle Java binaries if required.

Know how do all that? Awesome – carry on! Not so sure? Read on! ;-D

Setting the correct JRE location

First up, check if you have Java installed by typing java -version, if it comes up with something like the below, then you’re got Java installed, now we just need to find out where:

java version "1.7.0_07"
Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
Java HotSpot(TM) 64-Bit Server VM (build 23.3-b01, mixed mode)

If you didn’t get anything similar to the above you might want to install the official Oracle Java implementation, which I put together a brief step-by-step for here.

Assuming you have some variety of the Java Virtual Machine (JVM) install, check if your LD_LIBRARY_PATH environment variable is set with:

printenv | grep LIBRARY

If it comes up empty, then we need to find out where Java’s installed and set it correctly. To get the correct path for where your particular Java install is located, you might be tempted to try running which java:

$ which java
/usr/bin/java

However, this is a little bit of a fib, as Java is part of the alternatives setup where we can have multiple versions installed at once – which means that /usr/bin/java is really a symbolic link to the true java location. To find where it’s really pointing we can either ask update-alternatives how it’s configured like so (and pick a version different version if we want to):

$ update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).
 
  Selection    Path                               Priority   Status
------------------------------------------------------------
  0            /usr/bin/gij-4.6                    1046      auto mode
  1            /usr/bin/gij-4.6                    1046      manual mode
* 2            /usr/lib/jvm/jdk1.7.0_07/bin/java   1         manual mode
 
Press enter to keep the current choice[*], or type selection number: 2

Or we can look closely at the /usr/bin/java symlink:

$ ls -alh /usr/bin/java
lrwxrwxrwx 1 root root 22 Aug 15 05:03 /usr/bin/java -> /etc/alternatives/java

Which if we then look closely at /etc/alternatives/java then points at:

ls -alh /etc/alternatives/java
lrwxrwxrwx 1 root root 33 Aug 15 16:37 /etc/alternatives/java -> /usr/lib/jvm/jdk1.7.0_07/bin/java

Same thing as what the alternatives config’s pointing at ;-)

Now that we have the correct path, we can set it in the following manner (remember to substitute your particular Java location into the below lines!):

For 64-bit Linux:

export LD_LIBRARY_PATH="/usr/lib/jvm/jdk1.7.0_07/jre/lib/amd64"

For 32-bit Linux:

export LD_LIBRARY_PATH="/usr/lib/jvm/jdk1.7.0_07/jre/lib/i386"

With that done, you should be able to see that it’s set by running:

printenv | grep LIBRARY

Which should give you something like:

$ printenv | grep LIBRARY
LD_LIBRARY_PATH=/usr/lib/jvm/jdk1.7.0_07/jre/lib/amd64

Finally, we should be fit to launch Minecraft like this (assuming the minecraft.jar file is in your home folder):

java -Xmx1024M -Xms512M -cp ~/minecraft.jar net.minecraft.LauncherFrame

Or, without setting the memory and classpath variables, like this:

java -jar ~/minecraft.jar

Be aware that the LD_LIBRARY path will only be set for the current session of the current shell, so you’ll have to re-set it a lot. A quick and easy way to do this is to just knock together a quick launcher script as below (substituting your paths in) and throw it in /usr/local/bin:

minecraft.sh

#!/bin/bash
export LD_LIBRARY_PATH="/usr/lib/jvm/jdk1.7.0_07/jre/lib/amd64"
java -Xmx1024M -Xms512M -cp ~/Games/Minecraft/minecraft.jar net.minecraft.LauncherFrame

Final Notes

Not being able to set a persistent LD_LIBRARY_PATH is a pain, because it won’t take if set in the ~/.profile or ~/.bash_profile or ~/.bash_rc config files (I’m not so sure about ~/.pam_environment) – which you can read about here: https://help.ubuntu.com/community/EnvironmentVariables.

There’s a fix which involves disabling ssh-agent in this bug report (see post #21 here), but really for the sake of a two line launcher script I think it’s best to just leave it be.

Happy mining and crafting! =D

How To: Install the official Oracle JRE/JDK in Linux

Installing the official Sun/Oracle Java implementations used to be as easy as installing sun-java6-* and uninstalling all the OpenJDK and IcedTea (Java plugins based on OpenJDK) packages you could find – but you can’t get the offical “Sun” packages anymore, instead you have to go get the binaries from Oracle (who bought Sun Microsystems). You can take a swiz at the possible Java implementations here if you like.

Anyways, to get and install the official JRE or JDK (I’ll assume that most people aren’t going to be developing in Java so only want the Runtime Environment and not the full Development Kit):

  1. Head on over to: http://www.oracle.com/technetwork/java/javase/downloads/index.html and download tar.gz version of the latest JRE, which at the time of writing is 1.7 update 7 (i.e. 1.7.0_07, the Linux 64-bit version of which is called jre-7u7-linux-x64.tar.gz),
  2. Extract the downloaded archive through any way you see fit. I’ll assume you downloaded it to your Downloads folder and extracted it there for the following commands,
  3. Create a new folder for it wherever your distro likes to put Java installs, for example:
    sudo mkdir /usr/lib/jvm/jre1.7.0_07
  4. Move your extracted JRE to that location using:
    sudo mv ~/Downloads/jre7_u7/* /usr/lib/jvm/jre1.7.0_07/
  5. Update your alternatives to prefer the new version of java by running (one line at a time):
    sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jre1.7.0_07/bin/java" 1
    sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jre1.7.0_07/bin/javaws" 1

    If you’re installing the JDK you’ll prolly want to set the javac (Java Compiler) binary to the new version too using:

    sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jre1.7.0_07/bin/javac" 1

    The number at the end of the line is the priority of this binary out of any other java/javac/javaws binaries alternatives knows about, and goes from 1 (most important – try to use first) to 100 (least important – use only as a last resort)

  6. To make sure that the update-alternatives commands take, you can also run (again, one line at a time):
    sudo update-alternatives --config java
    sudo update-alternatives --config javaws
    sudo update-alternatives --config javac     <-- only if you installed the JDK
  7. Finally, to check it all really took, issue:
    java -version

    and you should see some output showing that the newest version of Java is in effect, like this:

    java version "1.7.0_07"
    Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
    Java HotSpot(TM) 64-Bit Server VM (build 23.3-b01, mixed mode)

Done & dusted.