Dec 22, 2009

Qt

It's been a while since I did any GUI development, but these days I've been working on a little project for a friend of mine. I decided to check out Qt, which is the main GUI library used for KDE applications. It's one of the main GUI toolkits for Linux apps that I still hadn't tried and cared to try (I haven't tried Tk, but I'm not really interested in trying it because of aesthetic reasons).

After a while of working with Qt, I have to give it two thumbs up!
Here's some of the highlights:
- "Garbage Collection" - it's not real garbage collection as far as I know, but the memory for GUI widgets is managed within Qt, so you don't have to worry about deleting them. It isn't full garbage collection because you still have to clean up your other stuff, but it's a nice to have.
- The meta-object system. Qt doesn't actually use real C++, it uses a slightly extended version which it converts to standard C++, and then compiles. This gives it the really nice messaging system that it has called slots and signals. A signal is a method that you don't define yourself, you just define a section in your class called signals:
class MyWidget : public QWidget {
...
signals:
void opened();
void closed();
At some point during your program you can emit a signal like this:
emit opened();
This makes your object send out the opened() signal to anyone who cares to listen.
How do you listen then? You use a slot. A slot is just like a regular method, except you can attach a slot to a signal. For example, a button in an app would send out the clicked() signal when you click on it:
connect(myButton, SIGNAL(clicked()), this, SLOT(myButtonPushed()))
This line would make it so that whenever myButton's clicked() signal is sent, the myButtonPushed() method on whoever "this" is would be called. You can even connect signals to other signals, so that when one signal goes off, it triggers another signal. This is handy for creating widgets that have subwidgets, but you don't want to reveal the subwidgets to other classes.
- The tools - You'd think that if there is this meta-compiler that has to run before the C++ compiler, the Makefiles for Qt would be nasty. And they probably are. However Qt provides you with a Makefile-generator so that you don't actually have to touch the darn things. You just go:
qmake -project && qmake
Running this from your code folder sets up a Makefile for your project so that you don't have to.
There is also an IDE for Qt development called Qt Creator. I haven't tried it because I'm not quite ready to stop using Vim, although supposedly Qt Creator has a Vim-mode so it might be interesting to try...unfortunately though it seems that to build Qt Creator you need Qt 4.6, which is not available in the Ubuntu repos just yet. Darn. Oh well, you can just use the qtcreator package. I'll try this out and let you know what happens.
- Aesthetics - the default widgets in Qt are appealing. They don't look like blocks, the fonts are well rendered, and animations are subtle/smooth. I know many developers don't actually care about aesthetics, but I do and this is a big win for me since I'm not very good at making things pretty myself.
- Cross-platform - my code can compile under Windows just fine, and supposedly under Mac as well. In fact Nokia advertises that it can run on Symbian as well, not that I need that very much.
- Cross-language - I'm using C++ for this, but you can write Qt apps in Java (and therefore any JVM language like Scala and JRuby) and Ruby, and probably more but I haven't bothered to check others.

So yeah, if you have the need to write a GUI-based app, give Qt a shot. It sure beats then hell out of GTK!

Dec 14, 2009

GIMP - White Face Outline

A couple people asked me how I created the picture for my current Facebook profile, which looks something like this:


I did it with the GIMP, and it was actually really easy. There's a few steps to follow:
1) Open up your picture in the GIMP (this is an easy step)
2) Go to Filters -> Edge-Detect -> Sobel - I use this one because it generates a lot less noise than the other ones, and it is mostly black and white. The issue is that some features which should be brighter aren't, like lips. You can experiment with some of the other Edge-Detect filters they have in there if you like.
3) Go to Colours -> Threshold. Drag the little arrow around in the histogram (which will appear on a dialog called "Threshold") until you get something you like. At this point as I mentioned in the last step certain features might not stand out, so you might have to do some tinkering with a white pencil to get those features to stand out a bit more (unfortunately I'm not an amazing artist, so the lips in that picture above look kinda wonky).
4) Remove noise. You can do this with the pencil tool to draw black over the noise, or you can use the select tool(s) to select and delete stuff (make sure to set your background colour to black). Do this until you have removed the stuff you don't want.

And tada! You should have an image that looks something like the one above.

Dec 12, 2009

Resetting Your Keyring

For those of you who have forgotten your keyring password and are annoyed at the apps like Empathy and Ubuntu one who insist on using it, you can reset it by deleting your keyrings folder:
1) Go to your Home Folder
2) In the address bar type ~/.gnome2/ (if you don't see the address bar, click the little icon with the paper and pencil that has a tooltip like "Toggle between ...")
3) Delete the folder called keyrings

Next time you run a program that wants to use the keyring you will be asked to type a password. This password doesn't have to be the same as your regular password.

If you are comfortable with a terminal, the command is:
rm -r ~/.gnome2/keyrings

Dec 10, 2009

Folder Bar in Nautilus

I just learned something today. If you go into Nautilus (the file browser for Ubuntu), you can see on the left there is a bar with your home folder, Desktop, Trash, etc. on it. Below that are a list of folders, probably Documents, Music, Ubuntu One (if you're running Karmic). You can drag and drop folders onto that list in order to access them quicker! The random little things you discover.

Dec 8, 2009

Computer Science vs. Economics For Me

A question people have asked me many times is why I went from Computer Science to Economics (although I'll note here that I actually did finish the CS degree instead of just transferring). It's a valid question, and I figure I'll answer it here.

Update: For those of you who are double-majoring in Computer Science and Economics, stay with it! If you go into an economics-oriented field, your computer skills will set you far apart from the hordes of computer-illiterate economics majors that graduate each year.
For those of you only studying economics, the best piece of advice for you is this: learn to use computers. And go beyond Excel, learn something sophisticated like SQL or R which are much more powerful.

And now, back to the article:
Here are my reasons:
1) While I like programming and working with computers, I found that working with them 40+ hours per week drained my enthusiasm for playing around in the off-hours. I would get home from work and not want to go anywhere near code. It was depressing. Now, even after doing stats and math all day long, I have no problem writing code at night when I'm done studying. So therefore I have decided that I would like to keep coding as a hobby, and do something else to earn a living.

2) More of the people I care about are interested in Economics, so they actually want to hear what I have to say about it (which isn't all that much right now, strangely enough). Some of my friends do care about computer stuff, in fact some of them even read this blog (hey guys! *waves*) but the vast majority of my friends and family don't really care too much about programming, computer science, Linux, etc. It's not that it isn't relevant to them, most of them find computers useful in some form or another, but when you compare questions like "why did I get a virus?" to questions like "why did I get laid off?" or "why did my investment portfolio bomb?" there is a much higher level of interest in the latter two. It's also a question of respect, I suspect that economists get a slightly higher level of respect than do programmers (although these days maybe not!).

3) I feel I can make a bigger contribution to the economic world than the computer world. It seems to me like a lot of the people doing things at the top in economics are just wanking around with math and saying that it reflects reality. I think it would be interesting to see what happens when you throw in more computer simulations using AI, or start wondering what happens when you mix computational complexity with game theory. For example, existence/uniqueness of equilibria matter and all, but the ability for a decision-maker/market to find said equilibria in a timely manner matters too.

4) The computer industry is governed more by economics than computer science (technology/computer science does play a fair-sized part mind you, just the part played by economics seems to be bigger). Why is Microsoft so big? Why is Java so popular? The answers to these questions are answered by economics as much as by technology.

Second Update (2015-06-18): It's been 6 years since I wrote this article, and probably 5 or so since that last update. That's enough time for some adventure and experience, which I'll share it here. I did a Master's in Economics, and worked in a number of different jobs: algorithmic trading, a successful Internet marketing startup, my own video game startup (briefly), and I'm now working at YouTube in San Francisco. This adventure is not over - I'm not even 30 years old. I know that in a few years if I decide to leave the Bay Area, I can go pretty much anywhere and not have to worry too much about finding work. There are very few disciplines that can boast this, but computer science is one of them. So here are some reasons why I am back in the tech world:

1) The jobs pay better. A good economist knows that utility increases with income, and therefore the rational choice between the two is to go into technology.

2) The jobs are more diverse. With economics you pretty much have two choices: a large financial institution, or a government. Unless you've built up some other skills elsewhere (business savvy, tech skills, social skills, entrepreneurship) then you've got limited options. With tech, you can do anything, anywhere. Software touches nearly every industry on the planet from farming to physics, and they are all looking for people who know how to make the computer do what they want.

3) It's easy to go from tech to economics; the reverse is not true. It wasn't very hard for me to get accepted to my Master's program in economics simply because I have an engineering background. Since graduate economics is all math and computers anyway, you're actually better off than the people who did their undergraduate degree in econ.

So while I found economics interesting, the only reason I would recommend that someone take economics over computer science is if they really liked economics and really didn't like computer science. Otherwise I'd suggest a major in computer science with either a minor or a double-major in economics.

Dec 4, 2009

Evaluate an expression in Vim

There might be a case when you need to write an expression and don't feel like calculating it yourself. If you're using Vim, then from insert mode you can hit Ctrl+R and then =, and you will then be able to type an expression to be evaluated. So suppose you hit:
<Ctrl+R>=5+2<Enter>
it will type out 7 for you. You can even do more advanced equations like:
cos(3.14159/2)
Unfortunately it is a bit limited, you can't do powers or logs. But it is handy for simple arithmetic.

Dec 3, 2009

Infinite Lists in Scala

One of the pretty cool things about Haskell is the ability to have infinite lists, thanks to Haskell's laziness. You can create a list containing all the Fibonacci numbers, or all the digits of π, or something like that.

Turns out that Scala can do it too, despite not being a lazy language. The main way to do it is with the lazy keyword:
lazy val hello = epicCalculation()

if (some condition){
println(hello) // epicCalculation() is done here
}else{
// don't use hello
// in this execution path, epicCalculation is never called
}
Here we're creating a constant variable called hello and only using it in one of our if branches. That means that if execution never goes into our if block, then the epic calculation is never computed. Pretty handy sometimes! This example isn't great because we can just call epicCalculation inside the if block, but whatever.
Unfortunately one catch is that the variable is evaluated when you pass it to another function, regardless of whether it is used or not:
object Main{
def getValue = {
println("getting value")
5
}
def output(y : Any) = {
println("outputting")
}
def main(args : Array[String]){
lazy val x = getValue
output(x)
}
}
Even though the variable y is not actually used inside output(), the value of x is still evaluated. So it isn't true laziness, but whatever.

We can also build infinite lists using the Stream class. Here's an example of generating a familiar list of numbers (I'd use Fibonacci but it is a bit more complex since each element depends on two previous elements instead of one):

object InfLists extends Application{
def numbers(current : Int) : Stream[Int] =
Stream.cons(current, numbers(current * 2))

// print out 10 numbers, starting with 1
numbers(1).take(10).foreach(println)
}
Yet again another trivial example, but it is kinda neat to be able to do this.

Note that the following does not work:
println(numbers(1) take 10)
Why not? Well here, we're not actually evaluating the values for the first 10 numbers. So when println goes to print the list, it just prints the first element followed by a ?, because it doesn't know what the rest of the list is.

Now if you actually want the Fibonacci series, you can do it like this:
Stream.cons(1, Stream.cons(1, fib.zip(fib.tail).map(f => f._1 + f._2)))
Swiped from here, converted to Scala. If you zip something with its tail, then you get a list of pairs that look like this: (ai, ai + 1). Then if you map that using +, you'll get your result.

Dec 1, 2009

CUSEC 2010

I'm fairly certain that anybody actually reading this blog and is able to go to this is already planning on going, but in the odd case that you are not I would highly recommend you check out CUSEC 2010 if you are at all interested in software development. I've been going for the last few years and it has been quite interesting each time. They've always had some great speakers including Tim Bray, Richard Stallman, Joey Devilla and Zed Shaw who usually give quite informative and inspiring talks.
This year the lineup is equally interesting, with folks like Reg Braithwaite and Matt Knox (guy who wrote some adware in Scheme, read article here).

So if you're interested in this kind of thing, are within reasonable travel distance from Montreal, and can handle the Canadian winter, feel free to come on out this January. The tickets are only $60 for students or $150 for non-students, which is ridiculously cheap when it comes to conferences. Plus Montreal is pretty sweet, so you'd definitely be having a good time.