Sep 15, 2008

Coding Tests in Interviews

I'm reading this Slashdot article about IT professionals being tested on the interview. There seems to be two minds about this, some people hate it and thing that it's disrespectful, others think it is mandatory. What about you?

I'll be honest, I've never been asked to write code in an interview (as far as I can remember). This is probably because either I did so poorly on the pre-code sections that they didn't even want to bother, or I did so well on the pre-code sections that it was just assumed I could code. One company I worked for started giving coding questions after I had started, but I never had to take it (I probably would have mucked up a few questions).

This is a difficult question to ask. The argument Slashdot puts forward is that companies don't ask other professionals these kinds of questions on the interview, so why should they ask IT professionals? It seems fairly disrespectful, they say. If somebody has several years experience, a degree, certifications, etc. it should be a fairly good indication that they can code.

On the other hand, there are a lot of bad coders out there. Some of them even made it through university. Imagine random guy Joe in high school, with excellent interpersonal skills and a passing interest in computers. He hears one day through some survey that graduates of computer science (or a related discipline that has computer or software in its name) get paid a fair bit more than everybody else. He goes to school to study this stuff, picks a school with a relatively easy program, and squeaks through with 50's. He goes off and works for some smallish company for a while doing simple in-house software, doesn't do it too well but they keep him around anyway because as mentioned before, he's a nice guy. He's now got a few years experience under his belt, plus a shiny degree, which can pad up his resume fairly well (it'd probably look better than mine).

Now Joe goes and applies at a new place, hoping for a higher paycheque. What happens if they don't give him code samples? He could probably get in fairly easily. He's got experience, he's got a degree, and he's a nice guy. What more could you want? Well, Joe can't write a program that swaps the values of two variables. Nor can he write FizzBuzz. Yet he gets the job over some new grad hotshot who went through with A's but has no real work experience.

So this is a perfectly good reason as to why companies would give coding tests during interviews. Do I blame them? Not really. However, it does depend on the coding questions. For the company I mentioned above (which happened to be the first job I got out of university), they give a question on CSS, on how to make it so that a box on a web page can have rounded corners, but be able to expand and fit any amount of text. Pretty easy right? I probably wouldn't have gotten it. My CSS skills when I graduated were sadly lacking - I'm still not incredible with it, makes me wonder why I'm a web programmer. I probably would have given some crap with <img> tags relatively positioned a bit, with some IE specific file somewhere. I didn't know about the whole background-image field. Yet it took about 2 minutes looking at how someone else did it for me to be able to replicate it. Some coding tests, from what I've seen, fail to take into account that people are capable of learning.

This is where the 3-month probation period comes in. I think that this time is good enough for both the company and the employee to see if they are a good fit for one another. If the coder sucks, then the company can let them go after the 3 months. If the company sucks, the coder can leave. It's not perfect, but it is a whole lot better than letting the interview alone decide everything.

Sep 14, 2008

Checking out Xubuntu

There's a computer at work that is a little bit slower than my home computer. The CPU isn't much slower, but there's a lot less RAM.

I've noticed that while coding, the system was eating up a lot of memory. A lot of it was coming from GNOME itself, and compiz. So I installed the xubuntu-desktop package and am now trying out XFCE.

It's blazing fast! Runs really well. There are a lot less features than in GNOME which is expected, but everything is very clean.

The one thing that really surprised me is that the default Xubuntu look is a bit cooler than the default Ubuntu look. I kinda liked it and didn't even bother changing it!

So if you have an older PC that you would like to stick Ubuntu on (maybe your grandma's, I know how much Linux users love to do this), the Xubuntu is definitely something worth checking out. Be careful though, I think the system requirements for Windows XP are still lower than Xubuntu, so you might actually be making their computer slower by sticking Linux on it.

On another note, I hate to put ads on my blog, but if anybody knows a good Rubyist in Montreal (or a good web developer willing to learn Ruby), let me know. I'm looking for someone to join my team.

Sep 1, 2008

Rock Band Drums in Linux

I announced some time ago that I had gotten a Wii, and the other day, I finally found Rock Band for it (they released it back in June, but unfortunately they didn't ship it with French manuals so they didn't get it in Quebec at the major retailers, had to go to a smaller game shop to get it).

One thing I noticed about it is that all the instruments are USB devices. So of course, the geek in me wonders, "Hmm, maybe I could hook that up to my computer...". So I tried it. I used the drums, since they're my favourite instrument in the game.

To get Linux to recognize it was simple for me. I just plugged it in. You can try it for yourself, type "lsusb" with the drums plugged in, and when they're not. You should see a line that disappears. I get this:
Bus 002 Device 006: ID 1bad:0005
It doesn't say what it is, but that's no biggie.

UPDATE (Nov. 13, 2008): In Intrepid 64-bit, the joystick no longer works. If you're having problems, click here. Also I've written a follow-up post if you actually want to download something to look at.

Now the hard part is to get it to work with your programs (it's not actually that hard). The funny thing is that the drum kit is actually a joystick, at least as far as the computer knows. In effect, the little D-pad is the joystick and all the drums/buttons/pedal are buttons. So you can use anything that interfaces with a joystick in order to use the drums in your program. I used SDL for this, which is a library for simple access to devices.

In order to use SDL to access your drums, you need a platform that supports SDL. Fortunately SDL is supported on a wide variety of platforms, so you should be OK. For this tutorial I'll be talking about Ubuntu Linux with g++, as that is what I used.
Next, you need a language with bindings to SDL. This is a lot of languages. I used C++, but you could write it in Haskell if you wanted to.

I make no guarantees about the drum kits for other systems like PS3 or XBox 360. I'm using the Wii version. I also don't know if it will give the same values for Windows or Mac OSX (don't see why it wouldn't).

So let's start. We'll do a bit of initialization:
#include <SDL.h>
#include <SDL_mixer.h>
#include <iostream>

using namespace std;

int main(){
if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0){
cout << "Something messed up. :(" <<endl;
exit(1);
}

atexit(SDL_Quit);
What this does is initalizes SDL. We want to initialize the joystick so that we can access the drums, we want to initialize video so we can create a window (for some reason the events were messed up when I didn't have a window) and you'll want sound if you actually want to play sounds with your drums. Then we tell the system to call SDL_Quit when the program exits. This is good to clean up after ourselves.
Note that I include the SDL_mixer library, this makes it a lot easier to play sounds.

Now we want to initialize the joystick. It's really easy. I'm going to skip error checking and assume you only have one joystick plugged in and that it will work the first try. If you have multiple joysticks plugged in (or devices that pretend to be joysticks, like the drums), you can use SDL_NumJoysticks() to see how many you have. Then you can iterate over them and call SDL_JoystickName() to see the name of the joystick. Choose the one that says "Nintendo Wii Drum Kit" or something like that in it.
//here I assume you have the joystick at 0,
//if not replace it with a different number
SDL_Joystick * joystick = SDL_JoystickOpen(0);

//make it so that events are triggered for joysticks
SDL_JoystickEventState(SDL_ENABLE);
Ok, so our joystick is enabled. Let's load some sounds now. You can see the docs for the SDL_mixer functions here if you want to know what they're doing.
Mix_Chunk * sounds[5];
const char * waves[] = {"bass.wav", "crash.wav", "hihat.wav",
"snare.wav", "kick.wav"};

if (Mix_OpenAudio(22050, AUDIO_S16SYS, 2, 4096) != 0){
cout <<"Couldn't open audio device: " <<Mix_GetError()
<<endl;
exit(1);
}

for (int i = 0; i < 5; i++){
sounds[i] = Mix_LoadWAV(waves[i]);

if (sounds[i] == NULL)
cout <<"Loading sound " <<waves[i] <<" failed:"
<<Mix_GetError() <<endl;
}
Here we set 5 sounds to load. This corresponds to the 5 buttons for the drum kit. I put it in an order that I used on the drums once upon a time, but you can do whatever you want. You could even make it beep or quack when you hit one.
We make a call to Mix_OpenAudio(), which initializes the mixer, tells it what frequency we want, how many channels, etc. This lets us make sound.
We then load in all the WAV data into 5 sounds with a call to Mix_LoadWAV().

One last thing to initialize. We need to create a window:
SDL_Surface * window = SDL_SetVideoMode(800, 600, 32, SDL_SWSURFACE);
Done. We have initialized everything, now let's get ready to rock! We need to set up an event handling structure and check for drum events. The way the drums work is it sends a number for each button. The numbers are like this:
0: blue
1: green
2: red
3: yellow
4: foot pedal

There is one catch though. The numbers 0-3 also correspond to the 1, A, B and 2 buttons respectively so to differentiate, the drum kit also sends a 7 every time you hit one of the pads (but not the pedal). So when you hit the blue one, you actually receive two buttons: a 0, then a 7.

We need to do a little magic to keep track of what button was hit. I do this by recording the last button that was hit, and then when a 7 is received, I know that it was a pad and that I should play a sound (unless it was a 4, in which case I don't wait for a 7 after).

Let's set up the event loop:
SDL_Event evt;
bool loop = true;
int last_btn = 0;

while (loop){
if (SDL_PollEvent(&evt)){ //check for event
if (evt.type == SDL_QUIT){
//close button, quit
loop = false;
}else if (evt.type == SDL_JOYBUTTONDOWN){
//joystick button hit, let's play
if (evt.jbutton.button == 7) //pad
Mix_PlayChannel(-1, sounds[last_btn], 0);
else if (evt.jbutton.button == 4) //pedal
Mix_PlayChannel(-1, sounds[4], 0);
else
last_btn = evt.jbutton.button;
}
}
}
In our example, we handle events by polling. There are other ways to do events with SDL, but this is the best way for games in my opinion.
We check to see if there is an event by calling SDL_PollEvent(). If there is, the function returns true and puts the info into our evt structure.
There are only two events we care about, SDL_QUIT and SDL_JOYBUTTONDOWN (we could use the joystick axes events to check to see if people used the D-pad, but we just want to play drums). If we get a quit event, then we just tell the loop to stop going and then go on with it. If it is a joystick button down event, it means someone hit something. We then want to check to see what was hit. If it is a 7, it means we have just hit a pad and the last_btn variable holds whatever pad it was. We make a call to Mix_PlayChannel() to play our WAV file.
If the button was a 4, it was the pedal, so play the pedal sound (which should be at sounds[4]).
Finally, if it was anything else, just store the value and be done with it.

Now we need to clean up:
for (int i = 0; i < 5; i++)
Mix_FreeChunk(sounds[i]);
Mix_CloseAudio();

// remember to use the same number here
// as you did with SDL_JoystickOpen()
SDL_JoystickClose(0);
And we're done! To compile with g++ you use the following command, assuming your code was in drums.cpp:
g++ `pkg-config --libs --cflags sdl` -lSDL_mixer drums.cpp -o drums
Then:
./drums
Now you should get a little black window pop up, and when you have it selected your drums should play sounds (so long as you have the WAV files in the same folder as the executable, you can get some good tracks here).

So yeah, Frets on Fire with drums anyone?

Let me know if you have any questions.

Update Nov. 12, 2008: Intrepid uses a HAL that doesn't use the Wii Drums properly. To fix it, you have to tell X what to do. However, keep in mind that if you don't follow these directions to the letter, you may run into big problems.

First, install the driver:
sudo apt-get install xserver-xorg-input-joystick
Backup your xorg.conf file:
cd /etc/X11
sudo cp xorg.conf xorg.conf.bak
You'll need to see what the kernel is loading your joystick as. Do this:
lshal > before   (with drums not plugged in)
lshal > after (with drums plugged in)
diff before after | grep event
This will output some stuff about the drums. You should see somewhere that it says /dev/input/event6 or something with a different number (event4, event5, etc.). Remember this number.

Next you'll need to make some tweaks to xorg.conf. Type:
gedit xorg.conf
You'll see a bunch of commented out sections, uncomment those (except for the actual comments). Before those add this, replacing event6 with whatever you had above:
Section "ServerFlags"
Option "AutoAddDevices" "False"
EndSection

Section "InputDevice"
Identifier "Configured Joystick"
Driver "joystick"
Option "Device" "/dev/input/event6"
EndSection

If you don't know what you're doing, write the following down on a piece of paper:
sudo cp /etc/X11/xorg.conf.bak /etc/X11/xorg.conf
If you mess up, this will get your system back. If things die and you can't log in, press Ctrl+Alt+F1 to switch to a terminal, log in normally, and type the stuff above. Then restart your computer.

Log out and log in again (assuming all went well) and you should be able to use the drums as a joystick again.

Aug 31, 2008

Afraid of the CLI?

I found myself wondering recently (I wonder how many blogs I've started with a sentence similar to that) about programmers that don't use the command line. I know that outside of the geek world, people really like the point-and-click interface, and don't really know or want to know how to use the command line.

However, then I come to the question at hand. How many programmers are afraid of the command line? It is something that is fairly technical, but as programming itself is something that is also fairly technical, I don't see why a programmer should be afraid of it. Yet I do find programmers who don't know how to use it.

In Rails, I think that the command line is essential. The number of tasks that are done through rake mean that the most efficient way to sort through them all is through command line: just type the command you want rake to do and it does it. No having to dig through GUI screens and all that to find the one you want to do.
Same goes for the generators, by using the command line arguments you can save yourself a bit of typing later on by passing the right things to script/generate.

For web programming in general (I say programming to assert that you are actually programming and not just making HTML/CSS pages) command line is also important for productivity. When dealing with a server, you'll have to check log messages. While you can do this through fancy web interfaces, or by downloading the log files via FTP, the easiest way to do it IMO is through SSH. It's simple:
ssh username@domain.com
cd /path/to/log/file
tail -n 1000 logfile.log (add a -f in there if you want real-time updates)
You can do more magic using grep to find things more specifically what you're looking for.

So why would programmers be afraid of it? My answer is that it has a higher learning curve. You need to know things in order to use it. You need to know what commands to type, and what parameters to send to them. Not knowing how to use things like tail or grep or nano (not that nano is terribly difficult to use, but I can imagine some developers not liking it) can remove the efficiency boost that the command-line provides. Even worse, not knowing about --help/-h conventions or man pages make it even more difficult to figure things out.

I'd say this is another one of those things where taking the time to actually learn it will pay off in the end, but requires you to actually take the time to learn it. And it seems that in the modern computing world, taking time to learn how to use things is a no-no.

Aug 26, 2008

The Illusion of Community

Responding to this article. If you choose to read it, try to read between the lines of the troll-speak. The guy makes a really good point, he just seems to feel the need to say it in a rather immature way.

I'll agree with him that Linux users should stop complaining when other people do things that don't support them (like the Democrats/Olympics using Silverlight). One of the drawbacks of Linux is that there is no support for certain things. If you didn't know this when you chose Linux, you do now. So shut up and accept the fact that Linux is not perfect. Or maybe even try doing something constructive instead of just complaining.

Now to my main point. He says that Linux is not a democracy, it is an anarchy. That is what I think really hits the nail right on the head. Linux is not a united community under the banner of Linux, rather it is a divided battlefield of users flocking under various banners labelled "KDE" or "Emacs" or the like, all of whom will go to great lengths to point out how the others under the same banner of Linux are wrong. And even then, people under the same banner are willing to turn on the group when they decide they don't like where the group is going (this is called "forking"), and then divide the community even further.

Some examples:
I use Ubuntu. I'd probably get called a n00b if I went to a Linux conference.
I use Vim. I'd get shunned by some Emacs users.
I use GVim. I'd probably get shunned by some Vim users. It's graphical, it must be for wussies.
I use NVidia's drivers. I'd get shunned for using proprietary software on my machine.
Yet people like the LinuxHaters author would probably dump me into the category of "Linux user" or "luser" as many of them so eloquently put it. Do I feel like I'm in a community?

Sometimes. There are plenty of great people who are under the banner of Linux. I'd guess they are the majority of people who make up the "Linux community". Yet their voices are all drowned out by the more militant types. I've had plenty of great experiences using Ubuntu forums to get things working, but have seen enough "RTFM" or "winblows/proprietary is teh ghey" to hesitate posting things in there.

One time I mentioned "Ubuntu forums" at the Montreal Linux Users' Group which stemmed a huge rant about how nobody on there knows about what they are talking about (I believe it was called "the blind leading the blind"). I didn't go back to the MLUG. It was not a community, but a group of elitists. That has been my perception of the Linux community.

So if you choose to go with Linux, remember that there are a lot of people out there worth ignoring. Linux itself is a good thing, and the community has it's moments, but I wouldn't list the community as a benefit of using the OS.

Aug 25, 2008

JRuby

Today I've been messing around with JRuby. I meant to check it out a while back, but have been procrastinating, and finally have gotten to it.
For those of you who don't know, JRuby is an implementation of Ruby in the Java Virtual Machine. It can access all the Java core library classes, which is pretty damn sweet.

Here's my setup:
Ubuntu 8.04 64-bit
Athlon X2 6400+
Ruby 1.8.6
JRuby 1.1.4
OpenJDK 6b11

So you may think, "oh, it has access to the Java libraries. So what? Ruby has tons of libraries." Well, Java has more, so it's always beneficial to have access to that.

Here is my main reason though. I made a little script that looks like this:
require 'benchmark'

def pythag(n)
result = []
(2..n).each do |c|
(1..c).each do |b|
a = Math.sqrt(c*c - b*b)
result << [a.to_i, b, c] if a.to_i == a
end
end
result
end

puts Benchmark.measure { pythag(5000); pythag(5000) }
Actually I didn't write it, I stole it off a comment from this article here. But anyway, check this out:
rob@alien:~/Programming/jruby$ ruby benchmark.rb 
40.750000 2.550000 43.300000 ( 43.440552)
rob@alien:~/Programming/jruby$ jruby benchmark.rb
14.920000 0.000000 14.920000 ( 14.919958)
I almost fell out of my chair. JRuby is over twice as fast! I was expecting that they'd be about the same, or JRuby might be a bit faster, but no. Over twice as fast. Damn.

You may notice I called pythag twice. I did this to see if it would make a difference because of JIT-compiling, and it doesn't seem to. Here's the output if I just call it once:
rob@alien:~/Programming/jruby$ ruby benchmark.rb 
19.560000 1.170000 20.730000 ( 20.934664)
rob@alien:~/Programming/jruby$ jruby benchmark.rb
7.999000 0.000000 7.999000 ( 7.998930)
Pretty much half as long.

I'm hoping to start running some other benchmarks. Here's another one I tried:
require 'benchmark'

def load(file)
words = {}
File.open(file, "r") do |f|
f.each_line do |l|
l = l.split(/[\s,\.!\?\"\';:]+/)
l.each do |w|
w = w.downcase
words[w] = (words[w] ? words[w] + 1 : 1)
end
end
end
words
end

puts Benchmark.measure {
words = load("kingJamesBible.txt")

words = words.to_a.sort { |a, b| b[1] <=> a[1] }

for i in 0..10
#puts "%s: %d" % [ words[i][0], words[i][1] ]
end
}
And the results:
rob@alien:~/Programming/jruby$ ruby benchmark2.rb 
2.370000 0.120000 2.490000 ( 2.487271)
rob@alien:~/Programming/jruby$ jruby benchmark2.rb
2.570000 0.000000 2.570000 ( 2.570358)
This time JRuby took longer. Not sure what to think here! Maybe it's fast in certain situations but not so fast in others.

Did you know the words "shall" and "unto" appear more often than "for" or "I"? Weird.

Aug 23, 2008

Installing OGRE on Ubuntu

I've been messing around with this C++ library called Ogre, which is a fancy 3D rendering library. It's great for building cross-platform 3D applications where you don't want to have to worry about a lot of the lower level details of 3D programming.

I found that it was a bit of a pain to install on Ubuntu. You can get the packages in Synaptic, but sometimes they are out of date, or there are a few libraries that work together but different versions are incompatible, etc. So I decided the best option was to roll up my sleeves and compile it on my own.

Here's what you have to do: get CEGUI, Cg and OIS. CEGUI is a widget library designed for 3D applications. It's not required for OGRE, but I think it is definitely a good thing to have. OIS is an input system, you use it to interact with the keyboard/mouse/joystick/etc. You can also use SDL for this, but SDL comes with a whole lot of other stuff that you may or may not need. Cg is Nvidia's shader language, from what I've gathered the Ogre guys highly recommend it.
You'll have to compile these guys from source, using the old ./configure + make + make install routine. No big deal. If there is no configure file, then use ./bootstrap first.
One problem with using CEGUI from the Ubuntu repositories is that it is set to use the Xerces XML parsing library. Unfortunately for some reason there are some issues with this, so you have to compile CEGUI yourself and tell it not to use Xerces. It'll probably default to Expat (another XML parsing library) which works well. Use this line instead of the normal ./configure:
./configure --disable-xerces-c
and off you go. OIS should install without any problems, as should Ogre. Cg doesn't even need to compile, you just copy the tarball to the root directory and extract it.

Once you've got everything installed, you might have some issues getting things to compile. Type this:
pkg-config --cflags OGRE OIS CEGUI
It should output something like this:
-DOGRE_GUI_gtk -DOGRE_CONFIG_LITTLE_ENDIAN -I/usr/local/include
-I/usr/local/include/OGRE -I/usr/local/include/OIS
-I/usr/local/include/CEGUI
These are the include paths to the libraries you just installed, and you'll need to use those flags when you compile your OGRE program. So when you create your makefile, put
CXXFLAGS = `pkg-config --cflags OGRE OIS CEGUI`
LFLAGS = `pkg-config --libs OGRE OIS CEGUI` -lCEGUIOgreRenderer
You have to put the -lCEGUIOgreRenderer if you're using CEGUI, it's the way Ogre and CEGUI communicate with one another.

One final hiccup is that Ubuntu doesn't know where to look for the shared object (.so) files once you've gotten your program to compile. They are in /usr/local/lib, but Ubuntu normally puts things in /usr/lib. So you have to edit /etc/ld.so.conf file and add the line:
/usr/local/lib
at the end. You only need to do this if you have issues with your Ogre app loading the shared objects.

And finally, you need to tell Ogre where to find the plugins. In your plugins.cfg file in the folder where your Ogre app is, make sure that the PluginFolder value is set to /usr/local/lib/OGRE.

Once you have all this going, there are some very well-written tutorials on the Ogre wiki. You should have some good stuff up and running in no time!