Tag Archives: Software development

Watch Steam for price drops

This could probably be done a little better, but the core idea is here: Watch a set of specified games on Steam and, if the price drops, send out a notification email. Set this up on a daily cron job and you’ll be notified when the game you’re looking for drops in price. Might be months, but it’ll likely happen.


$games = array(
    "Batman: Arkham Asylum" => array(
        "id" => 35010,
        "known" => "$49.99 USD"
    )
);
foreach ($games as $name => $values) {
    $doc = new DOMDocument();
    @$doc->loadHTMLFile(
        "http://store.steampowered.com/app/{$values['id']}/"
    );
    $current = $doc->getElementById("game_area_purchase") \
        ->getElementsByTagName("div")->item(1)->nodeValue;
    if ($current != $attributes['known']) {
        mail(
            'youraddress@example.com',
            'Price drop on steam',
            "$name dropped to $current"
        );
    }
}

Maybe better would be to collect the price from each day over a set of games and graph this data over time. It’s not necessary, but I’d be curious to see that extension of this idea.

Open Data in Vancouver

Some months ago, a co-worker pointed me towards VanMap, an online tool that provides fine detail on the City of Vancouver: property lines, zoning information, sewer mains, etc. The down-side to this site is that it only functions in Windows and that the underlying data isn’t directly available.

Fortunately, there’s talk of opening the city’s data in a permissive licensing model like the Creative Commons. Andrea Reimer‘s talk this evening about the progress towards that goal was informative, considering I wasn’t aware the problem was being worked on.

Brought up during this talk was the September 16th Hackathon. I’m not 100% clear yet on what the focus will be, but it’s there for the curious. One of their previous projects is VanTrash, which is a neat tool that can remind you when your trash pickup is. Pretty sweet, eh?

vantrash

Update

Looks like Vancouver’s Open Data Catalogue is up in beta form. Go take a look for it is super.

Database encoding correction script

Sometimes we run into databases that aren’t encoded properly. The following is just one method of fixing a very specific type of improper encoding: doubly encoded characters from Latin-1 to UTF-8.


Download

All it’s really doing is enumerating the conversion pairs and running “update $1 set $2 = replace($2, ‘$3′, ‘$4′)” on them.

Action throttling with memcache

Attached is a decent way of throttling user actions without storing a complete log of activity. All we do is store when the user last did something and how tired we are of seeing that user. When the user makes a second request, we throttle the user less based on the amount of time that’s passed.

I’d argue that this is a better way of doing it than WordPress’ default check_comment_flood_db function, as it allows occasional bursts of activity.

Colour-shifting backgrounds

The attached example demonstrates how you can smoothly change a theme’s colour using jQuery and jQuery Color. I’m not a design guru by any means, but I think the idea is sound: develop your images to show the highlights and shadows using transparent PNGs and shift the colour of some background class. You could even shift a set of colour classes to get complimentary colours going on.

I get that this won’t work in IE6 and is limited in the visual effects that it can produce, but it’s an interesting toy to consider.

Open source expectations

Let’s say you want some kind of change to a piece of open source software you use. There are a couple of options available.

  • Do it yourself
  • Convince someone to do it for you
  • Wait for someone to do it independent of your desire

The first option requires the skill to implement the change and the motivation to get it done.  The second requires some kind of leverage, which usually comes in the form of hiring a developer. Still, if you’re not capable of doing it yourself and you aren’t willing to hire someone to do it for you, what option is there but to wait? Open source projects grow on their own and reasonable concerns will likely be addressed in time.

While this seems relatively clear, I’ve seen a fair amount of expectation roughly paraphrased as “why aren’t people making the changes I asked for?” Simply put, the priorities of open source developers are different from those of the users. If patience doesn’t suit, try taking another look at options one or two.

Project management software

I’ve been looking around at the various options for project management software. My experiences started with Bugzilla, meandered around various proprietary solutions and eventually landed on Trac. For the longest while, Trac did everything I needed it to. That is, until I discovered Redmine.

Features that Redmine comes with out of the box

  • A clear and malleable issue tracking system
  • Multiple projects, each with access role settings
  • Per-project forums and wikis
  • Repository integration with Subversion and Git

Of the other packages I looked at (JIRA, Fogbugz et all), none of them provided the same intuitive interface. Maybe it’s because I’m coming from a Trac background, but Redmine was effortless to step into. If you haven’t given it a shot, I highly recommend it.

The pitfalls of framework integration

Consider the following scenario. You’ve been tasked with developing an application with whatever resources you see fit. This application has two main branches of functionality in which there’s reasonable overlap. After some investigation, you find three frameworks worth considering.

Task A Task B
Framework A Excellent Poor
Framework B Poor Excellent
Framework C Good Good

Assuming all else is equal, there’s no clear winner between these frameworks. How do we decide what’s best in this situation? A member of the Drupal community asked this very question back in 2005, specifically with MediaWiki, PHPBB and Drupal.

I would argue that there are overlooked costs in integrating frameworks A and B. While it does result in an application that excels at both tasks, the overall complexity of the system is increased and we begin to run into some fairly common issues.

  • Single sign-on and sign-off. Authentication should be persistent between both systems. If a user logs into one, consistency would dictate that they be logged into the other (likewise with logging out).
  • Model parity. If Framework A relies on some internal model that overlaps on both tasks, then that model will need to be translated and synchronized into Framework B and vice versa. A simple example is user accounts, but we can envision more complex examples such as replacing MediaWiki talk pages with PHPBB forums.
  • Task appendices. Since Framework A will be used exclusively for task A, this task must be disabled in Framework B. Alternatively, requests for task A in Framework B could be redirected, but this requires careful mapping and possibly, as mentioned above, model parity.
  • Increased custom code. It’s likely that neither of the frameworks have been specifically designed as a plugin for the other. As such, it will be necessary to write custom code to glue the two together. Whether or not this code can be written as plugins depends on individual frameworks considered.
  • Incoherent user interface. While not a functional requirement, it can be aesthetically jarring for users to move back and forth between two interface designs. Care can be taken to make one look like the other, but ultimately the two frameworks are likely to diverge on some design choices.

Integration of two mature frameworks is often a messier task than predicted and alternatives should be considered before committing to that approach. Framework C may never be the best at either task, but it demonstrates that it’s addressing their functionalities. It’s the coherence of a single system that leads to a cleaner, more manageable application.

Conditional content

The attached example demonstrates how you can display different views of content based on the context of a dragged block. Using jQuery’s sortable functionality, we can drag blocks from one list to another. These lists then define the contexts in which we display a specific content via CSS.

I gather this approach wouldn’t be ideal when each node has a lot of content and blocks aren’t moved frequently; An ajax approach might be better in that scenario. Trickier modifications can be applied to this basic principle, wherein you display and hide sub-nodes selectively within each block (e.g. hiding a column in a table, non-summary paragraphs, etc).

Recovering from and preventing software rot

Wikipedia’s article on software rot puts forth a familiar example. An application instance is deployed into the wild and is customized to meet the specific needs of its user-base. Over time, this fork is maintained by a series of individuals that inevitably increase its complexity. With small development teams and any standard amount of turnover, the new system will drift to the point where it’s too architecturally distinct to merge back into the base code. This is the dangerous position I’d like to speak to.

The key issue is that the base code’s development will continue without you. It doesn’t sound bad at first until a bug fix, performance optimization or fancy new feature is developed that your end-users want. When you write these yourself, you’re wasting time playing catch-up, throwing away a free development team. On top of that, the base code might get a new internal API making certain features trivial to implement that are infeasible in your fork.

If you get to this point, you need to look into migrating your data to a new system.

  1. Determine the key features that make up your application. Ignore the eye-candy and focus on the functional requirements.
  2. Compare these requirements to the features in the latest version of the base code. Does the new version support a reasonable plugin architecture? Chances are it didn’t at the time you forked, otherwise you wouldn’t be in this mess. Consider alternate code bases that are friendlier to module development.
  3. Build a prototype in the best-fit framework and confirm that it meets the requirements from the first step. It doesn’t need to look the same as your legacy system; It just needs to accomplish the same goals.
  4. Transition data and only data from your legacy system. You’ll need to map the two datasets and build a conversion script, which could take months depending on the complexities.

There are a number of frightening unknowns with this process. You don’t know how long the total transition time is going to take. Key features might need to be rebuilt from scratch using the plugin system. Database compatibility issues might arise while transitioning your data. These concerns make modernizing your application risky, but their risk is less than that of the issues you’re already dealing with. In the long term, the development investment pays for itself.

The heuristic I’m getting at is to keep things as simple as possible and you can do that by offsetting a large portion of development to an external community. This helps minimize the number of complex components you need to be concerned with, resulting in an application that’s easier to understand for current and future developers.