The Real Web on a Mobile

I have updated my actual-web-on-a-mobile program so that it copes with BBC Sport and various other sites better instead of giving an error.

The end result is that you have a text and links-only version of the web that will work on (some) mobile phones.

The program works by stripping all html except links and rewriting all links to point back at this server so those pages can be stripped once the links are clicked too.

You can search google and get the text of actual websites on your mobile without crashing your mobile’s browser or running out of memory here:

http://bluebones.net/miniweb/

You can enter a URL for stripping down to text and links only here:

http://bluebones.net/miniweb/?cmd=url

While you can use this service through your regular browser the reason this exists is for use with mobiles that understand HTML like the Nokia 7250i. You might be able to think of another use for these low bandwidth pages, please let me know if you do.

I’ve put up a snapshot of the source code but if you want the latest please contact me.

FileSystemObject Stops Working

Damn, just spent 30 minutes fixing a problem I first had in ASP over three years ago. The FileSystemObject just stops working and no error is reported. Just hangs forever. Then you need to do an iisreset or similar.

The problem is that Norton Anti-Virus’ “Script Blocking” doesn’t allow any use of the FileSystemObject. Even when it is set to “ask me what to do” when it encounters “scripting” it still just hangs. The simple fix is just to disable script blocking. Now I need to remember this for the next time.

Minimax with Alpha-Beta Pruning

When trying to understand minimax with alpha-beta pruning I found loads of Computer Science-type material on the web. But very little in the way of practical examples.

Hopefully my java Tic-Tac-Toe game with perfect AI that uses this technique will be useful to someone looking for a practical example.

If you have any questions, please put them in the comments here and I’ll do my best to answer them.

Ruby for Programmers

A minimalist’s guide to Ruby:

"strings", 'strings', :lisplikesymbol
Constant
variable
object.method()
Class::staticmethod()
$global
@instance_var
@@static_var
{ block }
do
       alternative_block
end
{ |block, args| at_beginning_of_block }
(1..3)
('a'..'z')
(0...5) # three dots = excludes last
['array', 'jfdlka']
{'hash' => 'dictionary', 'jfsdkal' => 'jfd9'}
/^regexp$/
nil
false
==
=== # if in range
if else end
"concat" << "enate"
check_for_nil.nil?

Generating Fixture Lists

Update 2007-03-21: If all you want to do is generate a fixtures list you can use my Fixtures Generator

I’ve been trying to find out how to generate fixture lists for some time (it is harder than it sounds!) and I finally worked it out thanks to this page about a fixture generating algorithm. My Java implementation of the algorithm is below.

/* 
 * This code owes an enormous debt to 
 * http://www.barrychessclub.org.uk/berger2001.htm 
 */

import java.util.Arrays;

public class Fixtures2 {

    public static void main(String[] args) {
        
        // Find out how many teams we want fixtures for.
        int teams = 0;
        try {
            teams = Integer.parseInt(args[0]);
        } catch (NumberFormatException e) {
            System.err.println("Please state number of teams as first arg.");
            System.exit(0);
        }
        
        // If odd number of teams add a "ghost".
        boolean ghost = false;
        if (teams % 2 == 1) {
            teams++;
            ghost = true;
        }
        
        // Generate the fixtures using the cyclic algorithm.
        int totalRounds = teams - 1;
        int matchesPerRound = teams / 2;
        String[][] rounds = new String[totalRounds][matchesPerRound];
        
        for (int round = 0; round < totalRounds; round++) {
            for (int match = 0; match < matchesPerRound; match++) {
                int home = (round + match) % (teams - 1);
                int away = (teams - 1 - match + round) % (teams - 1);
                // Last team stays in the same place while the others
                // rotate around it.
                if (match == 0) {
                    away = teams - 1;
                }
                // Add one so teams are number 1 to teams not 0 to teams - 1
                // upon display.
                rounds[round][match] = (home + 1) + " v " + (away + 1);
            }
        }
        
        // Interleave so that home and away games are fairly evenly dispersed.
        String[][] interleaved = new String[totalRounds][matchesPerRound];
        
        int evn = 0;
        int odd = (teams / 2);
        for (int i = 0; i < rounds.length; i++) {
            if (i % 2 == 0) {
                interleaved[i] = rounds[evn++];
            } else {
                interleaved[i] = rounds[odd++];
            }
        }
        
        rounds = interleaved;

        // Last team can't be away for every game so flip them
        // to home on odd rounds.
        for (int round = 0; round < rounds.length; round++) {
            if (round % 2 == 1) {
                rounds[round][0] = flip(rounds[round][0]);
            }
        }
        
        // Display the fixtures        
        for (int i = 0; i < rounds.length; i++) {
            System.out.println("Round " + (i + 1));
            System.out.println(Arrays.asList(rounds[i]));
            System.out.println();
        }
        
        System.out.println();
        
        if (ghost) {
            System.out.println("Matches against team " + teams + " are byes.");
        }
        
        System.out.println("Use mirror image of these rounds for "
            + "return fixtures.");
    }

    private static String flip(String match) {
        String[] components = match.split(" v ");
        return components[1] + " v " + components[0];
    }
}

Update 2005-06-05: Now allows “complementary teams”, that is – teams that never play at home at the same time as each other. For example, try 10 teams — for each pair from 1 & 6, 2 & 7, 3 & 8, 4 & 9, and 5 & 10, both are never both at home. It was meant to be in the original program but a bug in my code was fouling things up.

Update 2007-03-21: You might also want to see the source code to my PHP fixtures generator

Perfect IDE

My perfect IDE/text editor has the following features:

  • Java support. And extensible to support other languages. Preferably has existing libs/files for Perl, C#, Ruby, Python, PHP, ASP/VBScript.
  • Runs on Windows. Preferably cross platform for when (if) I make a jump to Linux or OS X as my main platform, and for when I am dabbling in those platforms.
  • Brilliant regex support.
  • Code completion. Intellisense (as in Visual Studio) where it understands the object model and supplies only methods of an object (for example) that exist on that object.
  • Unlimited undo.
  • Fast. Starts fast and stays fast when running.

To me that doesn’t look an unachievable list but my prime candidates all fall short:

Ultraedit doesn’t have the IDE-defining capability of understanding what the text files it is working on mean, therefore it cannot do Intellisense.

JEdit is too slow and Intellisense support is patchy and from a third party.

Visual Studio is just about there but only supports .NET languages.

IntelliJ IDEA is great, if very large/slow. But it only does Java.

My only hopes are Emacs (which doesn’t feel like a Windows application when running on Windows) and Eclipse (which at least aspires to supporting many languages though it is slow and uninituitive). I will investigate both of these further.

Basically I want Ultraedit (or any other really good text editor) with Intellisense. Or failing that Visual Studio/IntelliJ IDEA with support for all languages. Any suggestions?

Jobfight

I’ve added the ability to compare two keywords (and see which has more jobs attached) to my jobfight page.

Like googlefight, but for jobs.

The statistical record of how many jobs are available by keyword that I have been running for the past two years is still there, also.