Tag Archives: Python

Using the State Machine Compiler with Python

Today I learned about a state machine compiler and code generator. It provides a small DSL that you can use to describe a state machine and the transitions between the states, which will be compiled to create a number of classes, and then all you have to do is provide the code for the actions. Here, actions, states, and transitions are defined terms that are described in the documentation for the smc tool.

All you need to do is download the source code from SourceForge here. The jar file you’re looking for is located in smc/bin/Smc.jar. I’ll walk through the example in the SMC documentation. Copy the following snippet and save it as Turnstile.sm

%class Turnstile
%package turnstile
%start MainMap::Locked
%map MainMap
%%
Locked
{
 coin Unlocked { unlock(); }
 passs nil { alarm(); }
}
Unlocked
{
 passs Locked { lock(); }
 coin nil { thankyou(); }
}
%%

Great. Now compile that state machine script as:

java -jar Smc.jar -python Turnstile.sm

This should produce a Turnstile_sm.py in your working directory.

VERY IMPORTANT: Put smc/lib/Python/statemap.py in your PYTHONPATH or your working directory, you’ll need to import it in the next snippet.

import Turnstile_sm

class Turnstile:
    def __init__(self):
        self._fsm = Turnstile_sm.Turnstile_sm(self)
    def alarm(self):
        print("Alarming!")
    def thankyou(self):
        print("Thanks!")
    def lock(self):
        print("Locked!")
    def unlock(self):
        print("Unlocked!")

if __name__ == '__main__':
    ts = Turnstile()
    ts._fsm.coin()
    ts._fsm.passs()

Why does “pass” have an extra “s”? Because pass is reserved in Python, and I couldn’t think of a better variable name. So this doesn’t do much besides print stuff out when different actions are triggered by changes in state, but it’s still pretty cool. For more motivation for state machines, read this Robert Martin article.

The Recursive Maze Problem, Part I

Earlier this year, when I was looking for work, I got the same recursive maze problem three interviews in a row. Recursion is cute and clever, but you generally want to use iterative solutions in production.

Usually, you get a string representation of the maze, something like:

ms = '''
S####
....#
#.###
....G
##..#
...##
#..##
'''

So then you need to parse that into a list of lists, which isn’t difficult:

def maze_string_to_list_of_lists(maze: str) -> []:
    rows = maze.split()
    new_maze = []
    for row in rows:
        new_row = [i for i in row]
        new_maze.append(new_row)
    return new_maze

Next, I like to write a function to return cells orthogonal to some cell location. This originally considered cells north, south, east, and west of a location, but then I limited it to just south and east, because this is recursive and we have to worry about the stack size in Python. (Because recursion is as stupid as it is clever.)

def orthogonals(row: int, col: int, row_limit: int, col_limit: int) -> []:
    result = []
    # check input
    if row < 0 or row >= row_limit:
        return result
    if col < 0 or col >= col_limit:
        return result
    # compute output
    s = [row+1, col]
    e = [row, col+1]
    # check computed output
    if s[0] < row_limit:
        result.append(s)
    if e[1] < col_limit:
        result.append(e)
    return result

Finally, the meat and potatoes. Yeah, so SOLN is a global variable that’s laying around, which is bad. You know what else is bad? Recursive maze solvers.

SOLN = []

def find_path(row: int, col: int, maze: list) -> bool:
    if maze[row][col] == 'G':
        SOLN.append([row, col])
        return True
    if maze[row][col] == '#':
        return False
    SOLN.append([row, col])
    orthos = orthogonals(row, col, len(maze), len(maze[0]))
    for ortho in orthos:
        if ortho in SOLN:
            pass
        if find_path(ortho[0], ortho[1], maze):
            return True
    SOLN.pop()
    return False

References:

  • (Recursion: Solving a Maze)[https://www.cs.bu.edu/teaching/alg/maze/]
  • (Backtracking: Rat in a Maze)[http://www.geeksforgeeks.org/backttracking-set-2-rat-in-a-maze/]

Very Very Verbose Cosine Similarity

This material was a teaching aid for a crash course I gave at work about cosine similarity. Cosine similarity is a blunt instrument used to compare two sets of text. If two the two texts have high numbers of common words, then the texts are assumed to be similar. The ultimate goal is to plug two texts into a function and get an easy to understand number out that describes how similar the texts are, and cosine similarity is one way to skin that cat.

Please note, there are plenty of other very fast implementations for cosine similarity, but this one was written for educational purposes.

Continue reading

How Many Trials Before the Nth Success

TLDR: the negative binomial counts the number of trials needed before the Nth success.

I had this problem where we were considering running some very expensive tests that had a known success rate, and we wanted to know, given the success rate and the cost, whether we should run them at all. To make things more interesting, we were only interested in a set number n of successes, and we could stop all testing after the first n successes. My initial thought was to use the binomial distribution, but the binomial doesn’t “cut off” after a set number of successes. It turns out that we needed to use a version of the negative binomial distribution.

Continue reading

Setting Up Sphinx Documentation

It took me a while to get Sphinx documentation set up correctly. Since it is highly configurable, it is highly easy to not configure correctly. In this guide I’ll assume that you’re using a Python virtual environment, and that you’ve placed the source code that you want to document in a directory called src/. I’ll walk through installing and configuring what you need to create documentation from inline comments using the Google or NumPy style, and create API documentation for a Flask server. I’ll be extra-explicit about what directory I’m in when I make calls that make assumptions about the working directory.

Continue reading

Reinforcement Learning with Monte Carlo and Tabulation Methods

I was reading another blog post about reinforcement learning using Monte Carlo and tabulation methods that provided an example of the technique using Blackjack. I decided to implement my own method using Tic-Tac-Toe as an example. The basic idea is that you generate a random state of a game, and you generate a random action based on that state. Then you play the rest of the game through until the end and record the outcome. Then you should be able to store the state, action, and outcome as a key in a dictionary that refers to a count. Each time that state-action-outcome occurs again, you update the count by one. Over time, your dictionary will encode information about the relative strengths of different actions for a given state.

Continue reading

Simple Directed Graph in Python

This is a work in progress, there’s a lot of complex questions you can ask about graphs, but I though it was neat that you could produce an actual graphy looking thing in so few lines of code. This is a directed graph, and you use the graph object to first create nodes, and then define (unweighted) edges between them or to themselves. The __repr__() method just lists the node data, whatever that is, with an ASCII arrow pointing to another node’s data.

Continue reading