The latest on… Me.

March 15, 2008 - 6:38 pm No Comments

Plenty has changed since I last blogged about me. In fact, plenty has changed since I last blogged at all. I must admit, I’ve been a bit slack and haven’t been maintaining my blog much recently. I must do better. I really must.

So a quick update – as mentioned in a previous blog post, Chris and I finally decided to pack up and move overseas. We quit our jobs at Trade Me back in November ‘07 and the plan was to travel throughout South-East Asia for 3 months and ultimately end up in London where we would both find IT work and earn the big bucks.

Our 3 months in South-East Asia were amazing. I can’t stress that enough – if you haven’t been… GO! Asia has so much to offer and even the NZ dollar gets you so far! Thailand and Cambodia are cheeeeeap and cheerful, Japan was cold and expensive. Bangladesh was fascinating, Singapore was hot and sweaty, Malaysia was wet and Hong Kong was busy. Anyway, we haven’t done Vietnam yet so we’ll be going back… one day :). If you want to read all about our adventures in Asia, go to TravelStash – Chris And Annie, our very own travel blog.

During our holiday, I was offered two jobs – one at Google in Zurich as a Software Engineer in Test (omg, after so many years and so many interviews!) and another at Next Jump as a Software Engineer in London. Took me a while because it was a really tough decision to make, but eventually I picked Next Jump because the role was much more in line with where I want my career to head. Google then tried to convince me to join them in London instead. Let me tell you – it feels great to be so wanted! Anyway, I stuck with my decision and began the process of applying for the UK HSMP so that I could start at Next Jump as soon as I arrived in London. This application form ended up being a real mission, requiring me to provide all sorts of documentation, most of which I didn’t have access to, especially from some beach resort in Thailand! So my parents and brother did a great job helping me out, and together we got all the documents and forms done and sent off. The most memorable part of this process was jumping onto the back of a dodgy little motorbike with Chris AND a driver (yes, 3 of us!), wearing nothing more than shorts, singlets and jandals (psshhh, who needs a helmet!!), and weaving in and out of traffic on our way down to the main post office in Phnom Pehn to post my drivers’ license off to London. That would be enough to give any traffic cop in NZ a heart-attack!

We ended up in London on the 21st of February ‘08, a little ahead of schedule. Only a couple of days later I received my letter of acceptance from the Home Office in the UK – my HSMP application had been approved. However, it was only then that I found out that I had to go back to NZ to finish off the process and get my ‘entry clearance’. That took me a bit by surprise but what the hell, going back to NZ means I get to see my family and friends a lot sooner than I’d expected which is all good! Chris started looking for work (he needs someone to sponsor his work permit) by sending out a million emails a day to recruiters and large IT companies alike. Hopefully he’ll find the right role for him and we’ll be able to stay in the UK!! :)

Anyway, I’m writing this article from NZ so right now I’m waiting to have my biometrics meeting and get my entry clearance so I can finally start my new job at Next Jump. I’m really excited and can’t wait to sink my teeth into a new job! Looks like I might even get to go to New York for 3~4 weeks training on my way back to the UK so that should be awesome! Now I just need to get my brain back into geek mode and I should be fine… lol ;)

Code for GPS Tracking with Google Maps & AJAX

March 15, 2008 - 4:42 pm No Comments

Over the past few months, my article on GPS Tracking with Google Maps & AJAX has received many hits and attracted a multitude of comments requesting that the code for it be made available. I apologize for the delay but I’ve been away on holiday and far away from my trusted laptop. Now that things are somewhat back to normal and I can spend hour upon hour on my laptop again, here is the code that so many of you have asked for. I hope it makes sense and that it helps you all with what you’re trying to achieve. Obviously I haven’t posted the entire HTML and PHP coz it’s not all relevant to the GPS plotting but I hope what I have posted gives ya’ll a general idea on how to solve this particular problem. I’m sure there are many different ways to do this but this was just one way that I tried.Please feel free to ask questions and I’ll try to answer as best as I can! :)

...

Within the head section of the page that contains the gps tracking map:

[-]?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<script language="JavaScript">
 
function setTimer() {
   window.setTimeout("show_data();",5000);
}
 
function show_data(){
   //Append the id (just a simple count) to the requestURL
   var requestURL = "http://www.sitename.com/getGpsPoints.php";
   var count = document.getElementById("counter").value;
   count = parseInt(count, 10);
   var queries = "?id=" + count;
   var url = requestURL + queries;
 
   //Increment the hidden counter variable
   document.getElementById("counter").value = count+1; 
 
   var request = GXmlHttp.create();
   request.open("GET", url, true);
 
   request.onreadystatechange = function() {
      if (request.readyState == 4) {
         var xmlDoc = request.responseXML;
         var markers = xmlDoc.documentElement.getElementsByTagName("marker");
 
         for (var i = 0; i < markers.length; i++) {
            var point = new GPoint(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
 
            // Draw the MapMarker
            var mapMarker = new GMarker(point);
            map.addOverlay(mapMarker);
         }
 
         // Recenter the map
         map.centerAtLatLng(point); 
      }
   }
 
   request.send(null);
 
   //Reset the timer so that the page keeps refreshing itself
   setTimer();
}
 
</script>

Within the body section of the page that contains the gps tracking map, right at the bottom just before the /body tag:

[-]?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
<script language="JavaScript">
   var query = window.location.pathname;
   if (query == "/mapping/gps-tracking-with-google-maps--ajax") {
      var map = new GMap(document.getElementById("map"));
      mapSetup();
      setTimer();
   }
</script>

Separate PHP script that queries your database to retrieve the GPS points to plot:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
    header ("content-type: text/xml");
 
    $link = mysql_connect ("localhost", "username", "password");
    if (!$link) {
        die('Could not connect: ' . mysql_error());
    }
 
    mysql_select_db ("dbname");
 
    //If no search string is passed, then we can't search
    if(empty($_GET["id"])) {
        echo " ";
    } else {
        //Remove whitespace from beginning x%x% end of passed search.
        $search = trim($_GET["id"]);
 
        //Query the DB and store the result in a variable
        $query = mysql_query("SELECT * FROM gps WHERE id=".$search);
 
        //If no rows are found...
        if(mysql_num_rows($query) == 0) {
            echo " ";
        } else {
            //Stick the returned rows into a handy array for easy use
            $row = mysql_fetch_array($query) or die(mysql_error()); 
 
            //Write out XML using values returned by the query
            echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?><markers><marker lat=\"".$row["lat"]."\" lng=\"".$row["lng"]."\" /></markers>";
        }
    }
 
    mysql_close($link);
?>

Moving Overseas!

November 27, 2007 - 9:59 am No Comments

So I’m finally moving overseas! We’ve quit our jobs at Trade Me, sold pretty much everything we owned and are now in the final steps of packing and preparing for our move.

On Sunday 2nd December (like 5 days away!! :|), Chris and I hop on a flight to Singapore. From there, we have 3 months to make our way up to Hong Kong. On the 3rd of March, 2008, we will board another flight that will land us in London. At that point, we will start looking for work. We’re not sure where we want to live yet but it will all depend on where we can both find work. I have a couple of potentially great offers, one in Zurich and the other in London and I’m having trouble deciding where to go!

Now, for the pièce de résistance – Chris and I have been working like mad to get our travel blog up and working better than ever before we go. The URL for the site is http://www.travelstash.com and the URL for our ‘group’ is http:/www.travelstash.com/chris-and-annie/. There you go, now you can all keep up with our awesome travels!

Anyway, if you have any suggestions / travel tips for cool cats like us in Asia, or if you have a job you think would suit Chris or I, please leave us a comment. Every bit helps! :)

Other than that, bye bye NZ!

Instant Pudding Awesome-ness!

November 22, 2007 - 5:33 pm No Comments

What an awesome season! We lost every game in the last two seasons and this season, the Instant Puddings rose to the challenge and won the entire season! That’s right, we won!! WOOOHOOO!!

Textpattern plugins and Facebook apps

August 12, 2007 - 5:37 pm 1 Comment

Since Chris and I have become addicted to Facebook, we decided it would be cool to have a plugin for our respective blogging engines (Chris uses WordPress, I use Textpattern) that would update our Facebook accounts’ mini-feeds when we posted something on our blogs. Thus we both set off on our epic missions to create Facebook applications and WordPress / Textpattern plugins that would support this behaviour.

Here I’ll relate my experience with my Textpattern plugin. I’ll leave Chris to talk about his experience with WordPress.

So yeah, basically, my experience was a nightmare.

This was my first attempt ever at writing a Textpattern plugin so I am by no means an expert at this. It took me a while to figure out how to compile my php code so that I could deploy it to my Textpattern instance on my web server. Then it took me another while to figure out how to hook into Textpattern ‘events’. I must say, the documentation for this is really poor and I found myself trawling through the Textpattern source to figure out what functions did what. Not pretty. The best (and only) sites I found that helped me somewhat were this article on threshold state and this Textpattern source repository.

When I finally figured out how to call the ‘register_callback’ functions and that I had to use ‘article’ as the event I wanted to register my own events against, I was able to get stuck into it.

My next challenge was how to add a checkbox to the ‘write’ tab of the admin screens. I wanted a checkbox that when checked, would essentially call my code to notify my facebook account of my post. If it wasn’t checked, it wouldn’t notify facebook. However, adding a checkbox and positioning it where ever I want in the flow of elements on the page was NOT an easy task. Below is a sample of the code I had to use to get this to work:

1
2
3
4
5
6
7
8
9
10
function mdt_event_insert_checkbox($buffer) {
   $fb_notify = graf('<small><label for="notify_facebook">'.
      checkbox("notify_facebook", '1', '1', '', 'notify_facebook').
      'Notify Facebook?</label>&nbsp;');
 
   $find = '<input type="submit"';
   $replace = $fb_notify.$find;
 
   return str_replace($find, $replace, $buffer);
}

NASTY! I had to find the ‘Save’ button, then replace the HTML with my new HTML that includes the checkbox. OMG.

Anyway, I finally got that working (see screenshot below).

Next I needed to grab the title of the new post, the friendly-url to the article on my site and the excerpt of the new article. This again was no easy task. The following code seems to do the trick:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function current_url() {
   return 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
 
function get_latest_post() {
   include_once txpath.'/publish/taghandlers.php';
 
   // get the latest article posted
   $rs = safe_row("ID, Title, Excerpt", 'textpattern', "1=1 ORDER BY LastMod DESC LIMIT 0,1");
 
   $title = ' has blogged: ' . urlencode(stripslashes(urldecode('<a href="' . permlinkurl_id($rs['ID']) . '">'))) . substr($rs['Title'], 0, 45) . '</a>';
   $msg = substr($rs['Excerpt'], 0, 180);
   $url = current_url();
 
   if (strtolower($step) == "publish") {
   $url = $url . "?event=article";
 
   } elseif (strtolower($step) == "edit") {
      $url = $url . "?event=articlex%x%step=editx%x%ID=" . $rs['ID'];
   }
}

So now the tricky part – how to connect to Facebook, log in as myself and call the Facebook API function that updates my ‘mini-feed’ with some content. I first attempted this by embedding the Facebook API into the Textpattern plugin so that the integration would be completely seamless. This, however, was difficult on many levels. First of all, I couldn’t get the Facebook API to compile into my Textpattern plugin. The php compiler would tell me that certain server variables weren’t defined, etc etc. I did iron out all those error messages and warnings eventually though and finally got the code to compile. However, I later realized that this was never going to be a feasible solution because in order for this to work, my Facebook developers’ API key and secret key would need to be hard-coded into the Textpattern plugin and if I were ever to make this Textpattern plugin public (which I intend to do), I would be sharing my API and secret keys, something I don’t necessarily want to do. Doh! So I had to change my thinking somewhat.

The solution to this was to basically write the Facebook part of the plugin as a totally separate web application and have the Textpattern plugin call this web app, passing through to it the title, url and excerpt in the form of a query string. This method lets the Facebook web application handle all the Facebook functionality (logging in and authenticating, remembering you once you’re logged in, calling the appropriate API functions, etc etc) and the Textpattern plugin basically doesn’t need to know anything about Facebook.

What a mission.

However, it all seems to be working now and I’ve used it once already. Those of you who are on Facebook and have added me as a friend will be able to see little posts on my mini-feed (on my profile page) saying “Annie has blogged…” with a link through to this article. Very cool :) When I am comfortable that things are working as intended and I tidy things up enough to make my Textpattern plugin publicly available, I’ll put it up on my here somewhere for people to grab.

Phew

Indoor Soccer!!

August 8, 2007 - 6:09 pm 1 Comment

Well it’s been ages since I last blogged anything, so I thought I’d get back into it with something quite easy-going. So here we go…

I’ve been playing a bit of indoor soccer for the last few weeks and I’ve been really enjoying it! I’ve been playing for a team called “Instant Pudding” and… well, we’re getting better!! The guys on our team have some great soccer skills but I think all our fitness is lacking somewhat. But we are getting better! You can view our results for last season here.

Tomorrow I start playing for another team, “Dynamo Needarest”, a team set up by Chris and myself made up of a bunch of Trade Me guys and gals. Should be loads of fun but boy am I gonna be knackered and possibly quite sore after two games a week!

Anyhoo, one of my biggest gripes so far has been the fact that I haven’t been able to find indoor soccer boots in my size. I’ve been playing in my running shoes and although it’s worked out ok, I keep stubbing my big toe when I kick the ball or when I run and stop really fast. That’s not so much fun. However, today, I finally found a pair that fits! A pair of Puma children’s size 5!! Doesn’t matter though, what matters is they fit and they were cheap :) Rebel Sport had quite a good variety today (they didn’t last time I had a look) so I’m very excited about my next game.

Chris also got some new indoor soccer boots today – very nice. I’m sure we’re both gonna play like pros now that we’ve got the right gear (hehe, or not!).

Below is a pic of our hot new shoes.

Our new indoor soccer boots
Our new indoor soccer boots

And below is a photo of what seems to happen to me pretty much every game. Even though I play in a social league, there are some guys on the teams we play against that play real hard. Their high-powered kicks always seem to send the ball straight at me. On the bright side, I’ve saved a few goals for my team!! :|

A soccer ball imprinted on my thigh
A soccer ball imprinted on my thigh

A splash of orange

April 27, 2007 - 7:04 pm 1 Comment

Sitting in a hotel lounge in Delft (The Netherlands), Chris and I discovered, after a few gin and lemonades, that his digital camera (Canon Digital IXUS 750) has an awesome function called “Color Accent”. Turning this on allows the camera to focus on one color and filter out all others, making all other colors in the rest of the shot black and white.

Below is a photo I later took in our hotel room bathroom using this function. As you can see, I focused the shot on the orange of the shower curtain. Quite a nice effect.

Color Accent
Photo taken with a Canon Digital IXUS 750 using the Color Accent function

It’s all about… Me.

April 27, 2007 - 5:49 pm No Comments

Hehe, I love these article titles.

Anyway, a bit of an update – although not much has really happened since my last update (how boring).

Lets see, since last June, I have…


  1. Been a software developer at Trade Me for almost a year (woohoo!) – AND – I haven’t even broken anything yet… heheh… phew

  2. Worked on several big projects at Trade Me – namely helping develop the new look and feel of our DVD section (for which I wrote a cool google-suggest style AJAX enabled search but unfortunately you have to be a member of Trade Me to see this), adding support for rural and commercial properties in Trade Me Property (for which I was project lead! Oohh yeah!), and lots of other cool stuff…

  3. Re-designed and totally over-hauled Travelblog – now it does cool stuff like geocode cities that you visit on the fly and allows comments to be posted! :)

  4. Been on an awesome 5-week holiday to Europe, San Francisco and Tokyo with Chris – check it out at the “Travelblog”:http://travelblog.mindtrip.co.nz…

  5. Been to Noosa for a bit of fun in the warm ocean…

  6. Done a bit of web development contracting work on the side…

  7. Found out that two or more jobs at once doesn’t leave much time for watching TV…

  8. Tested out my interviewing skills by performing 6 technical tests on some developers wanting to work at Trade Me… it’s weird being on this end of the interview…

  9. OH and how can I forget… I interviewed for a Software Engineer in Test position at Google AGAIN, but this time in person and in Zurich. Oh, and I didn’t get the job. Again. But you can read all about that here if you’re interested, of course… :)


... and I think that’s about it really.

Next in the to-do list is…


  1. Studying for and hopefully doing some form of Microsoft Certification – I think it’s called Microsoft Certified Professional Developer (MCPD)

  2. Doing a bit more work on Travelblog so that I can maybe even make it public

  3. Working on Chris’ and my new little project… (which is top-secret at the moment so will post about it when a bit closer to it’s go-live date)

  4. Plan another looooooooong holiday somewhere, perhaps Asia this time :)


Yeah. That’s about it.

An example Prolog program

April 9, 2007 - 3:27 pm No Comments

Way back at university (like, 3 years ago), I did a couple of papers that covered Prolog. Unlike most procedural top-down programming languages that us software developers are used to using, Prolog is a logic programming language. A typical Prolog program consists of facts, rules and queries. Although I don’t have a Prolog interpreter on my machine at the moment, we used SICStus Prolog on NetBSD at university.

Speaking of SICStus Prolog – apparently it now has integrated support for developing web based applications using a new module called PrologBeans. Using this module, SICStus Prolog can be called from a Java-based application server. Awesome!!

Anyway, for those interested in what Prolog looks like, below is an old assignment that I submitted for a course on Artificial Intelligence. If I remember correctly, the assignment was for us to simulate a robot cleaning dishes. We were asked to implement all the facts and rules, in Prolog, for such a robot. When the robot encounters dirty dishes, it is supposed to clean them. If it encounters wet dishes, it is meant to dry them.

When the program is run with an initial state, the output is a list of steps that the robot would take according to the prolog rules written in the program.

Below is the code for this program.



%-*-prolog-*-
% operator(-Op, -Pre, -Del, -Add)
% operator definitions
% Pre is a list of state preconditions
% After Op is applied
% Del gets deleted from state
% Add gets added to state


operator(putDirtyDishFromBench(X), pre: [dirty(X), at(X,bench)], del: [at(X,bench)], add: [at(X,sink)]).


operator(putDirtyDishFromDrainer(X), pre: [dirty(X), at(X,drainer)], del: [at(X,drainer)], add: [at(X,sink)]).


operator(putDryDishInSink(X), pre: [dry(X), at(X,drainer)], del: [dry(X), at(X,drainer)], add: [cleanButWet(X), at(X,sink)]).


operator(putDryDishInCupboardFromDrainer(X), pre: [dry(X), at(X,drainer)], del: [at(X,drainer)], add: [at(X,cupboard)]).


operator(putDryDishInCupboardFromBench(X), pre: [dry(X), at(X,bench)], del: [at(X,bench)], add: [at(X,cupboard)]).


operator(putCleanButWetDishFromSink(X), pre: [cleanButWet(X), at(X,sink)], del: [at(X,sink)], add: [at(X,drainer)]).


operator(putCleanButWetDishFromBench(X), pre: [cleanButWet(X), at(X,bench)], del: [at(X,bench)], add: [at(X,drainer)]).


operator(pickUpTool(X,Y), pre: [holding(X)], del: [holding(X)], add: [holding(Y)]).


operator(processInSink(X), pre: [dirty(X), at(X, sink), holding(dishbrush)], del: [dirty(X)], add: [cleanButWet(X)]).


operator(processInDrainer(X), pre: [cleanButWet(X), at(X, drainer), holding(teatowel)], del: [cleanButWet(X)], add: [dry(X)]).


% instantiate(?Operator)
% Makes Operator ground (including its pre, del and add lists)


instantiate(putDirtyDishFromBench(X)) :- dish(X).
instantiate(putDirtyDishFromDrainer(X)) :- dish(X).
instantiate(putDryDishInSink(X)) :- dish(X).
instantiate(putDryDishInCupboardFromDrainer(X)) :- dish(X).
instantiate(putDryDishInCupboardFromBench(X)) :- dish(X).
instantiate(putCleanButWetDishFromSink(X)) :- dish(X).
instantiate(putCleanButWetDishFromBench(X)) :- dish(X).
instantiate(pickUpTool(X,Y)) :- tool(X), tool(Y), X\==Y.
instantiate(processInSink(X)) :- dish(X).
instantiate(processInDrainer(X)) :- dish(X).


% dish(?Object)
% Object is a dish
dish(dish1).
dish(dish2).
dish(dish3).
dish(dish4).
dish(dish5).


% tool(?Object)
% Object is a tool
tool(dishbrush).
tool(teatowel).
tool(nothing).


% location(?Object)
% Object is a location
location(bench).
location(sink).
location(drainer).
location(cupboard).

An example of how to use this prolog program:


TESTDISHES1:


testdishes1 :- goal_stack_plan([at(dish1, bench), dirty(dish1), holding(nothing)], [at(dish1, cupboard), dry(dish1)], Plan, FinalState, []).

And the plan found by the program when TESTDISHES1 is run:


PLAN FOUND FOR TESTDISHES1:


====================================
Plan to achieve [at(dish1,cupboard),dry(dish1)]
Starting at [at(dish1,bench),dirty(dish1),holding(nothing)] putDirtyDishFromBench(dish1) pickUpTool(nothing,teatowel) pickUpTool(teatowel,dishbrush) processInSink(dish1) putCleanButWetDishFromSink(dish1) pickUpTool(dishbrush,teatowel) processInDrainer(dish1) putDryDishInCupboardFromDrainer(dish1)
Ending in state: [holding(teatowel),dry(dish1),at(dish1,cupboard)]
====================================
yes | ?-

If this looks like something you might wanna have a go with, try looking at this tutorial.

I’ve been quoted… about VB.NET

April 3, 2007 - 5:06 am 1 Comment

This morning one of my fellow developers sent me a link to this article on Rowan Simpson’s (formerly the Software Development team lead at Trade Me, now heading up the Trade Me Products team) blog.

How exciting!! I’m famous!! :)

But seriously, writing code in VB.NET just frustrates me and that email I sent our dev group was one of a few instances (perhaps one of the more curious ones) where VB.NET just doesn’t seem to rate next to C#. I mean, the recent introduction of the using statement… come on! C# has had this for aaaaaaaaaaaages. And the fact that operator overloading has only JUST been introduced to VB.NET – again, C# has has this for ages. And language support for unsigned types (UInteger, ULong, and UShort) has again, only just been introduced in .NET 2 for dear ol’ VB.NET. I’m sure I was using unsigned types about 8 years ago at university (ok, so that might have been in Java, but still?!!?).

However, what frustrates me the most about VB.NET is probably the fact that I feel like I’m writing an essay in English when coding… Brackets are good! Semi-colons are good! And sticking to the OOP terminology that many programmers out there have learnt to love over the years must be good!

Oh well, better get back to my screeds of VB.NET – we have an early deploy tomorrow morning wooohoooo!!!