Prettify script for PC^2

Sat 17 November 2012 by Peter Ward

When I was doing programming competitions at uni, I wrote this script, which takes the default HTML output from PC^2 and add some colour to it to indicate passed / failed problems. Since it was written / enhanced on the day of the competition, there’s definitely some hacky code in there, but I’m publishing it so future generations can steal it for their own nefarious purposes.

This code is released into the public domain.


import re
import string
import sys

from lxml import html, etree

doc = etree.parse(open('prettify.xsl', 'rU'))
xslt = etree.XSLT(doc)

doc = html.parse(sys.stdin)

passed = re.compile('^[0-9]*/[1-9][0-9]*$')
failed = re.compile('^.*[1-9]/[-0]*$')

for node in doc.xpath('//td'):
    text = node.text or ''
    if passed.match(text):
        node.attrib['class'] = 'passed'
    elif failed.match(text):
        node.attrib['class'] = 'failed'

problems = dict(zip(string.uppercase, [
    'An Industrial Spy',
    'Simple Polygon',
    'High Score',
    'Rewards for Math!',
    'Divisible Subsequences',

for node in doc.xpath('//th/strong/u'):
    node.text = problems.get(node.text, node.text)

doc = xslt(doc)

#body = doc.xpath('//html/body')
#d = etree.Element('div')
#d.attrib['class'] = 'timer'
#import sys
#from datetime import datetime
#n =
#t = datetime(2011, 9, 3, 17, 0, 0, 0)
#print>>sys.stderr, n - t

print html.tostring(doc)
<!-- prettify.xsl -->

<xsl:stylesheet version="1.0"

    <xsl:variable name="stage" select="0" />

    <xsl:output method="xml" indent="yes"
        doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" />

    <!-- Document structure -->
    <xsl:template match="/">
            <xsl:apply-templates select="/html/head" />
            <xsl:apply-templates select="/html/body" />

    <!-- Head for styling, etc. -->
    <xsl:template match="/html/head">
            <xsl:copy-of select="/html/head/node()" />
            <script type="text/javascript" src=""></script>
            <!--<meta http-equiv="refresh" content="5" />-->
            <link href=""
                rel="stylesheet" type="text/css" />
            <style type="text/css">
                html, body { margin: 0; padding: 0; }
                a { color: #729fcf; }
                body {
                    font-family: 'Questrial', sans-serif;
                    color: #eeeeec;
                    background: #2e3436;
                table { font-size: 20pt; }
                .passed, .failed { font-weight: bold; }
                .passed {
                    background: #8ae234;
                    color: black;
                .failed {
                    background: #ef2929;
                    color: white;

                h1 { text-align: center; margin: 0; }

                thead th { font-size: 12pt; }
                    font-weight: normal;
                    text-align: left;

                th:nth-child(2) { width: 50px; }
                td:nth-child(4) { width: 3.5em; }
                td:nth-child(12) { width: 3.5em; }

    <!-- Body -->
    <xsl:template match="/html/body/table[1]">
        <table id="scoreboard">
                <xsl:for-each select="tr[1]/th">
                    <th scope="col"><xsl:value-of select="strong/u" /></th>
                <xsl:for-each select="tr[position() > 2]">
                        <!-- Rank -->
                        <td class="rank"><xsl:value-of select="td[1]" /></td>
                        <!-- Name -->
                        <th class="team-name" scope="row"><xsl:value-of select="td[2]" /></th>
                        <xsl:copy-of select="td[position() > 2]" />

    <xsl:template match="/html/body">
        <xsl:if test="$stage >= 1">
            <h1>Competition is over! Congratulations to all!!!</h1>
        <xsl:apply-templates select="table[1]" />
        <p>Prettify script by Peter Ward</p>
        <xsl:if test="$stage >= 2">
        <script type="text/javascript">
            var count = 0;
            var delay = 10000;
            function magical() {
                if (count > 60) {
                    var child = null;
                    var nodes = document.body.children;
                    for (var i = 0; i < nodes.length; i++) {
                        if (nodes[i].tagName == "DIV") {
                            child = nodes[i];
                window.setTimeout(magical, delay * (Math.random() / 2.0 + 0.75));
                if (delay > 10)
                    delay *= 0.9;
            window.onload = magical;

End of Honours

Thu 15 November 2012 by Peter Ward

Well, I’ve handed in my thesis (Providing Useful Feedback to Beginner Programmers), and done a presentation for it (twice, for logistical reasons), so I’ve now finished everything I need to do for uni! I’m very happy about this, and I’ve been enjoying the little bubble of …

read more

Semester 1, 2011

Mon 11 July 2011 by Peter Ward

Another year, another semester, another set of results. This time, a little worse than usual, for reasons I’ll explain shortly. However, let me first give you an update of what I’ve been up to since I last posted on my blog (more than six months ago :O).

First …

read more

Semester 2 Results

Sat 04 December 2010 by Peter Ward

An update to my previous post - I did reasonably well this semester, with 2 HDs in COMP3109 (compilers) and INFO2912, a D in COMP2907 (algorithms), and a C in MATH2988 (number theory & crypto). I would have preferred a HD in algorithms, but I guess the exam brought it down. Also …

read more

Life update

Tue 02 November 2010 by Peter Ward

Hurrah, I’ve reached the end of semester! Unfortunately, this does not mean that I can stop working… sigh. Exams are coming up, speaking of which, grumble at the person who organised my exam timetable. :(

Here’s my predictions for marks: high distinction in comp3109 (a great course, btw), a …

read more

Semester 1 marks

Sun 11 July 2010 by Peter Ward

Another year, another set of marks — I’m quite happy with them, especially maths. I wasn’t sure about doing advanced level and didn’t think I did particularly well in the exam, so getting a Credit was especially fortunate.

So, here they are:

COMP2129 — Operating Systems and Machine Principles …
read more

Semester 2 marks

Sun 11 July 2010 by Peter Ward

Avast! Here be (dungeons and?) dragons! Actually, it's just my marks for Semester 2 (which I've been rather slow in actually posting).

ELEC1601 - Foundations of Computer Systems
90 (High Distinction)
INFO1905 - Data Structures (Advanced)
86 (High Distinction)
MATH1003 - Integral Calculus and Modelling
71 (Credit)
MATH1004 - Discrete Maths
80 (Distinction)
PHIL1012 …
read more


Thu 10 December 2009 by Peter Ward

Any resemblance to reality is purely coincidental.

because you can never have enough Comic Sans read more

Update time

Tue 22 September 2009 by Peter Ward

Things I've done recently:

  • Participated in the ACM South-Pacific regional with Carlo & Ronny - we were the top 1st year team!
  • Wrote Huffman compression utility for INFO1905 assignment - Carlo & I worked out a really tiny way of storing the header. Now, it's just back to writing unit tests and documenting... (incidentally …
read more

Busy, busy, busy.

Tue 01 September 2009 by Peter Ward

Uni assignments, NCSS Challenge, math quizzes (urgh!), Presenter, and also ACM training. Wow there's heaps to do. I'm trying to uses Getting Things GNOME! to organise myself, and it works, but only when I use it. :( Clearly every organisation system should work even when I don't use it. ;)

In other …

read more