This isn’t my only goal for 2012, but it’s the only goal from my only set of goals for 2012 which contains only one goal.

My goal is to, each night before I go to bed, prepare for the next morning. This means having a default choice of what to wear, knowing what I need to pack and where I’m first going to go, and a draft of a schedule and to-do list for the day.

My inspiration for this comes from a few different sources:

This matters most to me because I feel that my best self can figure out all of the other stuff, but if I don’t start my mornings off right, I’m unlikely to be my best self.

I found that new terminal sessions were taking a while to load, so I started commenting things out in my bash profile (How to be a Programmer: A Short, Comprehensive, and Personal Summary calls it a Binary Search). I found that it was snappy when I commented out my calls to virtualenvwrapper and rbenv.

Of course, with these calls I lost the ability to use them, and I lost the defaults. To fix this I chose a faster way to load the defaults and made functions for loading the full functionality of these. Here is the relevant part of ~/.bash_profile.

# Python
export VIRTUAL_ENV_DISABLE_PROMPT=1
# my virtualenv is called "batv", replace this with what you passed to mkvirtualenv
source $HOME/.virtualenvs/batv/bin/activate
loadvirtualenv() {
  # the next two lines might not be necessary for you; I only have them on OS X and not Linux
  export PYTHONPATH=/Library/Python/2.7/site-packages/virtualenv-1.6.4-py2.7.egg
  export PYTHONPATH=/Library/Python/2.7/site-packages/virtualenvwrapper-2.10.1-py2.7.egg:$PYTHONPATH
  source /usr/local/bin/virtualenvwrapper.sh
  workon batv
}

# Ruby
export PATH="$HOME/.rbenv/shims/:$HOME/.rbenv/bin:$PATH"
loadrbenv() {
  eval "$(rbenv init -)"
}

To use my default virtualenv or to use rbenv without the rbenv shell command, I don’t have to run either of these functions. If I want to do advanced stuff with virtualenvwrapper, I type loadvirtualenv and hit enter, and then I can use all of virualenvwrapper in that terminal session. If I want to set a rbenv environment for my current shell, I type loadrbenv.

Before I made these changes, the contents each of these functions were run each time I created a terminal. Now they’re run only on demand and opening a new terminal tab is much snappier!

I’ve been reading quite a bit about parsing and templating in ruby as I attempt to port a templating engine from JavaScript to Ruby. Here are some scattered links:

Jison

Jison is a parser generator for JavaScript that has separate lex and bnf definitions. It’s used by Handlebars.js.

Repositoryjison
Ownerzaach

Treetop

Treetop is a parser generator for Ruby. It’s installed with Ruby On Rails, through the mail gem which is installed by ActionMailer.

Repositorytreetop

Citrus

Citrus is another promising parsing gem for Ruby. It seems to be very easy to get started with, and I like many of the design decisions.

Repositorycitrus

Temple

Temple is a templating-specific library that helps with a lot of the AST transformation. It doesn’t seem to have a CFG syntax so it seems that using treetop or citrus would make sense for complex grammars. Otherwise, strscan could be used.

Repositorytemple
Ownerjudofyr

temple-mustache

This is an implementation of a mustache renderer in . It uses strscan to generate the initial parse tree, and Temple to generate the ruby code. It supports mustache sections.

Repositorytemple-mustache
Ownerminad

Slim

Slim is a Haml-like templating library for Ruby that’s used in production by many. It uses Temple, with a line-based parser, which works well because it uses significant indentation for nesting.

Repositoryslim
Ownerstonean

For the November meeting of Front Range Pythoneers we did a bowling code kata. We worked as a group on the projector, but I also worked on my own version on my laptop. Here’s my code, which was fun to write. It’s a single file which contains its test cases and can be run on the command line or imported:

import unittest

class Frame(object):
    def __init__(self, tenth=False):
        self.rolls = []
        self.tenth = tenth

    def full(self):
        if len(self.rolls) >= self.max_rolls():
            return True
        if self.tenth:
            has_special = all([roll in ('X', '/') for roll in self.rolls])
            return len(self.rolls) == 2 and not has_special
        else:
            return self.strike()

    def roll(self, score):
        if self.full():
            raise RuntimeError('attempted to record a roll on a full frame')
        self.rolls.append(score)

    def pins(self):
        if len(self.rolls) == 0:
            return 0
        if self.strike() or self.spare():
            return 10
        else:
            return sum([int(roll) for roll in self.rolls])

    def first_roll_pins(self):
        if len(self.rolls) == 0:
            return 0
        elif self.rolls[0] == 'X':
            return 10
        else:
            return int(self.rolls[0])

    def score(self, subsequent_frames):
        if self.tenth:
            return self.tenth_frame_score()

        score = self.pins()
        if self.strike():
            score += sum([frame.pins() for frame in subsequent_frames])
        elif self.spare():
            if len(subsequent_frames) > 0:
                score += subsequent_frames[0].first_roll_pins()
        return score

    def tenth_frame_score(self):
        return min(Game(''.join(self.rolls)).score(), 40)

    def strike(self):
        return len(self.rolls) > 0 and self.rolls[0] == 'X'

    def spare(self):
        return len(self.rolls) > 0 and self.rolls[-1] == '/'

    def max_rolls(self):
        return 3 if self.tenth else 2

class Game(object):
    def __init__(self, roll_scores=''):
        self.frames = []
        for score in roll_scores:
            self.roll(score)

    def roll(self, score):
        if len(self.frames) == 0 or self.frames[-1].full():
            tenth = len(self.frames) == 9
            self.frames.append(Frame(tenth))
        self.frames[-1].roll(score)

    def score(self):
        return sum(self.frame_scores())

    def frame_scores(self):
        frame_scores = []
        for frame_index in xrange(len(self.frames)):
            frame = self.frames[frame_index]
            subsequent_frames = []
            if frame.strike() or frame.spare():
                subsequent_frames = self.frames[frame_index+1:]
                added_frames = 1
                if frame.strike() and len(subsequent_frames) > 0:
                    added_frames = 2 if subsequent_frames[0].strike() else 1
                subsequent_frames = subsequent_frames[:added_frames]
            frame_scores.append(frame.score(subsequent_frames))
        return frame_scores

class GameTest(unittest.TestCase):
    def test_initial_strike(self):
        self.assertEqual(Game('X').score(), 10)

    def test_two_strikes(self):
        self.assertEqual(Game('XX').score(), 20+10)

    def test_three_strikes(self):
        self.assertEqual(Game('XXX').score(), 30+20+10)

    def test_strike_spare_strike(self):
        self.assertEqual(Game('X9/X').score(), 20+20+10)

    def test_strike_strike_spare(self):
        self.assertEqual(Game('XX9/').score(), 30+20+10)
        self.assertEqual(Game('XX9/71').score(), 30+20+17+8)

    def test_perfect_game(self):
        game = Game('X'*12)
        self.assertEqual(len(game.frames), 10)
        self.assertEqual(game.score(), 300)

    def test_made_up_game(self):
        game = Game('X907/818/X70070/72')
        self.assertEqual(len(game.frames), 10)
        self.assertEqual(game.score(), 132)

if __name__ == '__main__':
    unittest.main()

I think that the tenth frame calculation is incorrect. My limited understanding of bowling slowed me down a fair bit. I got an object system that I’m fairly happy with, though!