The Little Things in Life Rock

Nathan Weizenbaum was helping me with a few issues in a pet project I’m working on.

In the process, I ended up learning a really neat trick that Ruby can do.

To give you a bit of background, I’m working on a GTK Tray Icon. To make a menu spawn upon right-clicking the tray icon, you’d expect to see something like this:

require 'gtk2'

class TrayIcon
  def initialize
    trayicon = Gtk::StatusIcon.new
    trayicon.set_icon_name('folder')
    trayicon.set_tooltip('My Tray Icon')
    trayicon.signal_connect('popup-menu') { |button, activate_time| on_right_click(button, activate_time) }
  end

  def on_right_click(status_icon, button, activate_time)
    rc_menu = Gtk::Menu.new

    exit = Gtk::ImageMenuItem.new('Quit')
    exit_image = Gtk::Image.new(Gtk::Stock::QUIT, Gtk::IconSize::MENU)
    exit.set_image(exit_image)
    exit.signal_connect('activate') { Gtk.main_quit }
    rc_menu.append(exit)

    rc_menu.show_all
    rc_menu.popup(nil, nil, button, activate_time)
  end
end

But, the line 8th line (trayicon.signal_connect …) is a bit unwieldy. The thing is, we need those arguments to be passed for everything to work. And that’s where Ruby’s Proc handling comes in to save me. The same line can be re-written, and work, using the following line instead:

trayicon.signal_connect('popup-menu', &method(:on_right_click))

Banshee Plugin for Xchat

I’ve been working on a wide variety of projects lately, so when I got some spare time today, I did something for myself.

As such, I’ve done a complete rewrite of the Banshee plugin for Xchat. It’s stable and shouldn’t have any bugs. Works great on this end. The code itself is improved as well. πŸ™‚

You can nab a copy here.

Ubuntu: The First Distro to Ship Compiz-Fusion by Default

As of the Tribe 2 release, due to the awesome work on the part of Michael Vogt (mvo) and Travis Watkins (Amaranth), Compiz 0.5.1 git and the Compiz-Fusion main plugins are not just a part of the default installation of Ubuntu, but enabled by Default, even on the LiveCD.

Of course, it’s only enabled for supported hardware devices, so for you folks that can’t run Compiz, you’ll be greeted by Metacity as always.

The rest of the Compiz-Fusion stuff is also in the universe repository, so feel free to pick it up by running the following command:

sudo apt-get install compiz-fusion-plugins-extra compizconfig-settings-manager

Keep in mind, Gutsy is alpha software and isn’t recommended for use on your desktop, however, if you’re feeling gutsy, it’s a fun experience. πŸ˜‰

Some Neat Stuff

I’ve been anxiously awaiting the release of SLED 10’s Service Pack 1 for a few small items: Gnome Main Menu 0.9.8, updated Gilouche theme, etc.

Finally, on the 18th, after way-too-long a wait, they put it out.

Since then I’ve compiled and configured a few things, while a couple more are being put off for a little bit (namely the international clock – which requires rebuilding the whole of gnome-panel).

Here’s a shot of Gnome Main Menu 0.9.8, with the updated Gilouche theme, to give you just a taste of some of the neat things that should start making their way upstream.

Adobe Really Does Love Us!

In addition to this week’s announcement about a particularly awesome little beta release of Flash 9 Update, which features all sorts of treats such as native GTK support and fullscreen use, Adobe has gone one step further in easing adoption of Flash on Linux: particularly for PCLinuxOS, openSUSE, and Fedora users.

As of yesterday, Adobe now sports its own, maintained YUM repository for Flash. πŸ˜€

In order to install Flash, just run the following:

wget http://linuxdownload.adobe.com/adobe-release/adobe-release-1.0-0.noarch.rpm -O ~/adobe-release-1.0-0.noarch.rpm
su -c "rpm -Uvh adobe-release-1.0-0.noarch.rpm" root
su -c "yum install -y flash-plugin" root

Remember to restart any web browsers after installing Flash!

With Net Censorship on

With net censorship on the rise, it is the responsibility and the privilege of those we can speak to speak for those who are repressed.

That said, I encourage each and every one of you who value your ability to spread information and have privacy and freedom on the Internet please visit Irrepressible.info (a sub-site of Amnesty International) and add your name to the list of those who refuse to let their freedoms be systematically robbed from them.

Gustav Holst is Pretty Much My Hero

Ever now and again I have these bursts where I have an extreme affinity for either a particular composer or piece.

Currently, the lucky piece (and man!) is Gustav Holst’s “Second Suite in F”. I just love it – most especially the second movement. πŸ˜€

Adventures with Scribble!: Nothing Quite Like Playtime

I was feeling a little bored, so I opened up Scribble! (after a brief svn update) and decided to play around some.

I ended up making the RGB circle:

screenshot.png

While it obviously doesn’t blend to create that insanely cool effect, it looks cool anyway. πŸ˜€

During the process of this, however, something struck me… unless you’ve played with graphics before, none of the “average Joe Sixpack” users that Scribble! is designed for know the golden rule of computer graphics!

When you’re working with graphics on a computer, there’s a little “rule” that you operate under. The point of origin is the top left corner of the screen. There are of course many reasons for this, none of which I’ll trouble you with, but, to keep things brief, if you were to draw up a simple grid with X and Y axes, as far as computer graphics are concerned, you’re dealing with the IV (4th) quadrant.

Now that we’ve established that, looking at Scribble!’s code is easy.

size(360,300)
brush.stroke = 0, 0, 0, 0.7

This code establishes the two traits of the Scribble we’re working on before we start any drawing. We’ve set the size to 360 pixels wide and 300 pixels tall. Then we’ve set the stroke of the brush (don’t forget – this is still Ruby and method act on objects, in this case, the stroke is acting on the brush) to be black using RGB values (0 red, 0 green, and 0 blue is the combination for black) and have an opacity of 70%.

brush.fill = 1, 0, 1, 0.5
circle :center => [130,170], :radius => 75

Now, we begin by setting the color of our brush to Magenta (1 red, 0 green, 1 blue) and set its opacity to 50%. This next portion is a little bit trickier in terms of syntax, but it’s relatively simple to read. We’re creating a circle with a center point 130 pixels to the right of the origin and 170 pixels down from the origin. If we compared this to the coordinate sheet we envisioned earlier, our center point is at (130, -170). The next bit, the radius, is set to 75. Simple, no? The rest of the script is just placing two more circles of different colors on other parts of our canvas.

If you’ve got any interesting Scribbles you want to share, please comment! πŸ™‚

Adventures with Scribble!: The Basics of Basics

Scribble! has been undergoing many changes lately to prepare for the mystical and (at least in my case) anticipated 0.1 release.

But the important thing to remember about Scribble!, is that, just like Hackety Hack, its goal is to teach people how to program without breaking out the boring lectures about “Hey this is syntax. Do it.” It’s a tool for beginners to learn a little bit about graphics using Cairo and Ruby to have a little fun and expand their knowledge.

So, you ask me, how does Scribble! do it?

Pretend we take the following code and drop it into Scribble!:

#Set Canvas Size to 500x500!
size(500,500)
brush.fill = 0, 0, 0.9, 0.04 #Uses standard "Red, Green, Blue, Opacity" values
brush.stroke = 0, 0, 0, 0.1 #Same as above

#I like circles too! ^_^
30.times do
  circle :center => [rand(size[0]), rand(size[1])], :radius => (rand(size[0]) - 150)
end

#Draw a cool spiral thing that Evan Farrar came up with. B)
scribble(250,250) do |s|
  s.curve 250, 300
  s.curve 300, 250
  s.curve 250, 200
  s.curve 200, 250
  s.curve 250, 350
  s.curve 350, 250
  s.curve 250, 150
  s.curve 150, 250
  s.curve 250, 400
end

## And to top it off, a blue smiley face over everything!
scribble(100, 10) do |s|
  s.line(100, 60)
  s.jump(150, 10)
  s.line(150, 60)
  s.jump(80, 70)
  s.curve(125, 90)
  s.curve(170, 70)
end

The code is, of course, a little commented (mainly because I’m a nice guy, <3), so it shouldn’t take too much explanation. In fact, once you look at the image below, it shouldn’t take any at all!

Scribble! here, Scribble! there…. hell Scribble! everywhere!

So, I encourage you to go pick up Scribble from SVN and play around some:
svn co svn://hamptoncatlin.com/scribble/trunk scribble

To run it, cd to ‘/path/to/scribble’ and run ‘bin/scribble’. If you come up with anything neat, share it with me!

Fun Maths in Ruby

There’s a buddy of mine who I chat with frequently on AIM by the name of Josh, and well, one of our favorite activities (besides endless political debates and what-not) is essentially a giant pissing contest between Ruby and Python.

Josh is your typical die-hard Python fan. In his mind, there really isn’t anything that can compare.

Naturally, it’s only my God-given duty to show him how and why I prefer Ruby. πŸ˜‰

One of our recent contests involved the matter of a simple task: mathematically, find and print all numbers between 1 and 100, designating which were divisible by 3, 5, or both. He was the first one to write any code, and here’s what he came up with:

i=1
while i<=100:
    if i%15==0:
        print("%s is divisible by 3 and 5" % i)
    elif i%3==0:
        print("%s is divisible by 3" % i)
    elif i%5==0:
        print("%s is divisible by 5" % i)
    else:
        print i
    i=i+1

Fairly simple, right? Here’s my first iteration, which is basically a mirror of Josh’s code in Ruby:

i = 1
loop do
  i = i + 1
  if i >= 101
    exit
  end
  case i
    when i % 15 == 0
      puts("#{i} is divisible by 15")
    when i % 3 == 0
      puts("#{i} is divisible by 3")
    when i % 5 == 0
      puts("#{i} is divisible by 5")
    else
      puts("#{i}")
  end
end

As anyone can tell you, there are some inherent issues with that code. Let’s talk about them:

  • The incrementation of i (i = i + 1) should never come at the beginning of a loop. It’s bad practice. I’m not going to go off into a huge rant as to why – it’s been covered and explained in so many text books and what-not that it’d be a waste of my time.
  • The code doesn’t intuitively “know” to stop at 100. It manually checks every single time the process is run if we’re above 100, which is unnecessarily redundant and time-consuming. Or just plain unnecessary.
  • Injecting a string was entirely unnecessary. “puts(i)” would have achieved the same effect in cleaner code.

To summarize: there are better ways of doing it. One other way is to use a ‘while’ loop, but that’s not the best way to do it either. In the end I settled for this implementation using a “for foo in bar” loop:

for i in (1..100)
  if i % 15 == 0
    puts("#{i} is divisible by both 3 and 5")
  elsif i % 3 == 0
    puts("#{i} is divisible by 3")
  elsif i % 5 == 0
    puts("#{i} is divisible by 5")
  else
    puts(i)
  end
end

Of course, after I did this, Josh realized he could do the same in Python:


for i in range(1, 101):
    if i%15==0:
        print("FizzBuzz")
    elif i%3==0:
        print("Fizz")
    elif i%5==0:
        print("Buzz")
    else:
        print i

And for kicks, he even did it in LISP:

(defun count()
	(setq i 1)
	(while (<= i 100)
		(cond
			((= 15 (gcd i 15)) (princ "i is divisible by 5 and 3n")

			((= 5 (gcd i 5)) (princ "i is divisible by 5n")

			((= 3 (gcd i 3)) (princ "i is divisible by 3n")

			(t (princ i) (princ "n") )
		)
		(setq i (+ 1 i))
	)
	(princ)
)

Let’s analyze the code (that is, my Ruby code), shall we?

The code opens with our main loop, which is a fairly readable type of loop. Simply put, it translates into “For the variable ‘i’ in the range of numbers 1 through 100, including 1 and 100, do the following”. Fairly easy to understand right? That’s Ruby for you. πŸ˜‰ From there, the code breaks down into a simple conditional where it checks first to see if the number is divisible by both 3 and 5. It goes on to check if it is divisible by 3 or 5. Finally, if none of the above is true, then the number is printed.

It’s important to understand why this code is better, and more efficient. First and foremost, it maintains readability, which is always a must when working with code, while at the same time using some of the nicer features in Ruby in order to avoid redundant work. The biggest change by switching to this type of loop is that the loop now knows to stop at 100 without us manually having to assert that the program exit. We also were able to remove all the redundant incrementation of ‘i’ because it’s factored into our loop already.

So why am I writing about something so trivial as a pissing contest? Because it’s an important tool for learning about how to teach coding, and more specifically Ruby. Since I’m still learning (albeit at a fairly rapid rate), I’m essentially a perfect guinea pig. Until you break down things like “for foo in bar” into human-understandable syntax, you’ll find that you will be going at problems from a longer, more difficult angle. High-level languages have very strong and usable syntax for a reason. However, you’ve got to make a conscious effort into learning more than just the most basic of the basics. The quirks might not be enjoyable to learn, but they’ll improve your code ten-fold.

PS. Thanks to Nathan for tipping me off about using “for foo in bar” instead of while! πŸ˜‰