Archive for December, 2009

Configuring an Android development platform on Ubuntu 9.04

Since I thoroughly dig Linux for all things development, I’m going to use a Virtual Machine running Ubuntu 9.04 to work on my Droid app, remind@home. I’ll later keep track of the project in a Subversion repository. I still don’t know where I will host my repository, but the short list is likely to be either Sourceforge or Google Code.

I’m using the directions on the Android Developer page to configure my SDK using Eclipse as the Java IDE. Here are the steps I had to follow to set up Ubuntu 9.04 as an Android development platform:

  1. Install Java 6 JDK by typing ‘sudo apt-get install sun-java6-jdk‘ on the command line.
  2. Install the Eclipse IDE. I initially tried this with apt to install the version of Eclipse from the repository, but this is version 3.2 (as of 2009-12-30) and the ADT recommends version 3.4 or newer. Later on in the configuration process, I had some difficulty installing ADT and ended up installing Eclipse 3.5 from source. Here’s how:
    1. Download the latest version of Eclipse classic (3.5.1 as of 2009-12-30) from the Eclipse download page.
    2. Extract the folder into your home directory. This does not appear to need compilation or any such fun stuff.
    3. Open the eclipe folder and run eclipse.
  3. Install the Android Development Tools (ADT) for Eclipse. Open Eclipse and go to Help -> Install New Software. Inside the dialog, click ‘Add’ and add the following:
    ADT : https://dl-ssl.google.com/android/eclipse/
    Check the box net to ‘Developer Tools’ and hit next. Follow the series of dialog boxes to install ADT. Restart Eclipse when done.
  4. Download the Android SDK for Linux from the Android developer page. Extract the folder into your home directory.
  5. Open Eclipse and configure the Android SDK’s location within Eclipse. Go to Window -> Preferences. Select the Android menu on the left and click Browse to choose the SDK location. Navigate to the /home/<user>/android-sdk-linux_86/ folder and hit OK. Hit OK to close the Preferences dialog.
  6. Install the Android platforms that you want to develop applications on. Go to Window -> Android SDK and AVD Manager. Click Available Packages on the left and choose which packages you want to install. Since this is my first app and I’m not concerned about it being usable on anything other than my Motorola Droid, I only chose Android 2.0 and Android 2.0.1. In the future, I can install more SDKs to ensure my software works through multiple devices. Click ‘Install Selected’ when done to install the desired SDKs.
  7. Create an Android Virtual Device (AVD) to begin work on. While still in the Android SDK and AVD Manager you opened in step 5, click ‘Virtual Devices’ on the left and click ‘New’. Name your device and choose your SDK. I named my device ‘motorola-droid’ and chose Android 2.0.1 and left all other settings the same and clicked ‘Create AVD’.
  8. From here, all that is left to do is start writing your app. I followed the Hello World tutorial available on the Android developer site. If you followed the directions for configuring Eclipse 3.5 on Ubuntu 9.04 with the Android Development Tools, you should have no problem compiling and running this app. However, The directions say it should be as easy as going to Run -> Run to launch the program, but I had some errors came up when I tried that method. Instead, go to the projects window on the left side and right click your project name ‘HelloAndroid’ and go to Run As -> Android Application to launch the program. It appears that the Run menu contains configuration settings to add a new configuration type (going to Run -> Run Configurations pulls up this menu) but I have yet to figure out how to add Android Application to that menu.

Now that I have a working development environment, I can get started on my remind@home application. I will continue to blog as that project moves forward.

, , , ,

1 Comment

The Netflix prize – Someone won $1m for this suggestion?

After ignoring this section of Netflix for a bit too long, I finally gave the suggestion system a try. I entered movie suggestions for 15 or so minutes (skipping a lot of movies that I never saw or hadn’t seen recently enough to accurately judge), and this is my result:

Have you ever wondered what you get when you mix David Attenborough’s fantastic biopic of Gandhi with Larry David’s awkwardly hilarious Curb Your Enthusiasm (season 3, in particular)? I know I haven’t. Netflix has the answer! The answer is Life in the Undergrowth, a documentary by David Attenborough and the life and habits of invertebrates.

Thanks Netflix!

No Comments

The Nightlife Project – Part 1 – Introduction to the Problem

“A carelessly planned project takes three times longer to complete than expected; a carefully planned project takes only twice as long.”

The Nightlife Project is a novice PHP/MySQL tutorial. While you don’t have to know a whole lot to get started, you should understand the basics of PHP and MySQL. Knowledge of variables, functions and flow control is required. If the following block of code makes sense to you, you are ready to start the project:

<?php
repeat('foo', 15);
function repeat($string, $count) {
     for($i = 0; $i < $count; ++$i) {
          mysql_query("INSERT INTO `data` VALUES ('$string')");
     }
}
?>

Now, an explanation is due.

You work for Vision Nightlife, a nightlife promotion company working out of Las Vegas. Your company hires promoters to hand out nightclub flyers for the various clubs that have hired your company. These promoters give flyers to tourists for things like free entry to Domi Lounge, a free drink at Club Septuro, etc. Each flyer is stamped with a unique code identifying the promoter that drove the tourists to the club. The club will then pay your company, based on how many people your promoters drove to their club. The amount is based on how many people and what day of the week. For example, Hoodoo Lounge pays $1 per person on Friday or Saturday nights, if you bring between 1 and 10 people. If you bring between 11 and 20 people, it is $1.50 per person, and 21 or more people is $2.25 per person. On a Wednesday night, those amounts are cut in half. Your company wants you to write software to keep track of all of this information.

Your software needs to track clubs, promoters, payment rates, referral amounts and payout amounts.

This is just an introduction to the nightlife project. Part 2 will begin looking at the database structure and writing the ideal schema for each table.

, , ,

No Comments

This week on twitter – 2009-12-20

  • I've been seeing a lot of American Apparel ads lately. I may not be the most fashionable out there, but holy shit is that horrible fashion. #
  • After a few days away from the problem that was hurting my soul for 2 weeks, I'm back on it. Hopefully I can finish this thing soon. #
  • I got an email from Verizon about my $100 Droid rebate. Looks like all is well and they should be sending me the rebate soon. #

Powered by Twitter Tools

No Comments

Congratulatons Google Reader! You are the one app that is better on my phone than the computer!

I really need to find a new RSS reader. Google Reader, for all it’s strengths, is really starting to annoy me. I have 352 unread items with no manageable way to filter that list down. If I choose expanded view, they automatically mark as read upon scrolling past (good), but sometimes I have to scroll past 20 pages of images (mostly game screens, bad). If I choose list view, I can see just titles (good) but anytime I scroll down, more items pop up (bad). I cannot find a way to just view 30 or so item titles, and then click mark all as read and view the next 30… except on my Droid.

This is the one website that is more usable on my phone than on the site. All I want is an easy way to chew through these 352 items. Let me mark a chunk as read by title alone. Don’t force me to change my RSS reader over this.

If anyone knows a way to stop the list view from auto loading items on the bottom, I will kill one person of your choosing. Deal?

,

No Comments

Outlining My First Droid App – remind@home

The honeymoon with my Droid is over and now it is time to get crackin’ on some sweet code. The idea struck me as I was hard at work completely forgetting to do something I said I would do once I got home. I want to make an app that reminds me of something when I reach a specific location. At home – find a good, free Windows C Compiler; at the brewstore – by a non metal spoon; in Phoenix – stop by Total Wine and find some booze not available in Vegas. I know there are similar things out there and I could just tag along and help their stuff, but this project is all about the learnin’. So here is the outline for Droid App #1 – remind@home.

Also – if anyone likes the concept and wishes they could try it out now, go get Astrid. It does a lot of what I want to do, and best of all, it already exists. So once again, this project is for my own educational purposes. I know apps like this already exist, but alas, my education does not.

remind@home – A Droid application that allows a user to set short text reminders for the next time he is in a specified location. IIt will be a Locale plugin and use Locale’s ability to trigger events in locations and notify the user of all messages tagged with that location.

I will build the system in 5 phases. Each phase corresponds to a beta version number (0.1 – 0.5) and upon stabilizing 0.5, I will release remind@home as version 1.0.

Phase 1

  • Create locale plugin to act as a bridge between Locale and remind@home. The locale plugin simple adds a setting where you tell remind@home which tags fire off in this situation.
  • Make an interface for adding a note to a tag.
  • When locale triggers remind@home, display all reminder notes for this tag.

Phase 2

  • Provide option for notes to have delay timers, so they notify a certain amount of time after Locale triggers the tag.

Phase 3

  • When a note is displayed, allow options for handling the note. ‘Dismiss’ would delete permanently, ‘Store’ would keep the note in the notification bar until dismissed, ‘Snooze’ would hide the note for 15 minutes, ‘Repeat’ would put the note in queue for the next time the tag triggers.

Phase 4

  • Allow one user to send a reminder to another user who has authenticated him.

Phase 5

  • Create a system to request another user’s tags who has authenticated him.
  • Allow tags to be marked as public and private.

,

1 Comment

One user’s bug is another user’s feature

An interesting dilemma popped up at work today when a coworker filed a bug report on one of the systems my dev team oversees. This nifty little error was the direct result of a previous fix. Yeah, I know, we all fix things and break other things, but hold with me and you’ll get where I’m going.

My company runs in internal framework for whipping up client sites where the tech more or less drops premade text content through a web interface to generate pages. One of the techs noticed that when you save a new page, it puts you back to the screen to add a new page. He wanted to go back to the previous page so he could edit it. Bug filed, handled by me, now it returns you to editing the previous page upon saving.

Well, apparently not all of the techs dug this new system. They wanted to just drop in all of the pages before editing anything, and this “fix” messed up their groove. Today, one of them decided it was high time to file a report about it. So now I have two bugs, dueling for supremacy and the rights to be deemed “the right way”. Of course, I’ll fix it in a way that solves both issues and shuts up both camps, but it goes to show you, one user’s bug is another user’s feature.

No Comments

The first week of World of Warcraft Dungeon Finder

Last Tuesday, Blizzard launched patch 3.3 for World of Warcraft. With my highest level character at the time a 72 Restoration Shaman, my main interest in this new patch was the Dungeon Finder system that replaced the old Looking for Group system. Blizzard also added Tier 10 gear and a new set of end game instances, but since I wasn’t close to that stuff, I wasn’t concerned about those things.

Last Wednesday, I did a post about my initial thoughts on this system. In the days since that post, I have fallen in love with this new system and I must commend Blizzard on really pushing World of Warcraft forward. This new system not only renews my interest in World of Warcraft, but ensures that I will finally get to do all of those dungeons that I want to do, but was never able to get a group together.

The major thing that I like about the system is the speed with which I can find a group. Granted, this is because I am a healer and there aren’t as many healers as DPS, but that doesn’t change the fact that I often find groups within 2 minutes. Very rarely do I actually wait long enough to consider questing or rep grinding or herb gathering. When I want a group, I am in one very quickly.

As a result of this turnaround speed, I am often able to complete two dungeons per hour, which has quickly gotten me some pretty nice gear from the dungeon bosses. At the time of writing, my now 77 Draenei Shaman is geared about as well as can be expected and I am rapidly approaching level 80. This would be the first time I have reached end game in an MMORPG.

As far as the quality of players that I find, it is a mixed bag as you would expect. I have had a few amazingly competent groups that can knock out a dungeon in 20 minutes and I have had a few groups that are so wretched I had to leave and take the deserter debuff. The main problem that I  have run into is incompetent tanks that are unable to hold aggro and oblivious to enemies that make a move for the squishies. I occasionally get subpar damage dealers that target the wrong enemy or overnuke, but I can handle those much better than I can handle a bad tank.

In the past week, the general competency level has gone up. It seems many players that never ran dungeons are suddenly doing so and are having to take a crash course in how to work as a team. I am one of those players. My healing skills now are significantly up from a week ago, and I’m sure many other players have had the same experiences.

On a final note, Death Knights are, for the most part, awful. This class seems to be a magnet for bad players who have no idea what their role in a team is. I’ve had Death Knight tanks in Blood Presence who do more damage than anyone in the team (while letting the warlock and shaman get beat down right behind him) and Death Knight damage dealers that insist on attacking a target the tank has not built up sufficient threat on. Almost any time I join a group with a Death Knight, I wince and assume the worst. I’ve rarely been proven wrong. Also – Shadow Priests aren’t much better.

No Comments

This week on twitter – 2009-12-13

  • Climbing. I have a V3 to beat. #
  • What the fuck is ArrayObject? I'm now on day 9 of finding a solution to a certain problem. It long ago stopped being "fun challenging". #
  • Now I get to find a solution to Kohana's validation not working with multidimensional arrays. Yay? Yay! #
  • I despise mail in rebates. Verizon better not mess up this $100 for me. #
  • I need to buy a jacket tonight. It is raining. Cold rain. I have no jacket. #

Powered by Twitter Tools

No Comments

Filtering an array with a string mask in PHP

I’ve been working on a solution the Kohana problem of the Validation library being unable to validate cleanly inside multidimensional arrays, and the root of this problem is passing a mask to the Validation::add_rules() method to identify deeply nested elements. In the course of trying to work out this problem, I wrote a function that accepts a mask and an array and returns the filtered array. While it doesn’t get me any closer to my actual goal, I do think it is an interesting function nonetheless and could be quite useful in the right circumstances. In the future, I might tweak this to allow you to invert the results, whereby it deletes anything that matches the mask, rather than preserves those that match the mask.

An example of a mask would be “messages/*/timestamp” would only keep elements of the array that matched $array['messages'][*]['timestamp'] with * being a wildcard.

function array_mask_filter($mask, $array, $ci = false) {
    if(!is_string($mask)) {
        throw new exception('filter mask must be a string');
    }

    if(!is_array($array)) {
        throw new exception('variable to be filtered must be an array');
    }

    $mask_chunks = explode('/', $mask);

    $this_mask = array_shift($mask_chunks);

    if($this_mask != '*') {
        foreach(array_keys($array) as $key) {
            $key = $ci ? strtolower($key) : $key;
            $this_mask = $ci ? strtolower($this_mask) : $this_mask;
            if($key !== $this_mask) {
                unset($array[$key]);
            }
        }
    }

    foreach(array_filter($array, 'is_array') as $key=>$element) {
        $array[$key] = array_mask_filter($element, implode('/', $mask_chunks));
        if(empty($array[$key])) {
            unset($array[$key]);
        }
    }

    return $array;
}

,

No Comments