CyanogenMod, there and back again

I own a Samsung Galaxy III (I9300), which has been my primary phone for just over two years. It takes care of the job, and I’m happy enough with it that I chose not to upgrade when my contract expired.

However, a few months ago I became increasingly annoyed with it:

  • Some apps would start updating and never finish, even after a restart
  • The keyboard became laggy, which can really drive you crazy
  • It has all these Samsung apps that I never use but cannot uninstall (classic example of Bloatware)

So I wanted to try a clean, stock Android install, without any bundled apps, to see if I get better performance. Turns out finding a “stock Android install without any bundled apps” that is sure to work on my phone is impossible or at least non-trivial. The core Android code is released publicly, but you still need someone to bundle it with the appropriate drivers and the essential apps you need to make the phone usuable.

A search for recommended open source, non-stock, Android builds lead me to CyanogenMod, which is most of the forums and blogs I went through recommended as the most stable and usable of the options out there.

I tried it for a few months, and switched back to the stock Samsung build this week. Below are my observations, all of which are anecdotal and not at all scientific.

Installing CyanogenMod

Installing CyanogenMod on my phone was really easy and hassle-free. Basically you download something on the phone, you download something on your PC, connect the two, and click a few buttons. The rest is all automatic, and worked first time, no issues. Very impressive.

Experience using CyanogenMod

The good:

  • The phone felt fast, snappier, more responsive, which I really enjoyed
  • Battery life definitely improved, lasting around 20% – 50% longer
  • The CyanogenMod UI is nice – homescreens and settings are organised in a slightly different way from the standard Samsung build, and I found it an improvement. You can take pictures from the lock screen, which come in handy to quickly capture something.
  • No bloatware!

The bad:

  • Google Talkback crashed on every use attempt.
  • Taking a photo and then hitting share works fine, but if you’re already in, say, WhatsApp, and then hit Attach -> Camera, it crashes. Same with Facebook.
  • Playing videos from within an application is broken. Clicking a video link in the Facebook app would open a page that never loaded. The same with BBC News videos and video links in the reddit app I was using.
  • Not something CyanogenMod can fix – but not using the standard Samsung Android build meant my employer’s security policies prohibited me from connecting to the corporate network, which meant no more e-mail on my phone, and no more calendar either – I was late for so many meetings – (sorry guys!)

Finally I became too annoyed with the inability to watch videos from within another app, and decided to switch back.

Switching back to the Samsung build

Switching back to the standard Samsung Android build was somewhat more tedious than switching to CyanogenMod. It involved:

  • Registering on so I could download the correct image to install.
  • Downloading Odin to flash the phone with the new image.
  • Following the instructions in this silent movie.

Overall, I am impressed by CyanogenMod, as a free, open project. It seems reasonably stable, and definitely has some improvements over the stock Samsung build. In the end, however, a small number of bugs made me switch back.

Posted in General Technical | Leave a comment

Reblog: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets

No full blog post this time. I just wanted to point you towards an excellent article I read yesterday, by Joel Spolsky: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

The article provides a short and highly readable intro to the different ways text can be encoded, and why the concept of “plain text” is not only a myth, but a dangerous myth. The article itself dates from 2003, but the information is definitely still relevant, and I am ashamed to say that I have been ignorant of the implications of text encodings for a long time. I don’t know if Joel’s threat to make me “peel onions for 6 months in a submarine” is still valid, but if it is, I best start packing.

It’s an absolute must read if you ever write any code at all. It won’t give you all the answers, but will hopefully leave you knowing what you don’t know, and that, I believe, is half the battle.

Now go click that link!

Posted in Software Development | Tagged , , | Leave a comment

Simple Python script that runs SQL scripts against a given SQLite database

Many of the search hits for my blog are along the lines of “python sqlite script”. I really hope those folks find what they are looking for.

I thought I might add this really simple script to run SQL script files against a SQLite database. I use this script all the time. Especially when I only want to make a tiny change to my database to test something, I find find it faster and more convenient to quickly type the SQL into a text file and run a python script from the command line, than it would have been through some SQLite interaction GUI. It becomes especially convenient if I use it alongside LINQPad – I can make changes using the command line, and run queries via LINQPad.

The script is really simple and requires no explanation, just some warnings. It targets Python 2.7 and won’t work in Python 3 as is. The exception handling does nothing except tell you “something” went wrong.

It doesn’t do queries – it only runs scripts against the database but reads no values back. But you can use it for create, insert, update and delete.

The script should be ready to use as is, and the command line is as follows:

python.exe .\ script.sql database.sqlite

If the database file does not exist, it will be created, so you can use this script to create a new SQLite database.

Below is the code, hosted in a gist – if you improve on this by adding better exception handling or whatever, please submit the changes, so we can all benefit Smile

Hope this helps!

Posted in Software Development | Tagged , , , , | 2 Comments

Hootsuite Hootlet causing problems with WordPress code snippets

Last night I reviewed one of my blog posts, and noticed that the source code samples were all scrambled in some places. I eventually figured out that it was the #region and #endregion tags that got messed up. I was surprised that I had not noticed it before, and changed the region tags to comments as a temporary solution.

This morning, on closer inspection, I noticed something suspicious in the scrambled snippets…

The original

Below is an actual code snippet – whether it is scrambled or not will depend on your browser.

public class MyClass
	#region Constructor

	public MyClass() { }


Here is a screenshot of the code for that snippet:


The problem

When I view that snippet as a draft post in Google Chrome, I get the following result:


Those class=”_hootified” statements were what made me suspicious. I had recently installed Hootsuite’s Hootlet browser extension for Google Chrome. I know Chrome uses no extension in incognito mode, so I popped open an incognito window and loaded the exact some page:



So apparently Hootlet is trying to do something clever with anything marked with a #, probably assuming it’s a Twitter hashtag (like there existed no hashes online pre-Twitter!).

I’m a bit relieved that the error wasn’t in my actual blog source, but I am also concerned that the rendering of those snippets are so unpredictable – how sure can I be that my readers are seeing my code snippets the way I intended?

I’m also not sure who  I should take this up with. Hootsuite? Chrome? WordPress? Rich Hewlett who wrote the WordPress source code plugin for Windows Live Writer? (Thanks Rich, it’s awesome!)

I’ll post an update once I got this figured out!


I posted about this on the HootSuite forum, and I’m impressed – I got a response in less than 12 hours. They suggest turning off the “Link Twitter status and user profile handles into the HootSuite dashboard” feature by right clicking on the extension icon and selecting Options:

While I appreciate the workaround, I hope they fix this on their end – another reader of my might have the same extension installed and not know about this effect, assuming instead that my code is quite bizarre!

Posted in General Technical | Tagged , , , , , , | 2 Comments

Organising custom Commands in a WPF TreeView using the Model-View-ViewModel design pattern

In my current project’s interface, the main elements of the GUI are a TabControl holding any number of workspaces, and a side panel with commands to launch the desired workspaces. It is closely based on a MVVM demo I saw, where the commands are displayed as a list of hyperlinks. However, since I have many possible workspaces, and they are logically grouped together, I wanted the side panel to list the available workspaces in a collapsible TreeView, and have the user open the desired workspace by clicked the corresponding command link.

In this post I will show you how I put together a tree of commands that can be modified at runtime, using the Model-View-ViewModel (MVVM) pattern. The result looks something like this:


The Model-View-ViewModel Design Pattern

MVVM is an interface design pattern is ideally suited for use with WPF, due to the way WPF GUI code binds to data and refreshes the display. I am not going to explain or demonstrate the MVVM pattern here – if you are unfamiliar with it, check out Josh Smith’s excellent introduction over at MSDN. My code here is based closely on the Demo Application code available in that article.

Putting Commands in ViewModels


In his article’s demo code, Josh uses a RelayCommand class, which implements ICommand, to wrap actions that can be invoked by the View. The ViewModel then hosts a RelayCommand, and in the View, a button or hyperlink binds to the RelayCommand. Some action is performed by the ViewModel when the command is invoked. You can find the source code for the RelayCommand class in Figure 3 of Josh’s article. Here I will just show how it is used, as this will make the rest of this post make more sense. Below is the ViewModel’s initialisation of a RelayCommand, and beneath that the binding to that command by the View:

// In the ViewModel:

private RelayCommand _demoCommand;

// Command Property:
public RelayCommand DemoCommand
        if (_demoCommand == null)
            // Initialize the command using a lambda expression:
            _demoCommand = new RelayCommand(param => DemoCommandTarget());

        return _demoCommand;

private void DemoCommandTarget()
    // Do stuff that you want the command to do...
        <!-- In the View: -->

        <Button Command="{Binding Path=DemoCommand}">Click Me!</Button>


Josh then goes a step further by declaring a ViewModel for commands, allowing him to define a default DataTemplate for displaying command links to the user. The CommandViewModel wraps the RelayCommand, which is injected upon construction. It further exposes a DisplayName property (which is implemented in the ViewModelBase class). Binding in the View is then to the CommandViewModel, rather than directly to the RelayCommand. Below is a slightly simplified version of the CommandViewModel from Josh’s article, which we are going to be modifying soon:

// Represents an actionable item displayed by a View.
public class CommandViewModel : ViewModelBase
    public CommandViewModel(string displayName, ICommand command)
        base.DisplayName = displayName;
        this.Command = command;

    public ICommand Command { get; private set; }

Grouping Commands into a Tree

In order to group CommandViewModels into a tree structure, we declare two more classes. We declare CommandTreeItem as a new abstract (and empty) baseclass for CommandViewModel, as well as a new CommandTreeGroup class. We let the CommandTreeGroup class expose an ObservableCollection of CommandTreeItem baseclass instances, thus allowing it to hold both CommandViewModel instances and more CommandTreeGroup instances. The code is below, but if your head is spinning from all these class names (mine is), check the image below the code for a class diagram that hopefully makes everything clear:

public class CommandTreeGroup : CommandTreeItem
    //region Fields

    private ObservableCollection<CommandTreeItem> _commandTreeItems;


    //region Constructor

    public CommandTreeGroup(string displayName)
        this.DisplayName = displayName;


    //region Properties

    public ObservableCollection<CommandTreeItem> CommandTreeItems
            if (_commandTreeItems == null)
                _commandTreeItems = new ObservableCollection<CommandTreeItem>();

            return _commandTreeItems;


The updated class structure now looks like this:


Initializing the Command Tree

We can now expose an ObservableCollection of CommandTreeItems in the MainWindowViewModel (lines 19-32), and fill it up with commands, groups of commands and subgroups of commands (lines 39-63). The code below creates the commands shown in the example tree at the very top of this post:

/// <summary>
/// ViewModel for application's main window.
/// </summary>
public class MainWindowViewModel : ViewModelBase

    //region Constructor

    public MainWindowViewModel()
        base.DisplayName = "MVVM Command Tree Demo";


    //region Properties

    private ObservableCollection<CommandTreeItem> _commands;

    public ObservableCollection<CommandTreeItem> Commands
            if (_commands == null)
                _commands = new ObservableCollection<CommandTreeItem>();

            Console.WriteLine("Commands queried, returning {0} items", _commands.Count);

            return _commands;


    //region Command Creation

    private void CreateInitialCommands()
        // Create a groupless command:
        CommandViewModel groupLessCommand = new CommandViewModel("Groupless Command", new RelayCommand(param => Console.WriteLine("Clicked Groupless Command")));

        // Create a Group:
        CommandTreeGroup group1 = new CommandTreeGroup("Command Group");

        // Add some Commands to the Group:
        CommandViewModel commandA = new CommandViewModel("Command A", new RelayCommand(param => Console.WriteLine("Clicked Command A.")));

        CommandViewModel commandB = new CommandViewModel("Command B", new RelayCommand(param => Console.WriteLine("Clicked Command B.")));

        // Create an inner group inside the first group:
        CommandTreeGroup innerGroup = new CommandTreeGroup("Inner Group");

        // Add a command to the inner group:
        CommandViewModel innerCommandB = new CommandViewModel("Add More Commands", new RelayCommand(param => this.AddCommand()));

    private void AddCommand()
        // Add a second groupless command:
        CommandViewModel newGrouplessCommand = new CommandViewModel("New Groupless Command", new RelayCommand(param => Console.WriteLine("Clicked New Groupless Command")));



In the code above, most commands are just lambdas that print out the command name when invoked, with the exception being innerCommandB, which calls AddCommand() to add another command to the tree at run time. Because the root list and the sub lists are all implemented as ObservableCollections, the View will automatically update to show the additional command.

Displaying the Command Tree

The rest of the niftiness happens over in the View, which really isn’t all that complicated. Here is the complete view code, with comments below:

<Window x:Class="MVVM_CommandTree_Demo.View.MainWindow"
        Title="{Binding DisplayName}" Height="600" Width="800">
        <TreeView ItemsSource="{Binding Path=Commands}">

                <DataTemplate DataType="{x:Type vm:CommandViewModel}">
                            <Hyperlink Command="{Binding Path=Command}">
                                <TextBlock Text="{Binding Path=DisplayName}" />

                <DataTemplate DataType="{x:Type vm:CommandTreeGroup}">
                    <TreeViewItem Header="{Binding Path=DisplayName}"
                                  ItemsSource="{Binding CommandTreeItems}" />


We start off in line 7 with a TreeView, for which we bind ItemsSource to the ObservableCollection of CommandTreeItem instances in the MainWindowViewModel, to form the root of our command tree.

We then declare two DataTemplates to tell the TreeView how to display a CommandViewModel and a CommandTreeGroup respectively.

DataTemplate for Commands

The first DataTemplate, for CommandViewModel, is intended to display the tree’s leaf nodes – the actual commands. It renders a TreeViewItem with a Hyperlink as header. The Hyperlink Command binds to CommandViewModel.Command, while the Hyperlink Text binds to CommandViewModel.DisplayName:

<DataTemplate DataType="{x:Type vm:CommandViewModel}">
            <Hyperlink Command="{Binding Path=Command}">
                <TextBlock Text="{Binding Path=DisplayName}" />

DataTemplate for Command Groups

The second DataTemplate, for CommandTreeGroup, is intended to display sub groups of commands. It renders a TreeViewItem with a plain text Header, bound to CommandTreeGroup.DisplayName. In addition, the TreeViewItem’s ItemsSource is bound to the ObservableCollection of CommandTreeItems in the group, thus creating the next set of branches and leaves:

<DataTemplate DataType="{x:Type vm:CommandTreeGroup}">
    <TreeViewItem Header="{Binding Path=DisplayName}"
                  ItemsSource="{Binding CommandTreeItems}" />

That’s it!

Super simple stuff! I hope that was useful. You can download the complete demo code here. Please leave a comment below, and let me know if something didn’t make sense or if you have ideas of awesomeness to add!

Update: I get quite a number of hits on this page, as well as a number of downloads for the demo code, and I’m always left wondering “Did you find what you were looking for? Did this help you?” If it did (or did not), please leave a comment, I would love to know!

Posted in Software Development | Tagged , , , , , , , , , , , | Leave a comment

Quick and easy way to insert a PDF graph or diagram into a Microsoft Word Document without losing too much quality

I had to solve this one for my boss today, and thought I would make a quick post with the solution I found.

The Image Quality Problem

In our line of work, when we want to include a PDF in a Word document, 9 out of 10 times it is a diagram or a graph. Word does not take kindly to this (I’m using Word 2010, Your Mileage May Vary). The image quality of an imported PDF document is greatly reduced when inside a word document.

The solution I found is to print the PDF diagram to a PNG image, using the Bullzip PDF Printer, and then to insert the PNG image in the Word document. I’ll use a series of screen shots to illustrate the problem and the solution.

Below is a screenshot of the original PDF diagram. Isn’t it lovely?


Inserting the PDF directly

There are two ways of directly inserting this PDF in a Word Document. One is to simply drag and drop the PDF file onto Word, the other is to use Insert – Object. Whichever way you choose, the result has really low quality:


(In case you’re wondering, I took the above screenshot after printing the Word document to PDF, so that is the actual output quality.)

Converting the PDF to PNG before inserting it

If we first print the PDF to PNG and then import it to Word, the result looks like this:


Much better!

How to do it

First of all, download and install Bullzip PDF Printer from here. It’s excellent, and it’s free! After installation, it will show up as a printer on your machine.

Next, open the original PDF diagram in Acrobat Reader, and go to File – Print. On the Print dialog, set the Printer to Bullzip PDF Printer. Also set the Size Options as shown below, to avoid ending up with lots of white space around your diagram:


After hitting Print, the Bullzip PDF Printer – Create File dialog will pop up. Here the important thing to change is the Format, which we set to PNG:


You can also set the output File Name. After hitting Save, you are left with a *.PNG file at the location of your choosing. You can now simply drag and drop this image onto Word to have much higher image quality than the PDF would have given you. There you go!

The way it should be

All of this back of forth between Python (which I used to generate the plot), Acrobat Reader, Bullzip and Word makes me miss them good-ol’-days, when I was working on my thesis.

Back then, working on a Linux machine,  I had Python generate plots and export them to *.eps (Encapsulated PostScript) files, which could be linked directly into my LaTeX document for perfect output to a *.ps or *.pdf document. The greatest advantage of that approach is that updates to the plot can be pushed all the way to your final document by running a single script, with no manual PNG printing, changing of settings, or dragging and dropping. That really is the way it should be, especially when working with plots and diagrams that depend on data, which might change at the last minute.

Posted in General Technical | Tagged , , , , , , , | 10 Comments

A Python script that finds and runs other Python scripts (which I use to build my SQLite database)

My, what an unwieldy blog title.

While working on my current project, I wanted to be able to generate and fill my SQLite database from scratch, in an instant, by calling a single script. I found a convenient way of doing this is to have a folder of Python scripts – each script does something to the database, typically creating a table and filling it with initial data which it reads from a text file.

As development continues, I’m constantly adding more tables or more data, so  I wanted new scripts in that folder to automatically be include in the database building process. To do this, I wrote another script to find and run everything it finds in that folder. This has been very convenient, and has saved me a lot of effort over the past couple of months. It works like this:

  1. I call, giving it a reference to the database file and a reference to the folder containing the scripts I want to run.
  2. scans the script folder for files that match Script*.py, and loads them all.
  3. opens a connection to the database. It will create the file if it does not already exist.
  4. iterates over the loaded scripts, passing each of them the open database connection.
  5. closes the database and prints a little run report.

Here is the directory structure for a contrived example with only two database scripts:

 |-- scripts

The Database Scripts

Before we get to, lets have a look at the subject scripts that are run by it. Here is the code for, a simple script that creates a new table in the database:

Name = "Script Two"

def CanRun(connection, listOfExecutedScriptNames):
    ''' Return False if this script can not yet run, True if it can.'''
    return True

def Run(connection):
    print "\n\tStarting %s Script" % Name

    dbCursor = connection.cursor()

    # Create table:
    SQLScript = r"""
                                [DemoString] TEXT NOT NULL ) """


    print "\tCreated DemoTable"

    print "\tEnd of %s Script" % (Name)

There is a bit an interface that expects the database scripts to adhere to:

  • The Name property in line 1 is needed by for reporting failures and for ensuring the scripts execute in the right order.
  • The CanRun function in line 3 is called by before the script is run – the script can implement custom code here to make sure any prerequisites have been satisfied. It receives an open connection to the database, and a string list of Names of those scripts which have already been run. below demonstrates the use of this.
  • The Run function in line 7 is called by, and is where the meat of the script goes. It receives an open database connection.

Below is the code for, which adds some data rows to the table created by

Name = "Script One"

def CanRun(connection, listOfExecutedScriptNames):
    ''' Return False if this script can not yet run, True if it can.'''
    if "Script Two" not in listOfExecutedScriptNames:
        return False
        return True

def Run(connection):
    print "\n\tStarting %s Script" % Name

    dbCursor = connection.cursor()

    changesPre = connection.total_changes # Count Changed Rows

    dataToAdd = ["These", "Are", "Some", "Strings", "To", "Add", "To", "The", "Database"]

    for word in dataToAdd:
        # Write to DB:
        cmd = "INSERT INTO DemoTable VALUES (null, ?)"
        values = (word,)
        dbCursor.execute(cmd, values)


    changesPost = connection.total_changes # Count Changed Rows
    changes = changesPost - changesPre # Count Changed Rows

    print "\tAdded some rows to DB"

    print "\tEnd of %s Script" % (Name)

Of interest here is the fact that CanRun now checks that has already been run – it needs the table to be created before it can add rows. CanRun uses the Name assigned to and the listOfExecutedScriptNames received from to check this. If has not been run, CanRun returns False – will then move on to the other scripts before returning to this one.

This empty file is needed for Python to recognise the scripts  folder as an importable module.

The launcher script:

Below are the two major functions of the launcher script. You can view and download the full script code here.

Loading the script files as modules

The LoadScripts function scans the script folder for Script*.py files, loads them, and returns a list of loaded modules:

def LoadScripts(scriptFolder):
    ''' Returns a list of module references '''
    # Find Script Files:
    scriptFiles = glob.glob(os.path.join(scriptFolder, "Script*.py"))
    print "Found %d Script Files" % (len(scriptFiles))

    # Load scripts:
    loadedScripts = []
    for scriptFile in scriptFiles:

            # Get full module name:
            scriptName = os.path.basename(scriptFile)
            scriptName = os.path.splitext(scriptName)[0]
            folderName = os.path.basename(scriptFolder)
            fullModuleName = "%s.%s" % (folderName, scriptName)

            # Import Script:
            script_module = __import__(fullModuleName, fromlist=["fullModuleName"])

            # Store reference to Script:

        except Exception, e:
            print "Something went wrong while loading script file \'%s\'" % scriptFile
            print e

    return loadedScripts

Line 21 forms the full module name of each script, which consists of the folder name and the filename, e.g. scripts.Script_One. It pops the module name in a variable, and the name of this variable is then put in a single element list given to the actual __import__ call in line 24.

If the subject script file fails to parse due to syntax errors or such, the error will be caught in line 29, and the next script loaded.

Running the loaded scripts

Actually running the loaded script is a simple matter of getting a reference to the module object created in line 24 above, and calling the function you want, in this case the Run function shown in the and samples:


Most of the code in the RunScripts function deals with making sure each script gets run, that they run in the right order, that there are no circular dependencies between scripts, and that the results are reported. Here is the code, with some comments below:

def RunScripts(databaseFilename, loadedScripts):
        # Open DB:
        connection = sqlite.connect(databaseFilename)

        # Keep a list of completed scripts so scripts can test if they are ready to run:
        namesOfCompletedScripts = []
        success = True
        # Keep passing over list until everything has been run:
        while (len(namesOfCompletedScripts) < len(loadedScripts)):
            nothingExecutedOnThisPass = True
            # Iterate over scripts:
            for script in loadedScripts:
                    # Check if this script has been run or not:
                    if (script.Name not in namesOfCompletedScripts):
                        # Ask script if it is ready to run -
                        # - give it a list of completed scripts:
                        if (script.CanRun(connection, namesOfCompletedScripts)):
                            # Run script:
                            nothingExecutedOnThisPass = False
                            print "\n%s not ready to run" % script.Name

                except Exception, e:
                    print "Something went wrong while running script %s" % script.Name
                    print e
                    success = False

            if (nothingExecutedOnThisPass):
                # If nothing executed on this pass, we're stuck -
                # - the remaining scripts won't run

        print "\nThe following scripts were successfully run:"
        print namesOfCompletedScripts

        if (len(namesOfCompletedScripts) < len(loadedScripts)):
            print "Some scripts failed:"
            for script in loadedScripts:
                if (script.Name not in namesOfCompletedScripts):
                    print "\t" + script.Name

    except Exception, e:
        print "Something went wrong while applying scripts to DB"
        print e
        # Close DB:

The database connection

The database connection is opened in line 38. This connection is then passed to each script’s CanRun function in line 53 and to each scripts Run function in line 55. Finally, it is closed again in line 85.

Running scripts in the correct order

Some scripts may depend on database elements created by other scripts – in this example, must create the DemoTable table before can add rows to it.

Each script is allowed to check it’s own prerequisites in its CanRun function, called in line 53. To assist it, RunScripts keeps a list of successfully completed scripts’ names in namesOfCompletedScripts. It also provides CanRun with a database connection, in case the subject script wants to manually check the structure of the database.

If a script indicates that it is not ready to be run, RunScripts skips over it and continues iterating over the rest of the scripts. It then keeps returning for another pass, revisiting all those scripts not yet listed in namesOfCompletedScripts. This includes both those scripts that were previously not ready to run, and those that raised errors during execution.

In the two script example given here, the first pass skips over due to not having been run. On the second pass, detect that its prerequisites are satisfied, and successfully executes.

RunScripts will continue to pass over the list of scripts until all have been executed. However, a CanRun requirement that cannot be satisfied, or a script that persistently raises an error upon execution, will cause this loop to be infinite. To halt execution in these cases, RunScripts monitors the boolean variable nothingExecutedOnThisPass, which is set to True at the start of each pass, and negated as soon as a script successfully completes. If an entire pass completes without a single script being successfully run, the remaining scripts will never be ready to run. Execution is halted, and the list of failed scripts is printed in lines 72-76.

There you have it

I found this an easy and straightforward way to automate the execution of new scripts. It frees the developer from manually adding scripts to the execution list, and also solves order-of-execution problems automatically. While it was used for database building here, I’m sure to use the same code in future for any scenarios where I have a rapidly changing list of scripts to run.

If you find this helpful, or have any cool ideas, please do leave a comment!

UPDATE 2013-02-28: I figured out that pysqlite2 is deprecated and has been replaced by the sqlite3 library, which is bundled with Python 2.5 and up by default, and thus requires no download. I’ve removed the links to pysqlite2 and modified the downloadable script to use sqlite3 instead.

Posted in Software Development | Tagged , , , , , | 2 Comments