Uni Timetable Manager v2 Beta & Source Code Released

July 21, 2008 by jackvalmadre

A beta release of version 2 is now available for download from the new site, http://unitimetable.googlepages.com/. I’ve also opened a Google Code webpage at http://code.google.com/p/unitimetable/ so it’s officially an open source project! If anyone’s interested in becoming a developer let me know. If you have any suggestions or bugs, you can add them to the Issues section at the Google Code site, or email/messenger (MSN/Gtalk) me on jack.valmadre@gmail.com.

New version 2 user interface

New version 2 user interface

Here’s a list of the major changes in version 2:

  1. Revamped user interface, including drag-droppable classes, nicer-looking classes, a sidebar showing remaining streams and ginormous vista-ified toolbar icons.
  2. An Import Wizard to make it easier to load the timetable data into the program. The code was also modularised to allow other universities to use the same program. A quick UNSW importer was hooked up (not guaranteed to work) and a QUT version is in the pipeline.
  3. You can now save and open files in XML format. Exporting as an image now includes support for EMF vector graphics (if a little buggy) and higher quality JPEGs. Alternatively you can export directly to the desktop background and the program will put a transparent overlay of the timetable on your wallpaper.
  4. I played around with the algorithm a bit. No major improvements though, I was mainly working on the interface.
Colour schemes + export to wallpaper features.

Colour schemes + export to wallpaper.

I’ve got a feeling there’s some features I’ve forgotten but I’ll edit them in as I remember. There’s also a hidden Easter Egg which can be unlocked by entering the “Konami Code” and pressing Enter :)

Windows 7 Beta Fish

January 31, 2009 by jackvalmadre

I’ve been trying out the Windows 7 Ultimate beta. The default wallpaper is a Siamese fighting fish (“betta” fish, get it?) Which gave me an idea! One fish, two fish, red fish, blue fish…

One fish, two fish, red fish, blue fish. Alpha fish, beta fish, gamma fish.

Alpha fish, beta fish, gamma fish.

:)

More Photos from Redmond

January 26, 2009 by jackvalmadre

This cereal is basically lots of little choc chip bikkies.

Breakfest! Pt 1

Breakfest! Part 1

Sausage “stir fry” with salad :)

Brown sugar snags, onion, jalapenos and lime.

Brown sugar snags, onions, jalapenos and lime.

Cucumber, capsicum lettuce, tomato, carrot and Balsamic.

Cucumber, capsicum lettuce, tomato, carrot and Balsamic.

On Christmas Eve, Jon and I went up to Snoqualmie for a snowboarding lesson. It snowed for the whole day and there was about a foot of powder on the slopes. :D

Driving up the I-90 to Snoqualmie Pass.

Driving up the I-90 to Snoqualmie Pass.

Jon drove.

Jono drove.

We had a bit of trouble getting out, but we didn't end up needing the chains.

We had a bit of trouble getting out, but we didn't end up needing the chains.

That night we got a few interns together and went to Claim Jumper for dinner.

John took on a huge plate of ribs.

John took on a gigantic plate of ribs.

I had the "Widow Maker Burger".

I had the "Widow Maker Burger".

"Ch-antler-ier"

"Ch-antler-ier"

Chris, Jeff, David, John and John.

Chris, Jeff, David, John and John.

We split the 6 layer "Mother Lode" cake between 6 people.

We split the 6 layer "Mother Lode" cake between 6 people.

On Christmas Day I made a snowman.

On Christmas Day I made a snowman.

He only lasted a couple of days.

He only lasted a couple of days.

Going...

Going...

...going...

...going...

Gone!

Gone!

Then on Christmas Day, Jeff did a roast for everyone.

John, Jeff and John.

John, Jeff and John.

Chris, David and Luke.

Chris, David and Luke.

Then trifle, jelly and crumble for dessert.

Then trifle, jelly and crumble for dessert.

On New Years’ Eve, we went in to Lincoln Square in Bellevue to watch the Space Needle fireworks.

Someone let off a firework in front of Lake Washington.

Someone let off a firework in front of Lake Washington.

More fireworks.

More fireworks.

Yay long exposure.

Yay long exposure.

Hanging out in the Microsoft cafeteria on the top floor.

Hanging out in the Microsoft cafeteria on the top floor.

Then next weekend we hit up Snoqualmie again.

The Impala made it back up no worries.

The Impala made it back up no worries.

Pretty solid snowfall up there!

Pretty solid snowfall up there!

Tom heading up to the slopes.

Tom heading up to the slopes.

I don't think these things actually go below "Moderate".

I don't think these things actually go below "Moderate".

A crow...

A crow...

And a mountain.

And a mountain.

The slopes are open until 10pm.

The slopes are open until 10pm.

The slopes at night.

Slopes at night again.

Snowing in Seattle!

December 22, 2008 by jackvalmadre
Having trouble finding time to post. Here’s some photos!!
Bunch of interns at the Space Needle.

A bunch of us at the Space Needle.

Looking out from the revolving restaurant.

Looking out from the revolving restaurant.

Path outside the building 86 cafeteria.

Outside the building 86 cafeteria.

Inside the building 86 cafeteria.

Inside the building 86 cafeteria.

Our place after the first day of snow!

Our place after the first day of snow!

Trekking off to work.

Trekking off to work.

I made a snow angel!

I made a snow angel!

Snowed under at Microsoft.

Snowed under at Microsoft.

It took me ages to get to work because I couldn't stop taking photos.

Started coming down pretty hard!

The full-time Microsoft Aussies had made a giant snow man.

The full-time Microsoft Aussies had made a giant snow man.

Strolling back at night.

Strolling back at night.

The Chevrolet.

The Chevrolet.

Walking in the next morning.

Walking in the next morning.

Roads were looking a bit better now.

Roads were looking a bit better now.

View from the balcony at night.

View from the balcony at night.

Snowy tree.

Snowy tree.

First Week at Microsoft

December 11, 2008 by jackvalmadre

After the first two days of orientation, I met the other developers in my team and got some more details about my project. I’m working with Live Search, Microsoft’s competition to Google’s search engine. The first week or two is a lot of setting up and getting familiar with the system. It’s a great place to work! Everyone’s really enthusiastic. Have a look at an aerial photo of my building.

My workspace, complete with dual monitors!

My workspace, complete with dual monitors!

I’m sharing an office with Tristan (another UQ intern) and Alex.

Redmond town centre.

Redmond town centre.

When we went for dinner in Redmond town centre the other night, we found all-you-can-eat Tacos for $5!

David and Jeff from UWA.

Taco Tuesday: David and Jeff from UWA.

Jeff braves the cold in shorts, t-shirt and pluggers.

Jeff braves the cold in shorts, t-shirt and pluggers.

We brought the other interns back next week (this was the original plan, but the cars got separated ;) ), but this time the tacos were only available at the bar and you had to be 21. Doh!

On the home front, I’ve managed to cook 1 batch of spaghetti bolognaise, 2 batches of French toast, and some bacon. :D

MMmmm.. French toast.

MMmmm.. French toast.

Deliciously easy. Although I have to admit the budget maple syrup probably wasn’t worth it. Same for the orange juice – $1.80 a gallon (~3.8L) is too cheap. I later discovered that my “juice” was 2% actual juice… sick.

The spag bol was good for 4 serves.

The spag bol was good for 4 nights.

Looking back at this photo, I’m not sure I got the meat-to-pasta ratio right. Oh well!

On the weekend, I met Chad, Shauna and Max, some friends of my aunt, Amanda. We went to the Experience Music Project in Seattle, which had some fantastic Jimi Hendrix recordings! They showed me around Pike Place Market and we ate dinner at the brewery there. We also went to the movies that night.

Giant guitar sculpture at the EMP.

Giant guitar sculpture at the EMP.

There were some robotic guitars strumming away.

There were some robotic guitars in there strumming away.

The building itself is pretty funky. The Experience Music Project shares it with the Science Fiction Museum.

The building itself is pretty funky. The Experience Music Project shares it with the Science Fiction Museum.

The EMP is at the base of the Seattle Space Needle.

The EMP is at the base of the Seattle Space Needle.

The famous Pike Place Market.

The famous Pike Place Market.

Chad, Shauna and Max at the Pike Place brewery.

Chad, Shauna and Max at the Pike Place brewery.

Walked back past the Space Needle on the way home.

Walked back past the Space Needle on the way home.

And Tom’s moved in with me! So it was a real action-packed week. I’ll stick up some car photos soon! My hire car is a red Chevrolet :D

Arriving in Redmond

December 1, 2008 by jackvalmadre

I touched down at Seattle airport at 12.10pm, after leaving Brisbane at 12.05pm the same day. :D We stopped over in LA from 7-9.30am.

Los Angeles sunrise

Los Angeles sunrise over the 747 wing.

The three other Brisbane interns (that we know of) on the flight were Matt, John and Tom. Tom had opted for a rental car from Seattle-Tacoma airport, so he drove us all to Redmond. It was pretty nerve-racking driving on the right hand side of the road – left turns especially – but he picked it up in no time!

Concentration.

Concentration.

Safely made it to Timberlawn to pick up the keys.

Safely made it to Timberlawn to pick up the keys.

I’m staying in a 2 bedroom apartment at Trails of Redmond, Matt’s sharing a 2 bedroom apartment with David from Western Australia at Timberlawn, Tom and John have studio apartments at Homestead Hotel. I haven’t heard whether I’ll be sharing the accommodation with anyone yet.

My place is the left side, middle floor.

My place is the left side, middle floor.

The dining room and balcony from the living room.

The dining room and balcony from the living room.

The kitchen.

The kitchen.

And here’s a few snaps I took when I was walking through the Microsoft campus last night.

Maple and pine trees down either side of the road.

Maple and pine trees down either side of the road.

Maple and pine trees lining the road.

More trees stretching around the corner.

Light and leaves cast on the footpath.

Light and leaves cast on the footpath.

Streetlight behind a tree on the way home.

Streetlight behind a tree on the way home.

I’m starting at Microsoft tomorrow, with New Employee Orientation in the morning.

ELEC Army Strikes

November 11, 2008 by jackvalmadre

Leading up to the ELEC2004 final exam yesterday, my worked examples and shameless blog plugging managed to pull quite a bit of traffic…

Blog stats.
Bandpass filter.

Blog stats.

1000+ (non-unique) hits, just a bit more than I’m used to. Nice work guys!! :D

Rotating Axes

October 17, 2008 by jackvalmadre

One for the MECH2210 kids.

You know you've done too much MECH when...

You know you've done too much MECH when...

Woohoo my first entry in the “Puns” category! Came up with this when I was up way too late working on 3D dynamics. Edit: Added some colour to assist my sketch ;)

Greyscale edition

Greyscale edition

Microsoft Internship over Summer Holidays

September 30, 2008 by jackvalmadre

A couple of weeks ago I went to an information session at UQ about working at Microsoft as an intern over the 3 month summer break. I was planning to wait and consider applying when I was in 3rd year, but I decided I had nothing to lose by applying this year and I sent off a resume the next day. After answering some email questions about experience, etc, they organised to interview me over the phone next week.

The phone interview consisted of a few language-specific questions (in your strongest language – C++/C# for me), some data structures/algorithms and a bit of problem solving/testing thrown in. I actually botched my C++ question, then I asked for more at the end. Phewph! ;)

After the phone interview, Microsoft sent me an email saying that my interview was in Melbourne tomorrow! They explained that didn’t have time to organise flights, but they’d reimburse me if I bought them. So on Thursday I flew down and caught up with my cousins for a cappuccino/frappe before the coding interview. :D

Approaching Melbourne's South Bank from the Skybus stop.

Approaching Melbourne's Southbank from the Skybus stop.

Pedestrian bridge over the Yarra River.

Pedestrian bridge over the Yarra River.

View from the bench where I chilled out and brushed up on some syntax.

View from the bench where I chilled out and brushed up on some syntax.

Looking down the river to the MCG.

Looking down the river to the MCG.

The three in-person interviews lasted half an hour each. One for software development, one for software development in testing and one for problem solving/sorting out details/having a chat. All the interviews went fairly well, although I did slip up a little bit at the start of the coding interview.

The following week, Microsoft sent me an email offering me a position over the holidays! So I’ll be working in Redmond, USA (near Seattle) from December to February. Woohoo!!

Edit: A bit of added hilarity… I’m going to have to learn to cook meals to some degree. Check out my last batch of fish fingers. :D

Whipping up a few fish fingers. Circa 2006.

Whipping up a few fish fingers. Circa 2006.

Resizable Image Control using PyGTK and Cairo

September 21, 2008 by jackvalmadre

I’ve been doing a little bit of GUI work in GTK. Something I really missed was a dynamically resizable image control – the gtk.Image object just seems to assume the same dimensions as the picture it’s displaying.

I found a good tutorial about rendering a custom widget using Cairo, with the widget itself inheriting from gtk.DrawingArea. Another useful resource was a C++/gtkmm article about drawing a gtk.gdk.Pixbuf object in a Cairo context. Here’s some screenshots of a demo program in Ubuntu 8.04 and Windows XP.

Scaled, aspect ratio maintained

Scaled, aspect ratio maintained.

Stretched, aspect ratio out the window.

Stretched, aspect ratio out the window.

Aspect preserved, black background.

Aspect preserved, black background.

Running in Windows XP.

Running in Windows XP.

Prevented from exceeding original resolution.

Prevented from exceeding original resolution.

Enlargement allowed, constant aspect enforced.

Enlargement allowed, constant aspect enforced.

resizableimage.py

Here’s the key bits of code for the ResizableImage control:

import pygtk
import gtk
from gtk import DrawingArea

class ResizableImage(DrawingArea):

    def __init__(self, aspect=True, enlarge=False,
            interp=gtk.gdk.INTERP_NEAREST, backcolor=None, max=(1600,1200)):
        """Construct a ResizableImage control.

        Parameters:
        aspect -- Maintain aspect ratio?
        enlarge -- Allow image to be scaled up?
        interp -- Method of interpolation to be used.
        backcolor -- Tuple (R, G, B) with values ranging from 0 to 1,
            or None for transparent.
        max -- Max dimensions for internal image (width, height).

        """
        DrawingArea.__init__(self)
        self.pixbuf = None
        ...
        self.connect('expose_event', self.expose)

The expose event is triggered when the control needs to be repainted. Here we just obtain a Cairo context and call draw().

    def expose(self, widget, event):
        # Load Cairo drawing context.
        self.context = self.window.cairo_create()
        # Set a clip region.
        self.context.rectangle(
            event.area.x, event.area.y,
            event.area.width, event.area.height)
        self.context.clip()
        # Render image.
        self.draw(self.context)
        return False

Then this is where the image actually gets rendered to the control. The size of the image is determined by resizeToFit(). A resized version of the gtk.Pixbuf member is created using scale_simple(). The gtk.Pixbuf image is displayed using set_source_pixbuf().

    def draw(self, context):
        # Get dimensions.
        rect = self.get_allocation()
        x, y = rect.x, rect.y
        # Remove parent offset, if any.
        parent = self.get_parent()
        if parent:
            offset = parent.get_allocation()
            x -= offset.x
            y -= offset.y
        # Fill background color.
        if self.backcolor:
            context.rectangle(x, y, rect.width, rect.height)
            context.set_source_rgb(*self.backcolor)
            context.fill_preserve()
        # Check if there is an image.
        if not self.pixbuf:
            return
        width, height = resizeToFit(
            (self.pixbuf.get_width(), self.pixbuf.get_height()),
            (rect.width, rect.height),
            self.aspect,
            self.enlarge)
        x = x + (rect.width - width) / 2
        y = y + (rect.height - height) / 2
        context.set_source_pixbuf(
            self.pixbuf.scale_simple(width, height, self.interp), x, y)
        context.paint()

    def set_from_pixbuf(self, pixbuf):
        width, height = pixbuf.get_width(), pixbuf.get_height()
        # Limit size of internal pixbuf to increase speed.
        if not self.max or (width < self.max[0] and height < self.max[1]):
            self.pixbuf = pixbuf
        else:
            width, height = resizeToFit((width, height), self.max)
            self.pixbuf = pixbuf.scale_simple(
                width, height,
                gtk.gdk.INTERP_BILINEAR)
        self.invalidate()

The self.max variable limits the size of the internal gtk.Pixbuf to prevent slow render times for larger images. The default maximum is 1600×1200. It can be disabled by setting max=None in the constructor call.

    def set_from_file(self, filename):
        self.set_from_pixbuf(gtk.gdk.pixbuf_new_from_file(filename))

    def invalidate(self):
        self.queue_draw()

    ...

A couple of functions external to the class:

def resizeToFit(image, frame, aspect=True, enlarge=False):
    """Resizes a rectangle to fit within another.

    Parameters:
    image -- A tuple of the original dimensions (width, height).
    frame -- A tuple of the target dimensions (width, height).
    aspect -- Maintain aspect ratio?
    enlarge -- Allow image to be scaled up?

    """
    if aspect:
        return scaleToFit(image, frame, enlarge)
    else:
        return stretchToFit(image, frame, enlarge)

def scaleToFit(image, frame, enlarge=False):
    image_width, image_height = image
    frame_width, frame_height = frame
    image_aspect = float(image_width) / image_height
    frame_aspect = float(frame_width) / frame_height
    # Determine maximum width/height (prevent up-scaling).
    if not enlarge:
        max_width = min(frame_width, image_width)
        max_height = min(frame_height, image_height)
    else:
        max_width = frame_width
        max_height = frame_height
    # Frame is wider than image.
    if frame_aspect > image_aspect:
        height = max_height
        width = int(height * image_aspect)
    # Frame is taller than image.
    else:
        width = max_width
        height = int(width / image_aspect)
    return (width, height)

def stretchToFit(image, frame, enlarge=False):
    image_width, image_height = image
    frame_width, frame_height = frame
    # Stop image from being blown up.
    if not enlarge:
        width = min(frame_width, image_width)
        height = min(frame_height, image_height)
    else:
        width = frame_width
        height = frame_height
    return (width, height)

demogtk.py

Here’s most of the code for the demo program:

import pygtk
import gtk
import gtk.glade

import os
from resizableimage import ResizableImage

class DemoGtk:

    def __init__(self):
        # Initiate GUI.
        self.gladefile = "demo.glade"
        self.wTree = gtk.glade.XML(self.gladefile)
        # Find widgets that we use.
        self.frame = self.wTree.get_widget('pictureframe')
        self.txtFile = self.wTree.get_widget('txtFile')
        self.chkAspect = self.wTree.get_widget('chkAspect')
        self.chkEnlarge = self.wTree.get_widget('chkEnlarge')

        # Connect signals.
        signals = {
            'on_window_destroy': self.destroy,
            'on_txtFile_changed': self.openFile,
            'on_chkAspect_clicked': self.changeAspect,
            'on_chkEnlarge_clicked': self.changeEnlarge
        }
        self.wTree.signal_autoconnect(signals)

        # Do some runtime GUI.
        self.image = ResizableImage(
            self.chkAspect.get_active(),
            self.chkEnlarge.get_active(),
            gtk.gdk.INTERP_BILINEAR)
        self.image.show()
        self.frame.add(self.image)

Options for interpolation type are gtk.gdk.INTERP_NEAREST, gtk.gdk.INTERP_TILES, gtk.gdk.INTERP_BILINEAR, gtk.gdk.INTERP_HYPER. I used “bilinear” here to get decent quality pictures. The “nearest” option is alright if you need more performance.

    def destroy(self, widget, data=None):
        gtk.main_quit()

    def openFile(self, widget, data=None):
        filename = widget.get_text()
        if not os.path.isfile(filename):
            return
        self.image.set_from_file(filename)

    def changeAspect(self, widget, data=None):
        self.image.set_aspect(widget.get_active())

    def changeEnlarge(self, widget, data=None):
        self.image.set_enlarge(widget.get_active())

def main():
    gui = DemoGtk()
    gtk.main()

if __name__ == '__main__':
    main()

Doesn’t look like I’m able to upload the source to WordPress. Just let me know in the comments if you’re after a bit more detail!

Auto Signon for UQ

September 20, 2008 by jackvalmadre

Although I haven’t worked on this since the first week or two of semester, thought I’d post up a screenshot of where I got up to for general interest. I was using Greasemonkey to write a Firefox extension that loads a selection of classes from the XML file saved by Uni Timetable Manager. It doesn’t do any sign-on yet, just loads up the selection and locates a couple of links. Probably get around to working on this more over the holidays!

The beginnings of Auto Signon

The beginnings of Auto Signon