<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Ben Wendt's blog</title>
    <atom:link href="http://localhost:8080/feed.xml" rel="self" type="application/rss+xml"></atom:link>
    <link>http://localhost:8080</link>
    <description>Ocassional Notes</description>
    <pubDate>Mon, 08 Sep 2025 20:00:00 -0400</pubDate>
    <generator>Wintersmith - https://github.com/jnordberg/wintersmith</generator>
    <language>en</language>
    <item>
      <title>File Integrity Monitoring in Python</title>
      <link>http://localhost:8080/articles/file-integrity-monitoring/</link>
      <pubDate>Mon, 08 Sep 2025 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/file-integrity-monitoring/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Some Anti-virus software will monitor that certain
key files, for example important binaries or the
kernel, have not been modified. The way to do this is with
&lt;a href=&quot;https://en.wikipedia.org/wiki/File_integrity_monitoring&quot;&gt;file integrity monitoring&lt;/a&gt;. The general idea is to store
hashes of files, and continually re-hash the files to
make sure nothing has changed.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Let’s look at how this might look in python.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;monitor_files&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(path, monitor_log_file=&lt;span class=&quot;string&quot;&gt;&quot;log.pickle&quot;&lt;/span&gt;, hashes=&lt;span class=&quot;params&quot;&gt;(hashlib.sha256, hashlib.blake2b, hashlib.md5, hashlib.sha3_512)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; os.path.exists(monitor_log_file):
        &lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; open(monitor_log_file, &lt;span class=&quot;string&quot;&gt;'rb'&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; handle:
            monitor_log = pickle.load(handle)
    &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;:
        monitor_log = {}

    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; os.path.exists(path):
        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; Exception(&lt;span class=&quot;string&quot;&gt;f&quot;Path does not exist &lt;span class=&quot;subst&quot;&gt;{path}&lt;/span&gt;&quot;&lt;/span&gt;)

    new_log = {}


    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; root, dirs, files &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; os.walk(path):

        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; file &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; files:
            print(root, dirs, file)
            file_hashes = []
            &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; hash_ &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; hashes:
                m = hash_()
                &lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; open(&lt;span class=&quot;string&quot;&gt;f&quot;&lt;span class=&quot;subst&quot;&gt;{root}&lt;/span&gt;/&lt;span class=&quot;subst&quot;&gt;{file}&lt;/span&gt;&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;rb&quot;&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; f:
                    m.update(f.read())
                file_hashes.append(m.digest()) 
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; file &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; monitor_log:
                &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; file_hashes != monitor_log[file]:
                    print(&lt;span class=&quot;string&quot;&gt;f&quot;hash mismatch for file &lt;span class=&quot;subst&quot;&gt;{file}&lt;/span&gt;&quot;&lt;/span&gt;)
            &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;:
                print(&lt;span class=&quot;string&quot;&gt;f&quot;new file &lt;span class=&quot;subst&quot;&gt;{file}&lt;/span&gt;&quot;&lt;/span&gt;)
            new_log[file] = file_hashes
    &lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; open(monitor_log_file, &lt;span class=&quot;string&quot;&gt;'wb'&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; handle:
        pickle.dump(new_log, handle)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notes about this code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There should be a size check. The file system can quickly give
  the file size and if there’s a mismatch between expected and
  actual, it’s clear that the file has been modified.&lt;/li&gt;
&lt;li&gt;Whole files are being hashed. This is fine for small files, but
  for big files, it’s better to store a bunch of small hashes and short-circuit the execution if a mismatch is found. For example,
  there’s no need to hash through a 100GB file if the first byte is wrong.&lt;/li&gt;
&lt;li&gt;Multiple hashes are being computed. This makes it very difficult
  to perform a hash collision attack, as the probability of
  finding an attack that can satisfy multiple hashes simultaneously
  is very low.&lt;/li&gt;
&lt;li&gt;Using pickle is a bad idea. Firstly, pickle is susceptible to 
  arbitrary code execution, so if this code is running in an
  untrusted environment, the serde is an attack vector (however
  minor). It’s better to use a WORM storage medium or ship valid hashes to a trusted remote machine. Ideally the trusted hash is
  generated on a trusted machine to begin with.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here’s a version that does the incremental hashing:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;meta&quot;&gt;@dataclass&lt;/span&gt;
&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;FileHashes&lt;/span&gt;:&lt;/span&gt;
    whole_file: bytes
    chunks: list[bytes]
    window_size: int
    file_size: int

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;rolling_fim&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(file_path: str, window_size:int = &lt;span class=&quot;number&quot;&gt;256&lt;/span&gt;, monitor_log_file=&lt;span class=&quot;string&quot;&gt;&quot;rolling_log.pickle&quot;&lt;/span&gt;, hash_ = hashlib.blake2b)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; os.path.exists(monitor_log_file):
        &lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; open(monitor_log_file, &lt;span class=&quot;string&quot;&gt;'rb'&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; handle:
            monitor_log = pickle.load(handle)
    &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;:
        print(&lt;span class=&quot;string&quot;&gt;&quot;warning, no old file integrity log exists.&quot;&lt;/span&gt;)
        monitor_log = FileHashes(&lt;span class=&quot;string&quot;&gt;b&quot;&quot;&lt;/span&gt;, [], window_size, os.path.getsize(file_path))

    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; os.path.exists(file_path):
        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; Exception(&lt;span class=&quot;string&quot;&gt;f&quot;Path does not exist &lt;span class=&quot;subst&quot;&gt;{file_path}&lt;/span&gt;&quot;&lt;/span&gt;)

    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; monitor_log.window_size != window_size:
        print(&lt;span class=&quot;string&quot;&gt;&quot;warning window size changed, expect all comparisons to fail.&quot;&lt;/span&gt;)

    new_log = FileHashes(&lt;span class=&quot;string&quot;&gt;b&quot;&quot;&lt;/span&gt;, [], window_size, os.path.getsize(file_path))

    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; new_log.file_size != monitor_log.file_size:
        print(&lt;span class=&quot;string&quot;&gt;&quot;file size changed. Files do not match.&quot;&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;

    m = hash_()

    chunk_num = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; open(file_path, &lt;span class=&quot;string&quot;&gt;&quot;rb&quot;&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; f:
        &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;True&lt;/span&gt;:
            n = hash_()
            chunk = f.read(window_size)
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; chunk:
                &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;
            m.update(chunk)
            n.update(chunk)
            new_log.chunks.append(n.digest())
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; len(monitor_log.chunks) &amp;gt; chunk_num &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; monitor_log.chunks[chunk_num] != new_log.chunks[chunk_num]:
                print(&lt;span class=&quot;string&quot;&gt;f&quot;mismatch found in chunk &lt;span class=&quot;subst&quot;&gt;{chunk_num}&lt;/span&gt;&quot;&lt;/span&gt;)
                &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;
            chunk_num += &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
    new_log.whole_file = m.digest()
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; monitor_log.whole_file != new_log.whole_file:
        print(&lt;span class=&quot;string&quot;&gt;&quot;mismatch in whole file hash&quot;&lt;/span&gt;)

    &lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; open(monitor_log_file, &lt;span class=&quot;string&quot;&gt;'wb'&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; handle:
        pickle.dump(new_log, handle)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notes on this code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Switched to use one hash, blake2b. Blake2b is generally preferred
  for hashing large files due to its speed. We could implement a 
  similar logic for computing multiple hashes of each chunk of the
  file to make collision attacks more difficult.&lt;/li&gt;
&lt;li&gt;Added the file size check here, because why not.&lt;/li&gt;
&lt;li&gt;The code computes a series of hashes of given window sizes of the
  source file. If one fails, short circuit execution.&lt;/li&gt;
&lt;li&gt;Also compute a whole file hash, this is also to make collision&lt;br&gt;  attacks more difficult.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This code is for illustration purposes only, but several improvements
have been identified that, if implemented, could make this system
more production ready. Further improvements would be needed to 
prevent a compromised machine from always returning known good 
hashes, such as remote verification.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Tell A Story To Write Better Code</title>
      <link>http://localhost:8080/articles/tell-story/</link>
      <pubDate>Fri, 29  Aug 2025 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/tell-story/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Programming could be described as the process of giving
a computer instructions. There are many ways to write
programs that have within some tolerance the same
function. Because of this arguments and philosophies arise
as to what way code should be written. When starting out
a lot of folks tend try to “golf” their code, make it as
short as possible, while others may aim for best performance.
I’m of the opinion that code should be
written (given a certain functionality) as a document that
communicates both the intent of the author and the
functionality of the program.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;My favorite technique for this is to have your code tell
a story. My old boss &lt;a href=&quot;https://www.linkedin.com/in/jack-neto/?originalSubdomain=ca&quot;&gt;Jack Neto&lt;/a&gt;
advocated for this at an old job at a company that no longer
exists, but I’m quite sure I had heard about it before then.&lt;/p&gt;
&lt;p&gt;The idea is start with a function body that is essentially
a script of your procedure. Fill it with nothing but function 
signatures of steps that will happen in that procedure. By reading 
this function, you’ll see exactly what the program does. You can 
iterate this so that the called functions are also little “scripts” 
of steps given by function calls, but eventually you get down to the 
level of granularity 
where the function bodies are short definitions of functionality.&lt;/p&gt;
&lt;p&gt;The technique ends with a very readable and maintainable product,
with the added bonus of making the writing process easier, testing
easier, and it’s more fun. My favorite part about this technique 
is that you can spend a long time writing code, then go click run
and generally just have a few minor things to fix up and it works.&lt;/p&gt;
&lt;p&gt;Let’s look at some examples.&lt;/p&gt;
&lt;p&gt;First I will preface with some versions of bad code to illustrate
why this is a useful technique.&lt;/p&gt;
&lt;p&gt;Imagine you asked a GPT to write a program to have your robot
take your dog for a walk. It might write something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;take_dog_for_walk&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(path, robot, dog)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;string&quot;&gt;&quot;&quot;&quot;Walk a dog and pick up poop.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;# Traverse the path&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; waypoint &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; path:

        &lt;span class=&quot;comment&quot;&gt;# go to the next waypoint&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; robot.at_location(waypoint):

            &lt;span class=&quot;comment&quot;&gt;# move along vector&lt;/span&gt;
            robot.step_in_direction((waypoint.x - position.x, waypoint.y - position.y))

            &lt;span class=&quot;comment&quot;&gt;# use vision to detect poop&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; dog.pooping:
                &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; dog.pooping:
                    &lt;span class=&quot;comment&quot;&gt;# a short delay&lt;/span&gt;
                    sleep &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;

                &lt;span class=&quot;comment&quot;&gt;# look at the poop and pick it up&lt;/span&gt;
                target = robot.locate_object(POOP, dog.position)
                robot.pick_up_object(target)

                &lt;span class=&quot;comment&quot;&gt;# set boolean to true.&lt;/span&gt;
                robot.holding_poop = &lt;span class=&quot;literal&quot;&gt;True&lt;/span&gt;

    &lt;span class=&quot;comment&quot;&gt;# dispose of poop if necessary.&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; robot.holding_poop:
        robot.dispose_waste()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…Or something like that. It tends to write things very procedurally
in one big function with lots of comments. Basically it’s the
coding style that books have been written warning against, and 
many developers have always spent their careers
fighting against.&lt;/p&gt;
&lt;p&gt;Now lets rewrite it as a story.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;walk_dog&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(robot, dog, path)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; waypoint &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; path:
        walk_dog_to_point(robot, dog, waypoint)
    dispose_poop(robot)

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;walk_dog_to_point&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(robot, dog, waypoint)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; robot.at_location(waypoint):
        move_toward(robot, waypoint)
        wait_for_dog_if_needed(robot, dog)
        pickup_poop_if_needed(robot, dog)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This part of the code is super readable. All it does is tell the
story of the walk. You barely have to understand python to
understand this. This code is naturally decomposed, and has
single responsibility.&lt;/p&gt;
&lt;p&gt;Another great thing is if you want to
use an LLM, you’ll now have a better outcome because something
like co-pilot can often take the function signature and guess
at the body of the function. You’ll of course have to verify that
it’s right, but it’s a smaller piece and more logically 
coherent so that should be easier.&lt;/p&gt;
&lt;p&gt;Let’s fill in the mock implementations
of these functions based on the earlier silly code to fill in the
details.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def move_toward(robot, waypoint):
    robot.step_in_direction((waypoint.x - position.x, waypoint.y - position.y))

def wait_for_dog_if_needed(robot, dog):
    if dog.pooping:
        while dog.pooping:
            sleep 1

def pickup_poop_if_needed(robot, dog):
    target = robot.locate_object(POOP, dog.position)
    if target:
        robot.pick_up_object(target)
        robot.holding_poop = True

def dispose_poop(robot)
    if robot.holding_poop():
        robot.dispose_waste()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another added bonus is these
smaller functions are naturally easier to unit test.&lt;/p&gt;
&lt;p&gt;There’s a maxim in computer science “code is read more than it’s
written”. One of my professors in university said to comment your
code because often it will be you who doesn’t remember how it works.&lt;/p&gt;
&lt;p&gt;In my experience if you write code as a document for reading as
much as a list of instructions (or whatever) for the computer, it
will be far more readable still. Formatting code as a story is the
best way to communicate your intent with future readers. And who 
knows, maybe it will be you.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Generating fractals from Dask Distributed</title>
      <link>http://localhost:8080/articles/dask-distributed-fractal/</link>
      <pubDate>Tue, 08 Jul 2025 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/dask-distributed-fractal/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;https://docs.dask.org/en/stable/index.html&quot;&gt;Dask&lt;/a&gt; distributed
is a python package / distributed processing framework that gives
the ability to parallelize code execution across a cluster.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For a simple example, observe:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(x)&lt;/span&gt;:&lt;/span&gt;
    x * &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;

scheduler_host = &lt;span class=&quot;string&quot;&gt;&quot;whatever&quot;&lt;/span&gt;
client = Client(&lt;span class=&quot;string&quot;&gt;&quot;tcp://{scheduler_host}:8786&quot;&lt;/span&gt;)
scattered_inputs = client.scatter(list(range(&lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;)))
futures = client.map(double, scattered_inputs)

results = client.gather(futures)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course I had to do a mandelbrot viewer. A mandelbrot fractal
is great for parallelization because each pixel it computed 
independently of all others. The “heat map” generated by the
mandelbrot fractal algorithm is basically the same as how long it took to compute each point!&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; dask.distributed &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; Client
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; dask
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; numpy &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; np
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; matplotlib.pyplot &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; plt


max_iter = &lt;span class=&quot;number&quot;&gt;180&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;# reference implementation...&lt;/span&gt;
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_mandelbrot_pts&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(x_y)&lt;/span&gt;:&lt;/span&gt;
    iterations = &lt;span class=&quot;number&quot;&gt;180&lt;/span&gt;
    x0, y0 = x_y
    x = float(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;)
    xtemp = float(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;)
    y = float(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;)
    iteration = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; ((x*x)+(y*y) &amp;lt; &lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; iteration &amp;lt; iterations:
        xtemp = x * x - y * y + x0
        y = &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt; * x * y + y0
        x = xtemp
        iteration += &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; iteration

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(w, h)&lt;/span&gt;:&lt;/span&gt;  
    minx, maxx, miny, maxy = (&lt;span class=&quot;number&quot;&gt;-0.8&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;-0.7&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;-0.2&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;-0.05&lt;/span&gt;)

    inputs = []
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; x &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(w):
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; y &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(h):
            x0 = (maxx-minx)*float(x)/float(w) + minx
            y0 = (maxy-miny)*float(y)/float(h) + miny
            inputs.append((x0, y0))
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; inputs

w = &lt;span class=&quot;number&quot;&gt;800&lt;/span&gt;
h = &lt;span class=&quot;number&quot;&gt;600&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;# Dear reader, please don't hack me now that you have my internal IP&lt;/span&gt;
client = Client(&lt;span class=&quot;string&quot;&gt;&quot;tcp://192.168.1.163:8786&quot;&lt;/span&gt;)
scattered_inputs = client.scatter(list(inputs(w, h)))
futures = client.map(get_mandelbrot_pts, scattered_inputs)

results = client.gather(futures)

array_2d = np.array(results).reshape((w, h))

plt.axis(&lt;span class=&quot;string&quot;&gt;'off'&lt;/span&gt;)
plt.figure(figsize=(&lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;))
plt.matshow(array_2d, fignum=&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, aspect=&lt;span class=&quot;string&quot;&gt;'auto'&lt;/span&gt;)
plt.savefig(&lt;span class=&quot;string&quot;&gt;'heatmap.png'&lt;/span&gt;, bbox_inches=&lt;span class=&quot;string&quot;&gt;'tight'&lt;/span&gt;, pad_inches=&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;)
plt.close()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will give you the standard fun image:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/dask-distributed-fractal/heatmap.png&quot; alt=&quot;mandelbrot from dask distributed&quot;&gt;&lt;/p&gt;
&lt;p&gt;This only tells half the story though. We haven’t talked about
running the scheduler and compute nodes!&lt;/p&gt;
&lt;p&gt;On my local network I have many computers. Just for fun,
definitely not performance (this particular problem runs
better on one machine), I hooked up the following computers
as dask compute nodes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My 2019 MBP i7&lt;/li&gt;
&lt;li&gt;My Steam Deck&lt;/li&gt;
&lt;li&gt;A 2012 i7 Mac Mini&lt;/li&gt;
&lt;li&gt;Two raspberry pi 4s&lt;/li&gt;
&lt;li&gt;For fun, an Orange Pi Zero 2W&lt;/li&gt;
&lt;li&gt;My creaking old i5 PC&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(I don’t have a new-ish computer)&lt;/p&gt;
&lt;p&gt;Enter dependency hell. Dask works on a “pickle everything”
serde model, but pickle is notoriously picky about sending
data between versions. Dask is super cool, but if I could 
make one criticism its that you can’t inject your own serde
to use for IPC.&lt;/p&gt;
&lt;p&gt;To sidestep dependency hell (&lt;em&gt;not today, Dependency Datan,
Dependency Jesus, take the wheel&lt;/em&gt;) I decided to run
everything in docker. (Podman actually, but yes, docker is
Dependency Jesus) Since all my CPUs were basically idle
I think the overhead of running in docker is fine, especially
for a toy implementation. Here’s the docker commands:&lt;/p&gt;
&lt;p&gt;For the scheduler, only run once:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alias docker=podman
docker run --network=host ghcr.io/dask/dask dask-scheduler&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Get your scheduler’s IP of course, and then run this on any
node you want to be a compute node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alias docker=podman
docker run --network=host ghcr.io/dask/dask dask-worker $SCHEDULER_IP:8786&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All in all, it seems like a fun way to run code distributed. I
can see how certain problems that are very parallelizable
would be good to run this way, as compared to using something
like spark. You don’t really need to learn a different mental
model of distributed computing for this framework. But, having
said that, the number of problems where this would be a performant 
solution may be limited, especially with being limited to python.&lt;/p&gt;
&lt;p&gt;One drawback is that there doesn’t appear to be any managed service 
for dask in the big cloud providers, which means if you wanted to use
this in production, you’d need to manage your own k8s cluster, which
is another level of pain and complexity that people prefer to
side-step.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Branch Coverage, A Cautionary Tale</title>
      <link>http://localhost:8080/articles/branch-coverage/</link>
      <pubDate>Sun, 06 Jul 2025 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/branch-coverage/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Unit testing your code is the ultimate route to developer
sanity. A well written test suite is a patchwork proof of
the correctness of your system. The more complete your
patchwork, the more you can rest easy knowing your code
will do what you intend it to do.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The typical measure of the completeness of a test suite is
line coverage. A profiler running while the test suite is
run checks every line of code to see whether it has been run
or not. In theory, the closer you get to 100%, the better
tested your code base is, and the more easily you can sleep
at night.&lt;/p&gt;
&lt;p&gt;This of course isn’t always true. For example, consider the
following code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;contrived_example&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(data, a, b)&lt;/span&gt;:&lt;/span&gt;
    encoding = &lt;span class=&quot;string&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; a:
        encoding = &lt;span class=&quot;string&quot;&gt;&quot;not a real encoding&quot;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; b:
        encoding = &lt;span class=&quot;string&quot;&gt;&quot;iso-8859-1&quot;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; data.decode(encoding)

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;test_contrived_example&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;assert&lt;/span&gt; contrived_example(&lt;span class=&quot;string&quot;&gt;b&quot;test&quot;&lt;/span&gt;, &lt;span class=&quot;literal&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;literal&quot;&gt;True&lt;/span&gt;) == &lt;span class=&quot;string&quot;&gt;&quot;test&quot;&lt;/span&gt;


test_contrived_example()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Congratulations, you have 100% line coverage! But what happens when you do this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;test_contrived_example_2&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;assert&lt;/span&gt; contrived_example(&lt;span class=&quot;string&quot;&gt;b&quot;test&quot;&lt;/span&gt;, &lt;span class=&quot;literal&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;literal&quot;&gt;False&lt;/span&gt;) == &lt;span class=&quot;string&quot;&gt;&quot;test&quot;&lt;/span&gt;

test_contrived_example_2()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Oh no, an error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LookupError: unknown encoding: not a real encoding&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is because the all possible branches weren’t checked by
&lt;code&gt;test_contrived_example&lt;/code&gt;, as shown by &lt;code&gt;test_contrived_example_2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But sometimes branch coverage isn’t enough either.  Consider this example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;my_function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(a, b)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; a &amp;gt;= &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;:
        a -= &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; b &amp;gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;:
        b /= a
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; b

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;test_small_a&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;:&lt;/span&gt;
    a = &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
    b = &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;
    print(&lt;span class=&quot;string&quot;&gt;f&quot;&lt;span class=&quot;subst&quot;&gt;{a}&lt;/span&gt; &lt;span class=&quot;subst&quot;&gt;{b}&lt;/span&gt; =&amp;gt; &lt;span class=&quot;subst&quot;&gt;{my_function(a, b)}&lt;/span&gt;&quot;&lt;/span&gt;)
    &lt;span class=&quot;keyword&quot;&gt;assert&lt;/span&gt; my_function(a, b) == &lt;span class=&quot;number&quot;&gt;2.0&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;test_big_a&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;:&lt;/span&gt;
    a = &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
    b = &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;
    print(&lt;span class=&quot;string&quot;&gt;f&quot;&lt;span class=&quot;subst&quot;&gt;{a}&lt;/span&gt; &lt;span class=&quot;subst&quot;&gt;{b}&lt;/span&gt; =&amp;gt; &lt;span class=&quot;subst&quot;&gt;{my_function(a, b)}&lt;/span&gt;&quot;&lt;/span&gt;)
    &lt;span class=&quot;keyword&quot;&gt;assert&lt;/span&gt; my_function(a, b) == &lt;span class=&quot;number&quot;&gt;2.0&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;test_small_b&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;:&lt;/span&gt;
    a = &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
    b = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
    print(&lt;span class=&quot;string&quot;&gt;f&quot;&lt;span class=&quot;subst&quot;&gt;{a}&lt;/span&gt; &lt;span class=&quot;subst&quot;&gt;{b}&lt;/span&gt; =&amp;gt; &lt;span class=&quot;subst&quot;&gt;{my_function(a, b)}&lt;/span&gt;&quot;&lt;/span&gt;)
    &lt;span class=&quot;keyword&quot;&gt;assert&lt;/span&gt; my_function(a, b) == &lt;span class=&quot;number&quot;&gt;0.0&lt;/span&gt;


tests = [test_small_a, test_big_a, test_small_b]

&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; test &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; tests:
    test()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This “test suite” gives 100% branch coverage of our example
function, but there’s still special case handling that can
cause an exception:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;my_function(&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yields &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ZeroDivisionError: division by zero&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So even with 100% branch coverage we cannot be sure that our
code is clear of errors. This is where the peer review process
is important. More eyes on a code base will reveal these edge
case issues that aren’t caught by code coverage.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Rotary MIDI</title>
      <link>http://localhost:8080/articles/rotary-midi/</link>
      <pubDate>Fri, 27 Jun 2025 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/rotary-midi/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Using the &lt;code&gt;BLEMidi.h&lt;/code&gt; library, you can get your esp32, the goat
of dev boards, to be a midi server (instrument), or client (it’s
complicated).&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;It’s pretty easy to get your esp32 to play notes:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;BLEMidi.h&amp;gt;&lt;/span&gt;&lt;/span&gt;


&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
  &lt;span class=&quot;built_in&quot;&gt;Serial&lt;/span&gt;.&lt;span class=&quot;built_in&quot;&gt;begin&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;115200&lt;/span&gt;);
  BLEMidiServer.&lt;span class=&quot;built_in&quot;&gt;begin&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;Basic MIDI device&quot;&lt;/span&gt;);
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;(!BLEMidiServer.isConnected()) {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;
    } 
    BLEMidiServer.noteOn(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;80&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;127&lt;/span&gt;);
    &lt;span class=&quot;built_in&quot;&gt;delay&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;);
    BLEMidiServer.noteOff(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;80&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;127&lt;/span&gt;);

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But that’s not really an instrument. I am not a musician, but
I wanted something I could play. In walks my joystick unit I
used in my last post about making an automated mouse clicker.
Out walks this musical abomination:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/rotary-midi/midi.jpg&quot; alt=&quot;esp32 midi device&quot;&gt;&lt;/p&gt;
&lt;p&gt;If you connect the pin outs as directed, this code will turn your
joystick into an esp32 controlled octave pointer. Probably the worst
musical instrument ever. As I said, I’m no musician, but I tried to
record myself playing the easy intro part of ode to joy (E-E-F-G-G
etc.) on this and it was well beyond my ability.&lt;/p&gt;
&lt;p&gt;Regardless it was a fun little project making a MIDI “instrument”.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;comment&quot;&gt;/*
GND    GND
+5V    3.3V (preferred for safety)
VRx    GPIO 34
VRy    GPIO 35
SW    GPIO 27
*/&lt;/span&gt;

&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;math.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;BLEMidi.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;Arduino.h&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;define&lt;/span&gt; VRX_PIN 34&lt;/span&gt;
&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;define&lt;/span&gt; VRY_PIN 35&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
  &lt;span class=&quot;built_in&quot;&gt;Serial&lt;/span&gt;.&lt;span class=&quot;built_in&quot;&gt;begin&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;115200&lt;/span&gt;);
  BLEMidiServer.&lt;span class=&quot;built_in&quot;&gt;begin&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;Basic MIDI device&quot;&lt;/span&gt;);
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;(!BLEMidiServer.isConnected()) {
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;
  }
  &lt;span class=&quot;keyword&quot;&gt;float&lt;/span&gt; x = &lt;span class=&quot;built_in&quot;&gt;analogRead&lt;/span&gt;(VRX_PIN) / &lt;span class=&quot;number&quot;&gt;2048.0&lt;/span&gt; - &lt;span class=&quot;number&quot;&gt;1.0&lt;/span&gt;;
  &lt;span class=&quot;keyword&quot;&gt;float&lt;/span&gt; y = &lt;span class=&quot;built_in&quot;&gt;analogRead&lt;/span&gt;(VRY_PIN) / &lt;span class=&quot;number&quot;&gt;2048.0&lt;/span&gt; - &lt;span class=&quot;number&quot;&gt;1.0&lt;/span&gt;;

  &lt;span class=&quot;keyword&quot;&gt;float&lt;/span&gt; theta = &lt;span class=&quot;built_in&quot;&gt;atan2&lt;/span&gt;(y, x);
  &lt;span class=&quot;keyword&quot;&gt;float&lt;/span&gt; degrees = theta * &lt;span class=&quot;number&quot;&gt;180.0&lt;/span&gt; / PI;
  &lt;span class=&quot;keyword&quot;&gt;float&lt;/span&gt; magnitude = &lt;span class=&quot;built_in&quot;&gt;sqrt&lt;/span&gt;(x * x + y * y);

  &lt;span class=&quot;comment&quot;&gt;// don't play a note unless the joystick is far enough from center.&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;(magnitude &amp;gt; &lt;span class=&quot;number&quot;&gt;0.5&lt;/span&gt;) {
    &lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; note = &lt;span class=&quot;built_in&quot;&gt;map&lt;/span&gt;( (&lt;span class=&quot;number&quot;&gt;180&lt;/span&gt; + degrees) / &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;360&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;52&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;76&lt;/span&gt;);

    &lt;span class=&quot;built_in&quot;&gt;Serial&lt;/span&gt;.&lt;span class=&quot;built_in&quot;&gt;print&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;Note: &quot;&lt;/span&gt;);
    &lt;span class=&quot;built_in&quot;&gt;Serial&lt;/span&gt;.&lt;span class=&quot;built_in&quot;&gt;print&lt;/span&gt;(note);

    BLEMidiServer.noteOn(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, note, &lt;span class=&quot;number&quot;&gt;127&lt;/span&gt;);
    &lt;span class=&quot;built_in&quot;&gt;delay&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;);
    BLEMidiServer.noteOff(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, note, &lt;span class=&quot;number&quot;&gt;127&lt;/span&gt;);
  }
}&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Cookie Clicking</title>
      <link>http://localhost:8080/articles/cookie-clicking/</link>
      <pubDate>Wed, 16 Apr 2025 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/cookie-clicking/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Cookie_Clicker&quot;&gt;Cookie clicker&lt;/a&gt; is a video game
where the goal is to click a cookie many times. Each click increments a click counter,
and as the number of clicks increases power-ups are unlocked that accelerate
the counter incrementing rate. Clearly this is a silly and futile endeavor.
But not all silly and futile endeavors are entirely pointless. Enter the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Arduino_Uno&quot;&gt;Arduino leonardo&lt;/a&gt;, an IC controller
that can act as a keyboard and mouse.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/cookie-clicking/device.jpg&quot; alt=&quot;the device&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;the device in question&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;My idea was simple, use the arduino to send a continuous stream of mouse clicks.
One thing I learned from working with this thing in the past is that it’s good to
have a failsafe mechanism. It’s not fun to have a device sending hundreds of mouse clicks with no way to turn it off. So there’s a connection between pin 8
and ground. When that is connected, mouse clicks will be sent continuously at
whatever x-y coordinate is currently on screen. To stop it, just unplug that
jumper wire. If I had a more well-stocked parts bin I would have used an on-off
switch.&lt;/p&gt;
&lt;p&gt;So here’s code that emulates the mouse with the joystick (with a left click option using joystick press) and the continuous click when the jumper is
attached.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;Mouse.h&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; horzPin = A0;
&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; vertPin = A1;
&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; selPin = &lt;span class=&quot;number&quot;&gt;9&lt;/span&gt;;         &lt;span class=&quot;comment&quot;&gt;// Joystick button&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; togglePin = &lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;;      &lt;span class=&quot;comment&quot;&gt;// Jumper cable pin&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; vertZero, horzZero;
&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; vertValue, horzValue;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; sensitivity = &lt;span class=&quot;number&quot;&gt;200&lt;/span&gt;;

&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; invertMouse = &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;

&lt;span class=&quot;keyword&quot;&gt;bool&lt;/span&gt; lastTogglePinState = &lt;span class=&quot;literal&quot;&gt;HIGH&lt;/span&gt;;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;{
  &lt;span class=&quot;built_in&quot;&gt;pinMode&lt;/span&gt;(horzPin, &lt;span class=&quot;literal&quot;&gt;INPUT&lt;/span&gt;);
  &lt;span class=&quot;built_in&quot;&gt;pinMode&lt;/span&gt;(vertPin, &lt;span class=&quot;literal&quot;&gt;INPUT&lt;/span&gt;);
  &lt;span class=&quot;built_in&quot;&gt;pinMode&lt;/span&gt;(selPin, &lt;span class=&quot;literal&quot;&gt;INPUT_PULLUP&lt;/span&gt;);
  &lt;span class=&quot;built_in&quot;&gt;pinMode&lt;/span&gt;(togglePin, &lt;span class=&quot;literal&quot;&gt;INPUT_PULLUP&lt;/span&gt;);  &lt;span class=&quot;comment&quot;&gt;// Jumper defaults to HIGH&lt;/span&gt;

  &lt;span class=&quot;built_in&quot;&gt;Serial&lt;/span&gt;.&lt;span class=&quot;built_in&quot;&gt;begin&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;9600&lt;/span&gt;);  &lt;span class=&quot;comment&quot;&gt;// For logging&lt;/span&gt;

  &lt;span class=&quot;built_in&quot;&gt;delay&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;1000&lt;/span&gt;);
  vertZero = &lt;span class=&quot;built_in&quot;&gt;analogRead&lt;/span&gt;(vertPin);
  horzZero = &lt;span class=&quot;built_in&quot;&gt;analogRead&lt;/span&gt;(horzPin);

  &lt;span class=&quot;built_in&quot;&gt;Mouse&lt;/span&gt;.&lt;span class=&quot;built_in&quot;&gt;begin&lt;/span&gt;();
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;{
  &lt;span class=&quot;comment&quot;&gt;// Joystick movement&lt;/span&gt;
  vertValue = -(&lt;span class=&quot;built_in&quot;&gt;analogRead&lt;/span&gt;(vertPin) - vertZero);
  horzValue = &lt;span class=&quot;built_in&quot;&gt;analogRead&lt;/span&gt;(horzPin) - horzZero;

  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (vertValue != &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;)
    &lt;span class=&quot;built_in&quot;&gt;Mouse&lt;/span&gt;.&lt;span class=&quot;built_in&quot;&gt;move&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, (invertMouse * (vertValue / sensitivity)), &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;);
  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (horzValue != &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;)
    &lt;span class=&quot;built_in&quot;&gt;Mouse&lt;/span&gt;.&lt;span class=&quot;built_in&quot;&gt;move&lt;/span&gt;((invertMouse * (horzValue / sensitivity)), &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;);
  &lt;span class=&quot;keyword&quot;&gt;bool&lt;/span&gt; currentToggleState = &lt;span class=&quot;built_in&quot;&gt;digitalRead&lt;/span&gt;(togglePin);
  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (currentToggleState == &lt;span class=&quot;literal&quot;&gt;LOW&lt;/span&gt;) {
    &lt;span class=&quot;built_in&quot;&gt;Mouse&lt;/span&gt;.&lt;span class=&quot;built_in&quot;&gt;click&lt;/span&gt;();
  }
  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (currentToggleState != lastTogglePinState) {

    lastTogglePinState = currentToggleState;
    &lt;span class=&quot;built_in&quot;&gt;delay&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;);  &lt;span class=&quot;comment&quot;&gt;// Debounce&lt;/span&gt;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you plug this in you’ll get the &lt;a href=&quot;https://cookieclicker.fandom.com/wiki/Uncanny_Clicker&quot;&gt;uncanny clicker&lt;/a&gt;
achievement in the game from clicking so fast.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Using ollama to make an epub synopsis</title>
      <link>http://localhost:8080/articles/ollama-synopsis/</link>
      <pubDate>Wed, 08 May 2024 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/ollama-synopsis/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Like everyone else, I do my best to read many books, and like
many, I find it to be a challenge, not just in finding the time,
but also I found after you’ve read enough books, especially
non-fiction, a lot of the book seems like filler. Different
books on the same subject will cover the same material, or the
author will be needlessly verbose in covering a topic. I thought
‘if I just want to read this book for the content, not the style,
could I shorten it with an ai tool to ease some of the pain
points?’&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now, synopsisizing has a long history, and has met with it’s
share of detractors. For those wanting the sense of accomplishment
of finishing a book, this isn’t for you. On the other hand, Coles
Notes was once a staple of classrooms and campuses, and certainly
helped many students achieve their goals. A manager I had a couple
years ago was a proponent of using a synopsis site, I forget the
name, but it served a similar purpose.&lt;/p&gt;
&lt;p&gt;Anyways, I thought I would try making a tool to generate a
shortened version of a text. The idea is to turn a chapter
into something more like a page of text. My target genre
is lighter non-fiction books and books about management,
which I would like to read some of to help me with work.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/meta-llama/llama3&quot;&gt;llama3&lt;/a&gt; is a gpt model.
It’s pretty good, and you can download the full model and
weights. A few weeks ago I was trying to install it, but ran 
into the usual cuda issues on my macbook, and had some annoying
dependency issues derail me on my old linux machine that has a
1060 6GB that I use for AI stuff. So my momentum was gone. Then
the other day, someone posted on the #random channel at work
about &lt;a href=&quot;https://github.com/ollama/ollama/&quot;&gt;ollama&lt;/a&gt;, which comes
with a mac installer. I’ve always been a huge proponent of 
avoiding dependency hell. I’ve been pulled down into that morass
regularly for decades. I’ve spent more time manually copying
around specific versions of dll files than I can remember; that’s
just how it was in the .net 1.0 days.&lt;/p&gt;
&lt;p&gt;So, I ran the ollama installer. Once it is running you can do
&lt;code&gt;ollama run llama3&lt;/code&gt; and chat with llama, as if you were in the
instagram app. This can be useful, but running on my macbook, it’s
actually much faster to run the inference on facebooks servers
that I’m sure have hefty GPUs. But for my purpose I had another
idea.&lt;/p&gt;
&lt;p&gt;I can open an ebook in python. These contain a collection of 
xml documents, one per chapter. I can create batches of paragraphs
and get a synopsis of each by prompting the ollama ai.&lt;/p&gt;
&lt;p&gt;Here’s some code.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; itertools &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; islice
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; ebooklib
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; requests
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; bs4 &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; BeautifulSoup
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; json

&lt;span class=&quot;comment&quot;&gt;# I found this code on stack overflow for making&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;# batches from a collection:&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;batched&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(iterable, n)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;string&quot;&gt;&quot;Batch data into lists of length n. The last batch may be shorter.&quot;&lt;/span&gt;
    it = iter(iterable)
    &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;True&lt;/span&gt;:
        batch = list(islice(it, n))
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; batch:
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;yield&lt;/span&gt; batch

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;gen_prompt&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(author, title, all_text)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;string&quot;&gt;&quot;&quot;&quot;this is under the assumption that llama3 may already
    know something about the book, so it's a hint to add
    the title and author. I did not validate this assumption.&quot;&quot;&quot;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;f&quot;generate a synopsis of this excerpt from '&lt;span class=&quot;subst&quot;&gt;{title}&lt;/span&gt;'&quot;&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;by {author} with no preamble and without referencing the &quot;&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;author or the excerpt: {all_text}&quot;&lt;/span&gt;

to_shorten = &lt;span class=&quot;string&quot;&gt;'my_book.epub'&lt;/span&gt;
book = ebooklib.epub.read_epub(to_shorten)

&lt;span class=&quot;comment&quot;&gt;# larger means less to read, but you'll hit a limit of what&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;# llama can handle if this is too big.&lt;/span&gt;
text_batch_size = &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;

author = book.get_metadata(&lt;span class=&quot;string&quot;&gt;'DC'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'creator'&lt;/span&gt;)[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;][&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]
title = book.get_metadata(&lt;span class=&quot;string&quot;&gt;'DC'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'title'&lt;/span&gt;)[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;][&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]
print(&lt;span class=&quot;string&quot;&gt;f&quot;author: &lt;span class=&quot;subst&quot;&gt;{author}&lt;/span&gt; title: &lt;span class=&quot;subst&quot;&gt;{title}&lt;/span&gt;&quot;&lt;/span&gt;)

&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; item &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; book.get_items():
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; item.get_type() == ebooklib.ITEM_DOCUMENT:
        print(&lt;span class=&quot;string&quot;&gt;'=================================='&lt;/span&gt;)
        print(&lt;span class=&quot;string&quot;&gt;'NAME : '&lt;/span&gt;, item.get_name())
        content = item.get_content()

        &lt;span class=&quot;comment&quot;&gt;# probably not the best choice.&lt;/span&gt;
        y = BeautifulSoup(content)

        &lt;span class=&quot;comment&quot;&gt;# pretty sure this title logic will depend on which ebook&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;# you are reading.&lt;/span&gt;
        title = y.findAll(&lt;span class=&quot;string&quot;&gt;'h3'&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; title:
            print(&lt;span class=&quot;string&quot;&gt;f&quot;&lt;span class=&quot;subst&quot;&gt;{title[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;].text}&lt;/span&gt;&quot;&lt;/span&gt;)
            print(&lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;.join([&lt;span class=&quot;string&quot;&gt;'='&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; l &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; title[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;].text]))

        &lt;span class=&quot;comment&quot;&gt;# I don't know enough about epubs to say whether they&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;# all use the p tag.&lt;/span&gt;
        ps = y.findAll(&lt;span class=&quot;string&quot;&gt;'p'&lt;/span&gt;)

        batches = batched(ps, text_batch_size)
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; batch &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; batches:
            all_text = &lt;span class=&quot;string&quot;&gt;&quot; &quot;&lt;/span&gt;.join([p.text &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; p &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; ps])
            prompt = gen_prompt(author, title, all_text)

            &lt;span class=&quot;comment&quot;&gt;# thanks ollama&lt;/span&gt;
            url = &lt;span class=&quot;string&quot;&gt;&quot;http://localhost:11434/api/generate&quot;&lt;/span&gt;
            body = {
                &lt;span class=&quot;string&quot;&gt;&quot;model&quot;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;llama3&quot;&lt;/span&gt;,
                &lt;span class=&quot;string&quot;&gt;&quot;prompt&quot;&lt;/span&gt;: prompt
            }

            x = requests.post(url, json = body)
            generated = &lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;

            &lt;span class=&quot;comment&quot;&gt;# the response contains JSONL essentially.&lt;/span&gt;
            &lt;span class=&quot;comment&quot;&gt;# One word per response object line.&lt;/span&gt;
            &lt;span class=&quot;comment&quot;&gt;# Convert it back to readable.&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; dat &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; x.text.split(&lt;span class=&quot;string&quot;&gt;&quot;\n&quot;&lt;/span&gt;):
                &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; dat:
                    &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;
                js = json.loads(dat)
                generated += js[&lt;span class=&quot;string&quot;&gt;&quot;response&quot;&lt;/span&gt;]

            print(generated)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Overall the result is pretty good. I’m still trying to find a
prompt that won’t start half of the outputs with things like
&lt;code&gt;&amp;quot;Here&amp;#39;s a synopsis of the excerpt:&amp;quot;&lt;/code&gt;, so it will read better,
but overall I’m quite happy with the results. Whether I’m happy
enough to get this running on my 1060, or if I’ll ever use it
again remains to be seen. But I did use it to get the “super gist”
of a book I had already read half of, and it worked quite well. I
mentioned in my intro how I find many of these kinds of books to
be quite repetitive and low-density for information. This leads
me to doing skimming. I think for me, if I pay close attention to
a synopsis rather than skimming, the result is about the same.
This post must be leading by far in justifications and
rationalizations per whatever, but that’s the nature of AI.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>An Intro to Data Build Tool (dbt) With Hive</title>
      <link>http://localhost:8080/articles/dbt-hive/</link>
      <pubDate>Mon, 25 Mar 2024 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/dbt-hive/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;DBT has support for a wide variety of databases. So far, I’ve been using
Google’s bigquery as the database for all of my DBT blog posts, so let’s
try something different. For this demo I’ll use &lt;a href=&quot;https://hive.apache.org/&quot;&gt;Apache Hive&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;development-environment-setup&quot;&gt;Development Environment Setup&lt;/h2&gt;
&lt;p&gt;Apache hive has a &lt;a href=&quot;https://hive.apache.org/developement/quickstart/&quot;&gt;quickstart guide&lt;/a&gt;
that doesn’t quite work, so I will provide the steps I took to get it going
in &lt;code&gt;podman&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;First, a very important step (I could imagine people wearing shirts with
this):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;alias&lt;/span&gt; docker=podman&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, pull the image:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker pull apache/hive:4.0.0-alpha-2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, run the image:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;export&lt;/span&gt; HIVE_VERSION=4.0.0-alpha-2
docker &lt;span class=&quot;built_in&quot;&gt;exec&lt;/span&gt; -it hive4 beeline -u &lt;span class=&quot;string&quot;&gt;'jdbc:hive2://localhost:10000/'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will put you into a beeline shell (a hive CLI). Keep this open.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-dbt-&quot;&gt;Setting up DBT.&lt;/h2&gt;
&lt;p&gt;This is based on the &lt;a href=&quot;https://docs.getdbt.com/docs/core/connect-data-platform/hive-setup&quot;&gt;dbt hive setup&lt;/a&gt;. First, edit &lt;code&gt;~/.dbt/profiles.yml&lt;/code&gt;. Add
something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;attr&quot;&gt;hive:&lt;/span&gt;
  &lt;span class=&quot;attr&quot;&gt;target:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;dev&lt;/span&gt;
  &lt;span class=&quot;attr&quot;&gt;outputs:&lt;/span&gt;
    &lt;span class=&quot;attr&quot;&gt;dev:&lt;/span&gt;
      &lt;span class=&quot;attr&quot;&gt;type:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;hive&lt;/span&gt;
      &lt;span class=&quot;attr&quot;&gt;host:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;localhost&lt;/span&gt;
      &lt;span class=&quot;attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;10000&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;# match your docker run from before.&lt;/span&gt;
      &lt;span class=&quot;attr&quot;&gt;schema:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;my_schema&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now do &lt;code&gt;pip install dbt-hive&lt;/code&gt;, then &lt;code&gt;dbt init ${your_project}&lt;/code&gt; and choose
hive for the adapter. Edit your new &lt;code&gt;dbt_project.yml&lt;/code&gt; and make sure your
profile name matches what is in the profiles file.&lt;/p&gt;
&lt;p&gt;Now you should be able to do whatever you want in dbt. For my example, I 
set up a quick seed called &lt;code&gt;randoms.csv&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csv&quot;&gt;id,random_value
1,2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a personal in-joke with myself. I had a professor in university
[Dr Marco Polannen], who, when teaching us about randomness said “is 2
random?” (The point was that a single number can’t really be random,
randomness is a property of a sequence where it is the shortest definition
of itself). So after naming my model “random” I thought 2 would be a good
seed value. Anyways… now you can run &lt;code&gt;dbt seed&lt;/code&gt;. If all goes well, you
can return to your beeline shell and run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; * &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; my_schema.randoms;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And see something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;+-------------+-----------------------+
| randoms.id  | randoms.random_value  |
+-------------+-----------------------+
| 1           | 2                     |
+-------------+-----------------------+&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And that’s it. You could extend this starting point to add tests, models
and so on. Have a nice day.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>An Intro to Data Build Tool (dbt) Hooks</title>
      <link>http://localhost:8080/articles/dbt-hooks/</link>
      <pubDate>Tue, 19 Mar 2024 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/dbt-hooks/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;https://getdbt.com/&quot;&gt;DBT&lt;/a&gt; supports &lt;a href=&quot;https://docs.getdbt.com/docs/build/hooks-operations&quot;&gt;hooks&lt;/a&gt;, which are a mechanism for
running operations at different points of the execution of your DBT
DAG. This is useful for running operations like adding a record to an
audit table, running specific reports, and more.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Here I will show an example based on my “enriched movies” example from my
previous blog post. Consider the use case where you want to export a table
to your data lake after populating it using DBT run. You could do 
something like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-jinja&quot;&gt;&lt;span class=&quot;template-variable&quot;&gt;{{ config(
  post_hook = &quot;EXPORT DATA
  OPTIONS (
    uri = 'gs://bq_movie_export/movie_export/*.json',
    format = 'JSON',
    overwrite = true)
AS (
  SELECT *
  FROM dbt_bwendt.enriched_movies
  ORDER BY movie_title
);
&quot;
) }}&lt;/span&gt;&lt;span class=&quot;xml&quot;&gt;

with movies as (
    select id as movie_id, title
    from &lt;/span&gt;&lt;span class=&quot;template-variable&quot;&gt;{{ ref('movies') }}&lt;/span&gt;&lt;span class=&quot;xml&quot;&gt;
),
actors as (
    select id as actor_id, name
    from &lt;/span&gt;&lt;span class=&quot;template-variable&quot;&gt;{{ ref('actors') }}&lt;/span&gt;&lt;span class=&quot;xml&quot;&gt;
),
movie_actor_mapping as (
    select id, movie_id, actor_id
    from &lt;/span&gt;&lt;span class=&quot;template-variable&quot;&gt;{{ ref('stg_actor_movies') }}&lt;/span&gt;&lt;span class=&quot;xml&quot;&gt;
)
select movie_actor_mapping.id,
    movies.title as movie_title,
    actors.name as actor_name
from movie_actor_mapping
join movies using (movie_id)
join actors using (actor_id)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the use of the &lt;code&gt;config&lt;/code&gt; macro with a post hook specified. The
action performed by the post hook is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;EXPORT DATA
  OPTIONS (
    uri = 'gs://bq_movie_export/movie_export&lt;span class=&quot;comment&quot;&gt;/*.json',
    format = 'JSON',
    overwrite = true)
AS (
  SELECT *
  FROM dbt_bwendt.enriched_movies
  ORDER BY movie_title
);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a bigquery specific export option that will write the table
to the specified GCS location. If you were to look in the generated file,
you would see this in JSONL format:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{&lt;span class=&quot;attr&quot;&gt;&quot;id&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;3&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;movie_title&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Avatar&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;actor_name&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Sigourney Weaver&quot;&lt;/span&gt;}
{&lt;span class=&quot;attr&quot;&gt;&quot;id&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;5&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;movie_title&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Paul&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;actor_name&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Sigourney Weaver&quot;&lt;/span&gt;}
{&lt;span class=&quot;attr&quot;&gt;&quot;id&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;2&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;movie_title&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Speed&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;actor_name&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Keanu Reeves&quot;&lt;/span&gt;}
{&lt;span class=&quot;attr&quot;&gt;&quot;id&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;1&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;movie_title&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Speed&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;actor_name&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Sandra Bullock&quot;&lt;/span&gt;}
{&lt;span class=&quot;attr&quot;&gt;&quot;id&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;6&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;movie_title&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Terminator 2&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;actor_name&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Linda Hamilton&quot;&lt;/span&gt;}
{&lt;span class=&quot;attr&quot;&gt;&quot;id&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;4&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;movie_title&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;The Matrix&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;actor_name&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Keanu Reeves&quot;&lt;/span&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bigquery’s export automatically writes these out in a way that will be easy to read into another distributed processing engine like dataprow or
dataflow.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>An Intro to Data Build Tool (dbt)</title>
      <link>http://localhost:8080/articles/dbt-intro/</link>
      <pubDate>Tue, 12 Mar 2024 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/dbt-intro/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;DBT is a tool to simplify populating the relationships
between different tables. With DBT, you can specify the
queries used to create your tables, as well as parameterizing
portions of those queries. You can also add data tests.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;introduction-getting-to-know-data-build-tool-dbt-&quot;&gt;Introduction: Getting to Know Data Build Tool (dbt)&lt;/h2&gt;
&lt;p&gt;Ever wished for a smoother way to handle your data without the 
headaches of complex ETL processes? Enter Data Build Tool, or 
as we fondly call it, DBT. It makes data transformations and 
modeling feel like a breeze.&lt;/p&gt;
&lt;p&gt;DBT takes a refreshing approach to data pipelines, letting you 
express your data transformations in good old SQL. No need for 
fancy jargon or convoluted workflows—just simple, 
straightforward SQL magic.&lt;/p&gt;
&lt;p&gt;In this article, we’ll take a relaxed stroll through the world 
of DBT, from setting it up to some cool tricks it can do. So 
grab your favorite drink, kick back, and let’s dive into the 
world of DBT together!&lt;/p&gt;
&lt;h2 id=&quot;installation-of-project-bootsrapping-&quot;&gt;Installation of Project Bootsrapping.&lt;/h2&gt;
&lt;p&gt;To get started with dbt, the recommended method for 
installation is to use pip.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install dbt-{your adapater}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am using bigquery, but there are adapters for all the major
database engines, including snowflake, postgres, cassandra,
mySQL, SQLServer, SQLite, Oracle, Athena, Redshift and many more.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.getdbt.com/docs/trusted-adapters&quot;&gt;Trusted Adapters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.getdbt.com/docs/community-adapters&quot;&gt;Community Adapters&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So for me, the install was done with:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install dbt-bigquery&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This mat take a while because it has to install some GCS
dependencies, such as grpc. You can then confirm your DBT
installed correctly with:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;dbt --version&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you will be ready to start your own DBT project. I have
been keeping a GCP console open to bigquery to verify my
changes.&lt;/p&gt;
&lt;p&gt;First navigate to the parent folder of where you want to store
your DBT project, and then run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;dbt init&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will start a configuration wizard which has fairly 
reasonable defaults. When the configuration is complete, &lt;code&gt;cd&lt;/code&gt; 
to your new folder and you will be ready to start working with 
DBT.&lt;/p&gt;
&lt;h2 id=&quot;dbt-profiles&quot;&gt;DBT Profiles&lt;/h2&gt;
&lt;p&gt;DBT init will have created a file named &lt;code&gt;dbt_project.yml&lt;/code&gt; in
your project root. Take a look! This will have all the info
you entered in the setup wizard. It’s also where you can
configure connections to external sources of data.&lt;/p&gt;
&lt;p&gt;We can add a reference to the public &lt;code&gt;dbt-tutorial&lt;/code&gt; dataset
in GCP by adding this to &lt;code&gt;dbt_profile.yml&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;attr&quot;&gt;jaffle_shop:&lt;/span&gt;
  &lt;span class=&quot;attr&quot;&gt;target:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;dev&lt;/span&gt;
  &lt;span class=&quot;attr&quot;&gt;outputs:&lt;/span&gt;
    &lt;span class=&quot;attr&quot;&gt;dev:&lt;/span&gt;
      &lt;span class=&quot;attr&quot;&gt;type:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;bigquery&lt;/span&gt;
      &lt;span class=&quot;attr&quot;&gt;method:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;oauth&lt;/span&gt;
      &lt;span class=&quot;attr&quot;&gt;project:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;dbt-tutorial&lt;/span&gt;
      &lt;span class=&quot;attr&quot;&gt;dataset:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;jaffle_shop&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your profile is also the place where you configure your
materialization strategy. The default is view. You can
configure this by:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;attr&quot;&gt;models:&lt;/span&gt;
  &lt;span class=&quot;attr&quot;&gt;my_dataset:&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;# Config indicated by + and applies to all files&lt;/span&gt;
    &lt;span class=&quot;string&quot;&gt;+materialized:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;table&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can override this materialization config on a per-model
basis in your model.&lt;/p&gt;
&lt;h2 id=&quot;database-seeds&quot;&gt;Database Seeds&lt;/h2&gt;
&lt;p&gt;DBT supports database &lt;a href=&quot;https://docs.getdbt.com/docs/build/seeds&quot;&gt;seeds&lt;/a&gt;. These are described as:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Seeds are CSV files in your dbt project (typically in your seeds directory), that dbt can load into your data warehouse using the dbt seed command.
Seeds are best suited to static data which changes infrequently.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Seeds are not meant as a way of loading database dumps,
but it does seem like it would be pretty easy to abuse
this.&lt;/p&gt;
&lt;p&gt;Here are some seeds I will use for my demo.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;seeds/movies.csv&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csv&quot;&gt;id,title,year 
1,Speed,1994
2,Avatar,2008
3,The Matrix,1998
4,Paul,2012
5,Terminator 2,1992&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;seeds/actors.csv&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csv&quot;&gt;id,name
1,Sandra Bullock
2,Keanu Reeves
3,Mickey Rooney
4,Sigourney Weaver
5,Nick Frost
6,Linda Hamilton&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;seeds/stg_actor_movies.csv&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csv&quot;&gt;id,movie_id,actor_id
1,1,1
2,1,2
3,2,4
4,3,2
5,4,4
6,5,6&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that this is closer to “loading a dump” than
proper seed loading, but this is for a demo, so that
is fine.&lt;/p&gt;
&lt;p&gt;If you now run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;dbt run&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And look in your database, you should see these three tables.&lt;/p&gt;
&lt;h2 id=&quot;models&quot;&gt;Models&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;models/&lt;/code&gt; folder is where you will put your model files.
You can put a file in here such as:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;flowers.sql&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;id&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'flea bane'&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; plant
&lt;span class=&quot;keyword&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;all&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'showy tick trefoil'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After a DBT run, these will appear in your database. It would 
be more common to do something like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;stg_customers.sql&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; customer_id,
        first_name,
        last_name

    &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; {{ &lt;span class=&quot;keyword&quot;&gt;ref&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'jaffle_shop'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'customers'&lt;/span&gt;) }}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the use of the &lt;a href=&quot;https://docs.getdbt.com/reference/dbt-jinja-functions/ref&quot;&gt;ref&lt;/a&gt;
function here. DBT will resolve this reference to the table 
you set up in your profile; note how the first parameter
&lt;code&gt;jaffle_shop&lt;/code&gt; matches the profile name, and &lt;code&gt;customers&lt;/code&gt; is
the name of the table in that public dataset.&lt;/p&gt;
&lt;h3 id=&quot;macros&quot;&gt;Macros&lt;/h3&gt;
&lt;p&gt;In the &lt;code&gt;macros/&lt;/code&gt; folder, you can define jinja macros that will
be accessible from your models. For example, you could make a
good customers macro called &lt;code&gt;good_customer.sql&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;{% macro good_customer(number_of_orders) %}
CASE when {{ number_of_orders }} &amp;gt;= 3 then
    true
    else
    false
end
{% endmacro %}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is needlessly verbose but serves to illustrate how to use
a macro. Assume then that we use this macro in model called
&lt;code&gt;customers.sql&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; customers &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; (
 &lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; * &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; {{ &lt;span class=&quot;keyword&quot;&gt;ref&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'stg_customers'&lt;/span&gt;) }}

),

orders &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; (

    &lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; * &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; {{ &lt;span class=&quot;keyword&quot;&gt;ref&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'stg_orders'&lt;/span&gt;) }}

),

customer_orders &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; (

    &lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt;
        customer_id,

        &lt;span class=&quot;keyword&quot;&gt;min&lt;/span&gt;(order_date) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; first_order_date,
        &lt;span class=&quot;keyword&quot;&gt;max&lt;/span&gt;(order_date) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; most_recent_order_date,
        &lt;span class=&quot;keyword&quot;&gt;count&lt;/span&gt;(order_id) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; number_of_orders

    &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; orders

    &lt;span class=&quot;keyword&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;

),

&lt;span class=&quot;keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; (

    &lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt;
        customers.customer_id,
        customers.first_name,
        customers.last_name,
        customer_orders.first_order_date,
        customer_orders.most_recent_order_date,
        &lt;span class=&quot;keyword&quot;&gt;coalesce&lt;/span&gt;(customer_orders.number_of_orders, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; number_of_orders,
        {{ good_customer(&lt;span class=&quot;string&quot;&gt;'customer_orders.number_of_orders'&lt;/span&gt;) }} &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; is_good_customer
    &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; customers

    &lt;span class=&quot;keyword&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;join&lt;/span&gt; customer_orders &lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; (customer_id)

)

&lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; * &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;final&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here you see the reference to the &lt;code&gt;good_customer&lt;/code&gt; macro. You
can see the generated sql by looking in the &lt;code&gt;target&lt;/code&gt; folder.
So for this model, you could run
&lt;code&gt;cat target/compiled/my_proj/models/customers.sql&lt;/code&gt;, where you would see something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; customers &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; (
 &lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; * &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;`my_proj`&lt;/span&gt;.&lt;span class=&quot;string&quot;&gt;`my_dataset`&lt;/span&gt;.&lt;span class=&quot;string&quot;&gt;`stg_customers`&lt;/span&gt;

),

orders &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; (

    &lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; * &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;`my_proj`&lt;/span&gt;.&lt;span class=&quot;string&quot;&gt;`my_dataset`&lt;/span&gt;.&lt;span class=&quot;string&quot;&gt;`stg_orders`&lt;/span&gt;

),

customer_orders &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; (

    &lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt;
        customer_id,

        &lt;span class=&quot;keyword&quot;&gt;min&lt;/span&gt;(order_date) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; first_order_date,
        &lt;span class=&quot;keyword&quot;&gt;max&lt;/span&gt;(order_date) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; most_recent_order_date,
        &lt;span class=&quot;keyword&quot;&gt;count&lt;/span&gt;(order_id) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; number_of_orders

    &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; orders

    &lt;span class=&quot;keyword&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;

),

&lt;span class=&quot;keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; (

    &lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt;
        customers.customer_id,
        customers.first_name,
        customers.last_name,
        customer_orders.first_order_date,
        customer_orders.most_recent_order_date,
        &lt;span class=&quot;keyword&quot;&gt;coalesce&lt;/span&gt;(customer_orders.number_of_orders, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; number_of_orders,

&lt;span class=&quot;keyword&quot;&gt;CASE&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;when&lt;/span&gt; customer_orders.number_of_orders &amp;gt;= &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;literal&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
 &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; is_good_customer
    &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; customers

    &lt;span class=&quot;keyword&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;join&lt;/span&gt; customer_orders &lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; (customer_id)

)

&lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; * &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;final&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note how the case statement has been inlined from the macro.&lt;/p&gt;
&lt;h2 id=&quot;schemas&quot;&gt;Schemas&lt;/h2&gt;
&lt;p&gt;In the model folder, there is a file called &lt;code&gt;schema.yml&lt;/code&gt; that
will contain the schemas of all of your tables in yaml format.
This is not auto-generated. You should be going in here and 
populating any fields you create. So for my customers table, I 
have:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;attr&quot;&gt;models:&lt;/span&gt;
  &lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;customers&lt;/span&gt;
    &lt;span class=&quot;attr&quot;&gt;description:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;One&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;per&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;customer&lt;/span&gt;
    &lt;span class=&quot;attr&quot;&gt;columns:&lt;/span&gt;
      &lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;customer_id&lt;/span&gt;
        &lt;span class=&quot;attr&quot;&gt;description:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;Primary&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;key&lt;/span&gt;
        &lt;span class=&quot;attr&quot;&gt;tests:&lt;/span&gt;
          &lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;unique&lt;/span&gt;
          &lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;not_null&lt;/span&gt;
      &lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;first_order_date&lt;/span&gt;
        &lt;span class=&quot;attr&quot;&gt;description:&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;customer&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;yet&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;placed&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;an&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;order.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the presence of the &lt;code&gt;tests&lt;/code&gt; key. This is where you will
define your data tests, including the ones I’ve shown here
for column constraints, but you can do more interesting stuff
as well.&lt;/p&gt;
&lt;p&gt;A DBT test passes when the query it represents returns zero
rows. So imagine I made a macro called
&lt;code&gt;test_does_not_contain.sql&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;{% macro test_does_not_contain(model, column_name, unwanted) %}
select {{column_name}}
from {{model}}
where contains_substr({{column_name}}, &amp;#39;{{unwanted}}&amp;#39;)
{% endmacro %}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Note that test macro names must begin with &lt;code&gt;test_&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;I can then use this test for my fields by adding it in the 
schema, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;customer_orders_by_name&lt;/span&gt;
    &lt;span class=&quot;attr&quot;&gt;description:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;report&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;how&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;many&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;orders&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;come&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;customers&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;per&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;name.&lt;/span&gt;
    &lt;span class=&quot;attr&quot;&gt;columns:&lt;/span&gt;
      &lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;first_name&lt;/span&gt;
        &lt;span class=&quot;attr&quot;&gt;description:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;1st&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;name.&lt;/span&gt;
        &lt;span class=&quot;attr&quot;&gt;tests:&lt;/span&gt;
          &lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;unique&lt;/span&gt;
          &lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;not_null&lt;/span&gt;
          &lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;does_not_contain:&lt;/span&gt;
              &lt;span class=&quot;attr&quot;&gt;unwanted:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;😂&lt;/span&gt;
      &lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;total_orders&lt;/span&gt;
        &lt;span class=&quot;attr&quot;&gt;tests:&lt;/span&gt;
          &lt;span class=&quot;bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;dbt_expectations.expect_column_values_to_be_between:&lt;/span&gt;
              &lt;span class=&quot;attr&quot;&gt;min_value:&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
              &lt;span class=&quot;attr&quot;&gt;strictly:&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will now throw an error if any first names contain the
laughing smiling emoji ‘😂’.&lt;/p&gt;
&lt;p&gt;Note the second added test. After installing the 
&lt;code&gt;dbt_expectations&lt;/code&gt; package you can use its tests, and this one
does range checking. You can install the package by running
&lt;code&gt;dbt deps --add-package dbt_expectations:1.0.0&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;data-tests&quot;&gt;Data Tests&lt;/h2&gt;
&lt;p&gt;For larger tests, such as data quality tests, you can add a 
test in the tests folder, like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; 
    order_amount_cents
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt;
    {{ &lt;span class=&quot;keyword&quot;&gt;ref&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'order_amounts'&lt;/span&gt;) }}
&lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; order_amount_cents &amp;lt;= &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As before, DBT expects zero rows to be returned from a test 
for it to pass. You can configure the expected number of rows
for a failure or warning. You can run all the tests with
&lt;code&gt;dbt test&lt;/code&gt;. Tests will likely fail if you haven’t first 
populated their underlying tables. Tests also run when you do
&lt;code&gt;dbt run&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;analyses&quot;&gt;Analyses&lt;/h1&gt;
&lt;p&gt;If you want the goodness of re-usable code to generate SQL
without necessarily using it to populate a table, you can 
put SQL in the analyses folder. For example you could make
&lt;code&gt;movies_by_year.sql&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;year&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;count&lt;/span&gt;(*)
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt;
    {{ &lt;span class=&quot;keyword&quot;&gt;ref&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'movies'&lt;/span&gt;) }}
&lt;span class=&quot;keyword&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;year&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then run&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;dbt compile&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then inspect the file:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cat target/compiled/my_proj/analyses/movies_by_year.sql&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will give you something like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;year&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;count&lt;/span&gt;(*)
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt;
    &lt;span class=&quot;string&quot;&gt;`my_project`&lt;/span&gt;.&lt;span class=&quot;string&quot;&gt;`my_dataset`&lt;/span&gt;.&lt;span class=&quot;string&quot;&gt;`movies`&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;year&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;python-models&quot;&gt;Python models&lt;/h2&gt;
&lt;p&gt;DBT also supports &lt;a href=&quot;https://docs.getdbt.com/docs/build/python-models&quot;&gt;python models&lt;/a&gt;.
 You could make something like &lt;code&gt;transformed_customers.py&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;my_transform&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(name)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;f&quot;&lt;span class=&quot;subst&quot;&gt;{name}&lt;/span&gt; &lt;span class=&quot;subst&quot;&gt;{name[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;].lower()}&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(dbt, session)&lt;/span&gt;:&lt;/span&gt;
    dbt.config(materialized=&lt;span class=&quot;string&quot;&gt;&quot;table&quot;&lt;/span&gt;)

    df = dbt.ref(&lt;span class=&quot;string&quot;&gt;&quot;customers&quot;&lt;/span&gt;)

    pdf = df.to_pandas()

    pdf[&lt;span class=&quot;string&quot;&gt;'name2'&lt;/span&gt;] = pdf[&lt;span class=&quot;string&quot;&gt;'first_name'&lt;/span&gt;].apply(my_transform)

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; pdf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You don’t have to use pandas here. In fact, is probably
quite often a bad idea. &lt;code&gt;df&lt;/code&gt; will be a spark data frame.&lt;/p&gt;
&lt;p&gt;This will apply your custom transformation logic to each row
and save that in the new table. Note that the python logic
will be run through whatever flavour of spark is convenient
for your platform. So since I’m using bigquery, that means
dataproc.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;And there you have it -— your crash course in Data Build Tool 
(DBT). It’s like the Swiss Army knife of data, simplifying 
your life and making building and managing data projects a 
whole lot easier.&lt;/p&gt;
&lt;p&gt;As you venture into the world of DBT, remember that you’re 
equipped with a powerful tool that’s trusted by data 
professionals worldwide. Whether you’re a seasoned analyst or 
a newcomer to the data scene, DBT offers a friendly and 
intuitive platform to work with.&lt;/p&gt;
&lt;p&gt;So take a deep breath, relax, and dive into the wonderful 
world of DBT. Experiment, explore, and have fun with it! After 
all, data doesn’t have to be daunting -— it can be downright 
delightful with DBT by your side.&lt;/p&gt;
&lt;p&gt;Here’s to embracing data adventures with a smile—dbt style!&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Finding Sator Squares</title>
      <link>http://localhost:8080/articles/sator-square/</link>
      <pubDate>Sun, 12 Nov 2023 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/sator-square/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I had a visit with my mother recently where she introduced me to the idea of
&lt;a href=&quot;https://en.wikipedia.org/wiki/Sator_Square&quot;&gt;Sator Squares&lt;/a&gt;. It’s a five letter
acrostic, popular in ancient Rome, and originally rediscovered during the 
excavation of Pompei and Herculaneum. It has the interesting property that
transposition of the matrix is an identity operation.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/sator-square/sator.jpg&quot; alt=&quot;sator square&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Image from wikipedia&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The drawing she wrote of it has been sitting on my counter for ages, and 
I’ve been meaning to code it ever since I first saw it.&lt;/p&gt;
&lt;p&gt;Here’s a definition of whether or not a collection of five words (assumed
to be five letters, which is safe because I’m re-using my wordle dictionary):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;is_sator2&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(w0, w1, w2, w3, w4)&lt;/span&gt; -&amp;gt; bool:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; w0[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] == w1[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; w0[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;] == w2[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; w0[&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;] == w3[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; w4[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] == w0[&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;] \
        &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; w1[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;] == w2[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; w1[&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;] == w3[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; w1[&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;] == w4[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] \
        &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; w2[&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;] == w3[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; w2[&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;] == w4[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;] \
        &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; w3[&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;] == w4[&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I tried using &lt;code&gt;itertools.permutations&lt;/code&gt; to check every option, but it was horribly
inefficient, due to checking so many things that aren’t even possibly sator squares.&lt;/p&gt;
&lt;p&gt;Here’s an optimization that can rip through thousands of words per second:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# word_map is a mapping of first letters to words that start&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;# with that letter.&lt;/span&gt;
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;look_for_sator&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(search_in, word_map)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; word0 &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; search_in:
        print(word0)
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; word1 &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; word_map[word0[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]]:
            &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; word2 &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; word_map[word0[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;]]:
                &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; word2[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] != word1[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;]:
                    &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;
                &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; word3 &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; word_map[word0[&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;]]:
                    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; word3[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] != word1[&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;or&lt;/span&gt; word3[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;] != word2[&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;]:
                        &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;
                    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; word4 &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; word_map[word0[&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;]]:
                        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; word4[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] != word1[&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;or&lt;/span&gt; word4[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;] != word2[&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;or&lt;/span&gt; word4[&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;] != word3[&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;]:
                            &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;
                        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; is_sator(word0, word1, word2, word3, word4):
                            print(&lt;span class=&quot;string&quot;&gt;&quot;======&quot;&lt;/span&gt;)
                            print_sator((word0, word1, word2, word3, word4))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will give nice outputs like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hippo
======
hippo
idler
plead
peace
order
======
hippo
inlet
plant
pence
otter
======
hippo
inlet
plant
penne
otter
======
hippo
inlet
pleat
peace
otter
======
hippo
islet
plant
pence
otter
======
hippo
islet
plant
penne
otter
======
hippo
islet
pleat
peace
otter&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>An uninformative error in bigquery</title>
      <link>http://localhost:8080/articles/bigquery-error/</link>
      <pubDate>Tue, 24 Oct 2023 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/bigquery-error/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Just a quick note about an uninformative error I saw in bigquery the other day
and was having trouble finding on google. If you see the error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MaterializedView is required for DerivationSpec&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When trying to create a materialized view in bigquery on google cloud platform (GCP),
it means you didn’t specify the query, or including an empty query. It’s an easy
mistake to make. Maybe this will help someone some day.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Schemas and SqlTransform in Beam</title>
      <link>http://localhost:8080/articles/schemas-sql-beam/</link>
      <pubDate>Thu, 13 Jul 2023 00:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/schemas-sql-beam/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Beam has support for working with collections of data that conforms
to a schema, and you can use SQL Transforms to transform this data.
This feels a bit more like working with data in spark, but beam
does not have the same level of optimization.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Here’s some imports. I’ll leave these in because beam’s docs are not
great and I had to copy these out of a &lt;a href=&quot;https://www.youtube.com/watch?v=zx4p-UNSmrA&quot;&gt;youtube video&lt;/a&gt;
when I was learning to do this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; apache_beam &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; beam
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; apache_beam.transforms.sql &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; SqlTransform

&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; typing

&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; faker &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; Faker&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is my schema class. Beam wants it to be a named tuple.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(typing.NamedTuple)&lt;/span&gt;:&lt;/span&gt;
    person_id: int
    name: str
    fave_color: str&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you have to register a coder for the class:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;beam.coders.registry.register_coder(Person, beam.coders.RowCoder)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here’s an example showing some usage of the schema and a
transformation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; beam.Pipeline() &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; p:
    fake = Faker()
    people = (
        p |
        &lt;span class=&quot;string&quot;&gt;&quot;get ids&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Create(list(range(&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;_000)))
        | &lt;span class=&quot;string&quot;&gt;&quot;to people&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Map(&lt;span class=&quot;keyword&quot;&gt;lambda&lt;/span&gt; person_id: Person(
            person_id=person_id,
            name=fake.name(),
            fave_color=fake.color_name()
            )
        ).with_output_types(Person)
        | SqlTransform(&lt;span class=&quot;string&quot;&gt;&quot;&quot;&quot;
            select fave_color, count(*) as `COUNT`
            FROM PCOLLECTION
            group by fave_color
        &quot;&quot;&quot;&lt;/span&gt;)
        | &lt;span class=&quot;string&quot;&gt;&quot;print&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Map(&lt;span class=&quot;keyword&quot;&gt;print&lt;/span&gt;)
    )&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Solving Spelling Bee and Letter Boxed</title>
      <link>http://localhost:8080/articles/spelling-bee-and-letter-boxed/</link>
      <pubDate>Mon, 14 Nov 2022 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/spelling-bee-and-letter-boxed/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I’ve written &lt;em&gt;many&lt;/em&gt; times about solving wordle. I still play wordle most
days, but recently I’ve moved on to playing other daily games available
on the NYT site,
&lt;a href=&quot;https://www.nytimes.com/puzzles/spelling-bee&quot;&gt;spellling bee&lt;/a&gt; and
&lt;a href=&quot;https://www.nytimes.com/puzzles/letter-boxed&quot;&gt;letter boxed&lt;/a&gt;. So let’s
solve those too.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/spelling-bee-and-letter-boxed/spellingbee.png&quot; alt=&quot;spelling bee&quot;&gt;&lt;/p&gt;
&lt;p&gt;Spelling bee is just about spelling as many words as you can, but they
all have to inclue the central letter. The ideal is to get a
&lt;a href=&quot;https://en.wikipedia.org/wiki/Pangram&quot;&gt;pangram&lt;/a&gt;, i.e. a word that
includes all the available letters.&lt;/p&gt;
&lt;p&gt;Here’s a regular expression that will find all possible solutions to spelling bee, assuming &lt;code&gt;clhawbe&lt;/code&gt; are the available letters and &lt;code&gt;a&lt;/code&gt; is
the mandatory letter:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;grep -E &lt;span class=&quot;string&quot;&gt;'^[clhawbe]+$'&lt;/span&gt; /usr/share/dict/words | grep a&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This doesn’t solve the pangram but it should be clear how to extend to
solve for that.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/spelling-bee-and-letter-boxed/letterboxed.png&quot; alt=&quot;letter boxed&quot;&gt;&lt;/p&gt;
&lt;p&gt;Letter boxed is played on a box with three letters on each side. The aim
is to spell words that use up all the letters within five turns, but 
you cannot use two consecutive letters from the same side of the 
square. And each new word must start with the final letter of the
previous word. Here’s a python that gives all the words you can spell.
First, we’ll set up the dictionary and the letters we have to work with:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; english_words &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; english_words_set

english_words = list(english_words_set)

groups = ((&lt;span class=&quot;string&quot;&gt;'r'&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;'h'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'t'&lt;/span&gt;), (&lt;span class=&quot;string&quot;&gt;'m'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'a'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'d'&lt;/span&gt;), (&lt;span class=&quot;string&quot;&gt;'u'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'s'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'o'&lt;/span&gt;), (&lt;span class=&quot;string&quot;&gt;'i'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'w'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'c'&lt;/span&gt;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s the function that can determine whether a word can be spelled 
given the rules of the game:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;can_spell_word&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(word, groups, exclude_group=None)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; word == &lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;:
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; i, group &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; enumerate(groups):
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; i == exclude_group:
            &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; word[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; group:
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; can_spell_word(word[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;:], groups, i)

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;False&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ages ago I was talking programming with some colleagues. One mentioned
having trouble thinking about how to write recursive functions. A second
co-worker recounted something one of his professors had told him:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The trick to writing recursive functions is to write it like it’s already been written.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I love that expression.&lt;/p&gt;
&lt;p&gt;Anyways, here’s iterating through the dictionary to find the words you
can spell:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;found_words = []
&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; word &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; english_words:
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; len(word) &amp;lt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;:
        &lt;span class=&quot;comment&quot;&gt;# game rule of minimum letters.&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; can_spell_word(word, groups):
        found_words.append(word)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I didn’t bother extending this to finding which groups of words can
solve letter boxed in a given number of turns, or the least number of
turns but it should be very doable from here.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Safe Navigation in Python</title>
      <link>http://localhost:8080/articles/safe-navigate-python/</link>
      <pubDate>Wed, 12 Oct 2022 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/safe-navigate-python/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;In a chain of method calls, what happens when
one of the calls returns a null? The next chained call will throw some kind of reference
error. But what if you don’t want to deal with
a reference error? What if you want the null
value to be the answer? That’s where a safe
navigation operator is useful.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Ruby has a safe navigation operator &lt;code&gt;&amp;amp;.&lt;/code&gt;. This is really useful
in database applications. For example, consider a database model
of a tree, so you might have something like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;tree.trunk.branches[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;].branches[&lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;].twigs[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;].leaves[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But what if your tree doesn’t have that leaf, or that branch, or if
it has no trunk? But also you don’t mind “null” being the answer to
your query. Well that’s where safe navigation is useful. Observe:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;tree&amp;amp;.trunk&amp;amp;.branches&amp;amp;.[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;]&amp;amp;.branches&amp;amp;.[&lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;]&amp;amp;.twigs&amp;amp;.[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;]&amp;amp;.leaves&amp;amp;.[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This would return null if any of the calls in the chain return
null, without having 9 levels of short-circuiting.&lt;/p&gt;
&lt;p&gt;Note: I’m ignoring the law of demeter in this post.&lt;/p&gt;
&lt;p&gt;But python does not have a safe navigation operator. One has been
proposed, but currently it doesn’t exist.&lt;/p&gt;
&lt;p&gt;it is however possible to roll one. Consider an input document like
this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;meta&quot;&gt;&amp;lt;!doctype &lt;span class=&quot;meta-keyword&quot;&gt;html&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;html&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;Something&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;article&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;My article&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;Some text &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;b&lt;/span&gt;&amp;gt;&lt;/span&gt;yelling &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;i&lt;/span&gt;&amp;gt;&lt;/span&gt;curiously&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;i&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;b&lt;/span&gt;&amp;gt;&lt;/span&gt;.&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;article&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;article&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;My article&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;Some text &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;b&lt;/span&gt;&amp;gt;&lt;/span&gt;yelling &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;i&lt;/span&gt;&amp;gt;&lt;/span&gt;curiously&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;i&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;b&lt;/span&gt;&amp;gt;&lt;/span&gt;.&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;article&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;html&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Reading the article with beautiful soup, you can access various html
nodes using a chained dot notaion:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; bs4
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; typing &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; List, Optional


&lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; open(&lt;span class=&quot;string&quot;&gt;&quot;something.html&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;r&quot;&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; f:
    soup = bs4.BeautifulSoup(f.read(), &lt;span class=&quot;string&quot;&gt;&quot;html.parser&quot;&lt;/span&gt;)

print(soup.body.article.div.p.b.i)
&lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt;:
    print(soup.body.article.div.p.c.i)
&lt;span class=&quot;keyword&quot;&gt;except&lt;/span&gt; AttributeError:
    print(&lt;span class=&quot;string&quot;&gt;&quot;that did not work.&quot;&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we can read the contents of the b tag, but not the c tag, since the
latter doesn’t exist. But if we have the function we talked about:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;safe_navigate&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(soup: Optional[bs4.BeautifulSoup], tag_list: List[str])&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; tag_list:
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; safe_navigate(getattr(soup, tag_list[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;], &lt;span class=&quot;literal&quot;&gt;None&lt;/span&gt;), tag_list[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;:])
    &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;:
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; soup

print(safe_navigate(soup, [&lt;span class=&quot;string&quot;&gt;&quot;body&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;article&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;div&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;p&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;b&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;i&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;text&quot;&lt;/span&gt;]))
print(safe_navigate(soup, [&lt;span class=&quot;string&quot;&gt;&quot;body&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;article&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;div&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;p&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;c&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;i&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;text&quot;&lt;/span&gt;]))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now our document query works in both cases, the query with the &lt;code&gt;b&lt;/code&gt; gives
the expected result, and the query with &lt;code&gt;c&lt;/code&gt; returns &lt;code&gt;None&lt;/code&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>A Tale From Microservice Hell</title>
      <link>http://localhost:8080/articles/microservice-hell/</link>
      <pubDate>Tue, 20 Sep 2022 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/microservice-hell/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Ages ago I was working as a contractor on a data engineering
team, working on a knowledge graph platform that was built on
a service architecture.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The platform had dozens of services. Each service had its
code in its own repository. We used containers for
deployment, testing, and so on. This meant we had dozens of
containers to migrate over. Several of the containers
were built on top of other containers, for example there was
a base python container, and a base java container. All of
these containers had images hosted on docker hub.&lt;/p&gt;
&lt;p&gt;A decision was made to change container registries. This meant
we would have to go in to every repository, update the 
container deployment in the CD code, then once that was merged,
update the container pull code and make a separate pull
request in an infra repo to update the container location there. 
And because we had several base containers, that meant there were
several more containers that we would need to deal with, and
we would need to handle those base containers first.&lt;/p&gt;
&lt;p&gt;All told, each repo had two or three PRs needed to update the
container repository, and across the dozens of repositories this
added up to about 40 pull requests. I decided that the 40 subtasks
would overwhelm JIRA so all tracking was done in a big spreadsheet
with rows for each container image and columns for each task state.&lt;/p&gt;
&lt;p&gt;I eventually got through the migration, but it was pretty painful.
The process put a large PR overhead on the team for the several
weeks the job took to complete. The mechanical part of updating
everything was manageable, but the hardest part was tracking down
all the different stake holders to determine which images were in
use, and which were not (and did not need to be migrated). Even with
my best efforts there we still missed a couple images that we had
to go back and migrate later.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Running a shell command for each entry in a PCollection</title>
      <link>http://localhost:8080/articles/beam-subprocess-run/</link>
      <pubDate>Sat, 16 Jul 2022 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/beam-subprocess-run/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I was preparing for something I needed to do at work with beam,
namely running a shell command for something that isn’t possible
to run natively in the beam runtime, and did not find much
documentation for it. It’s relatively straight-forward but I have
not “blogged” in a while so here goes.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Cowsay is a notoriously difficult algorithm, which no one outside
of the original author has been able to optimize to work in less
than &lt;code&gt;O(n^n)&lt;/code&gt; time. As such, the best way to access the mind
expanding functionality is to use the binary:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; apache_beam &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; beam
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; subprocess &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; run

&lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; beam.Pipeline() &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; p:
    cowed = (p | 
        &lt;span class=&quot;string&quot;&gt;&quot;sayings&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Create([
            &lt;span class=&quot;string&quot;&gt;&quot;You're damned if you do, damned if you don't.&quot;&lt;/span&gt;,
            &lt;span class=&quot;string&quot;&gt;&quot;Takes one to know one.&quot;&lt;/span&gt;
        ]) |
        &lt;span class=&quot;string&quot;&gt;&quot;cow it&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Map(
            &lt;span class=&quot;keyword&quot;&gt;lambda&lt;/span&gt; x: run([&lt;span class=&quot;string&quot;&gt;&quot;cowsay&quot;&lt;/span&gt;, x]).stdout
        )
        | &lt;span class=&quot;string&quot;&gt;&quot;output&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Map(&lt;span class=&quot;keyword&quot;&gt;print&lt;/span&gt;)
    )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will give this delightful output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; ________________________________________
/ You&amp;#39;re damned if you do, damned if you \
\ don&amp;#39;t.                                 /
 ----------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
None
 ________________________
&amp;lt; Takes one to know one. &amp;gt;
 ------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
None&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Another application would be to draw upon feature-rich
applications, such as ffmpeg:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; apache_beam &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; beam
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; glob
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; subprocess &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; run

files = glob.glob(&lt;span class=&quot;string&quot;&gt;&quot;*.mov&quot;&lt;/span&gt;)

&lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; beam.Pipeline() &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; p:
    cowed = (p | 
        &lt;span class=&quot;string&quot;&gt;&quot;sayings&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Create(files) |
        &lt;span class=&quot;string&quot;&gt;&quot;cow it&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Map(
            &lt;span class=&quot;keyword&quot;&gt;lambda&lt;/span&gt; x: run([&lt;span class=&quot;string&quot;&gt;&quot;ffmpeg&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;-i&quot;&lt;/span&gt;, x, &lt;span class=&quot;string&quot;&gt;f&quot;&lt;span class=&quot;subst&quot;&gt;{x}&lt;/span&gt;.mp4&quot;&lt;/span&gt;]).stdout
        )
        | &lt;span class=&quot;string&quot;&gt;&quot;output&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Map(&lt;span class=&quot;keyword&quot;&gt;print&lt;/span&gt;)
    )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course you would tweak the ffmpeg command line settings for
whatever you are doing here.&lt;/p&gt;
&lt;p&gt;Anyways, pretty straight-forward but thought it was worth
“blogging” about.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Transferring Musical Likes Between Services</title>
      <link>http://localhost:8080/articles/youtube-music-api/</link>
      <pubDate>Sat, 21 May 2022 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/youtube-music-api/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;After using spotify for many years, I decided to try switching
my music service a few months ago. I was finding that any time
I put on shuffle, spotify would eventually direct me back to
funk and soul music from the seventies. I generally love those
styles of music, but for a service that is supposed to provide
discovery, it wasn’t really working for me.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I compared the various services available in Canada on the
following criteria:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Library&lt;/li&gt;
&lt;li&gt;Sonos Support&lt;/li&gt;
&lt;li&gt;iOS Support&lt;/li&gt;
&lt;li&gt;Mac Support&lt;/li&gt;
&lt;li&gt;CarPlay Support&lt;/li&gt;
&lt;li&gt;Google Home Support&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tidal met most of my needs, so I gave it a try. It’s a good
service, kind of lacking in the polish I got used to with
spotify, but the library was good and I could listen on most
of my devices. I even found it has an app for my roku TV,
which I never really used. I was a bit disappointed with the
CarPlay app, but it was okay. The real sticking point was no
Google Home, so when my trial ended, I signed up for a youtube
music trial.&lt;/p&gt;
&lt;p&gt;One thing I will say for tidal was the discovery was like a
bresh of fresh air coming from spotify. I found a lot of 
really great stuff on there.&lt;/p&gt;
&lt;p&gt;Youtube Music doesn’t have a real mac app, but there is a “web
native” app, which is basically what “chrome apps” are now, from
what I can tell.&lt;/p&gt;
&lt;p&gt;When I left spotify, I exported my thousands of Liked songs with
the hope of importing them to whatever service I settled on.
Unfortunately Tidal’s API is worse than almost any I’ve seen,
and Youtube Music doesn’t even have an api. There is, however, 
an unofficial API for Youtube Music called
&lt;a href=&quot;https://ytmusicapi.readthedocs.io/en/latest/&quot;&gt;ytmusicapi&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It’s a bit of a kludgey library, working by pretending to be a
client in a browser, but overall it worked great. Youtube Music
seems to have some kind of protection in place to prevent abuse
so if you just fire off a tonne of requests using the library,
you will see a lot of timeouts. The usual way to deal with
something like this would be to use a &lt;a href=&quot;https://pypi.org/project/retry/&quot;&gt;retry decorator&lt;/a&gt;
But I decided to roll my own, which I thought was nifty and
worth sharing:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;retry_backoff&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(fn, args, i=&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt;:
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; fn(*args)
    &lt;span class=&quot;keyword&quot;&gt;except&lt;/span&gt; ReadTimeout:
        time.sleep(&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt; * i)
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; retry_backoff(fn, args, i+&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you can call this with something like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;retry_backoff(ytmusic.rate_song, [video_id, &lt;span class=&quot;string&quot;&gt;'LIKE'&lt;/span&gt;])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obviously would be more useful if the Exception type
and sleep multiplier were configurable, but it worked
for me. I got all the Likes imported. I may move off
youtube music, maybe even starting a new spotify account,
but for now I am happy.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Doing some biological modeling</title>
      <link>http://localhost:8080/articles/biological-modeling/</link>
      <pubDate>Mon, 02 May 2022 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/biological-modeling/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;At my new job our focus is to uncover scientific insights
to accelerate and improve scientific research. I’m a data
engineer by trade, but the science side of the business
bleeds in to what I do on a fairly regular basis. Without
the scientific and research background that many of my
peers have, I feel the need to do some self improvement
in those areas. So I was happy to find a series of videos
on youtube titled &lt;a href=&quot;https://www.youtube.com/playlist?list=PLWVKUEZ25V97W2qS7faggHrv5gdhPcgjq&quot;&gt;Computational Biology with Python
(Modeling Gene Networks)&lt;/a&gt; created by &lt;a href=&quot;https://www.youtube.com/channel/UCti8KSLHdoVd7K0VZwUZk_g&quot;&gt;Mike
Saint Antoine&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The video series centers around modeling ordinary
differential equations and stochastic differential
equations using python, specifically for gene
expression, and the central dogma of molecular
biology. This was great for me, because that is a
topic that has come up at work, so it was a great
chance to bridge my history of working with code,
and my ancient (university days) history of working
with math.&lt;/p&gt;
&lt;p&gt;The central dogma of molecular biology is that
information flows from DNA to mRNA to proteins. That
is DNA is transcibed into mRNA and mRNA expresses
proteins. I think.&lt;/p&gt;
&lt;p&gt;DNA ➡ mRNA ➡ protein&lt;/p&gt;
&lt;p&gt;This is modeled roughly as:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;mrna_change = k_m - gamma_m * m
protein_change = k_p * m - gamma_p * p&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the amount of mRNA has a constant upward
change, but it slows down as more mRNA is present. And
the amount of the protein goes up proportional to the
amount of mRNA present and decreases proportional to the
amount of protein present.&lt;/p&gt;
&lt;p&gt;I went ahead and coded the model for myself before the
videos showed a solution. Here’s my code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;m_0 = &lt;span class=&quot;number&quot;&gt;1.0&lt;/span&gt;
p_0 = &lt;span class=&quot;number&quot;&gt;1.0&lt;/span&gt;
gamma_m = &lt;span class=&quot;number&quot;&gt;0.4&lt;/span&gt;
gamma_p = &lt;span class=&quot;number&quot;&gt;0.6&lt;/span&gt;
k_m = &lt;span class=&quot;number&quot;&gt;0.5&lt;/span&gt;
k_p = &lt;span class=&quot;number&quot;&gt;0.9&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;next_m_p&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(m, p)&lt;/span&gt;:&lt;/span&gt;
    m += k_m - gamma_m * m
    p += k_p * m - gamma_p * p
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (m, p)

m = m_0
p = p_0
mps = [(m, p)]
&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(&lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;):
    m, p = next_m_p(m, p)
    mps.append((m, p))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives a plot like this, which the next video
showed how to do with 
&lt;a href=&quot;https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.odeint.html&quot;&gt;odeint&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/biological-modeling/first.png&quot; alt=&quot;dogma&quot;&gt;&lt;/p&gt;
&lt;p&gt;The course goes on to talk about more complex systems
and finishes with a stochastic model of a 3 gene
oscillating system with I think was called a Goodwin
Oscillator.&lt;/p&gt;
&lt;p&gt;Way back in my university days I took a course in fourth
year called Mathematical Modeling, with professor
&lt;a href=&quot;https://www.trentu.ca/news/experts/profile/kenzu-abdella&quot;&gt;Kenzu Abdella&lt;/a&gt;. 
In those days I did almost all of my coding in &lt;a href=&quot;https://www.maplesoft.com/&quot;&gt;Maple&lt;/a&gt;,
which is basically Canada’s mathematica. I haven’t used it
in 15 years or so, but I’d say it’s a functional
language used mostly for symbolic manipulation and
equation solving. I spent many late nights working in
maple trying to do my year-end project for that course.&lt;/p&gt;
&lt;p&gt;I was trying to replicate and hopefully improve the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Lotka%E2%80%93Volterra_equations&quot;&gt;Lotka-Volterra predator prey population model&lt;/a&gt;.
The idea of the model is that predator and prey 
population levels are dependent. An over-population of 
prey leads to higher levels of predators, which leads to
a population crash in prey, then the predator population
crashes. So both are cyclical, but there is a lag between 
the cycles. Honestly I remember that finding a data set
of predator and prey populations was more challenging than
the math or coding aspect. And I’ve found that finding good
data is often the hardest part in a modelling exercise.&lt;/p&gt;
&lt;p&gt;Because of my experience with this model, I decided to try
my hand with knowledge from the video series on the Lotka-
Volterra model with the techniques from the video.&lt;/p&gt;
&lt;p&gt;First, here’s how I would do it before having watched the videos:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# started with the values from wikipedia for these&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;# then fiddled until I got something reasonable.&lt;/span&gt;
alpha = &lt;span class=&quot;number&quot;&gt;0.0075&lt;/span&gt;
beta = &lt;span class=&quot;number&quot;&gt;0.133&lt;/span&gt;
delta = &lt;span class=&quot;number&quot;&gt;0.10&lt;/span&gt;
gamma = &lt;span class=&quot;number&quot;&gt;0.10&lt;/span&gt;
x0 = &lt;span class=&quot;number&quot;&gt;0.5&lt;/span&gt;
y0 = &lt;span class=&quot;number&quot;&gt;0.1&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;next_xy&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(x, y)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (x + alpha * x - beta * x * y, 
        y + delta * x * y - gamma * y)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which gives this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/biological-modeling/lv1.png&quot; alt=&quot;lotka-volterra&quot;&gt;&lt;/p&gt;
&lt;p&gt;I’m not a population biologist or whatever, but
I think this looks pretty nice.&lt;/p&gt;
&lt;p&gt;And here’s how the problem would be solved
using the technique from the videos:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;sim&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(variables, t, params)&lt;/span&gt;:&lt;/span&gt;
    x, y = variables
    alpha, beta, delta, gamma = params
    dxdt = alpha * x - beta * x * y
    dydt = delta * x * y - gamma * y

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;([dxdt, dydt])
&lt;span class=&quot;comment&quot;&gt;# I think the wikipedia values worked here.&lt;/span&gt;
alpha = &lt;span class=&quot;number&quot;&gt;0.66&lt;/span&gt;
beta = &lt;span class=&quot;number&quot;&gt;1.33&lt;/span&gt;
delta = &lt;span class=&quot;number&quot;&gt;1.0&lt;/span&gt;
gamma = &lt;span class=&quot;number&quot;&gt;1.0&lt;/span&gt;
params = (alpha, beta, delta, gamma)
t = np.linspace(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;50&lt;/span&gt;, num=&lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;)
y0 = [&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]

y = odeint(sim, y0, t, args=(params,))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which gives this plot:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/biological-modeling/lv2.png&quot; alt=&quot;predator prey model&quot;&gt;&lt;/p&gt;
&lt;p&gt;I tried to do the stochastic model but I couldn’t get
it working. I noticed that Mike Saint Antoine has a
couple videos about Lotka-Volterra, so I’ll probably
check those out at a later date and see what I was doing
wrong.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Diabolical Answers In Wordle</title>
      <link>http://localhost:8080/articles/worst-answers-wordle/</link>
      <pubDate>Mon, 11 Apr 2022 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/worst-answers-wordle/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I’ve blogged several times about wordle before. It’s a great
game for someone like me who loves words. I don’t think I’m a
great wordle player, but I love thinking about the intricacies
of the game. One bugaboo in wordle, which I’ll call “diabolical
answers” is when you reach a point where you have four letters
correct and there are many possible answers. The worst of these
would have more than six possible words, meaning you aren’t
guaranteed a win even though you’re almost done.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I’ll start with an example. The word “soare”, which I blogged
about earlier as being a great first guess, is also a diabolical
answer, and this happened to me the other day. Assuming all but
the second letter are correct, other possible answers include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;scare&lt;/li&gt;
&lt;li&gt;share&lt;/li&gt;
&lt;li&gt;slare&lt;/li&gt;
&lt;li&gt;snare&lt;/li&gt;
&lt;li&gt;spare&lt;/li&gt;
&lt;li&gt;stare&lt;/li&gt;
&lt;li&gt;sware&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Admittedly some of these are rare and don’t occur in wordle’s
dictionary.&lt;/p&gt;
&lt;p&gt;I am still working on learning more &lt;a href=&quot;https://beam.apache.org/&quot;&gt;Apache Beam&lt;/a&gt;, so I thought I would try to find these diabolical words using that tool. Here is the algorithm:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; apache_beam &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; beam
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; wordfreq &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; word_frequency

&lt;span class=&quot;comment&quot;&gt;# should probably use the actual wordle dictionary.&lt;/span&gt;
dictionary = &lt;span class=&quot;string&quot;&gt;&quot;/usr/share/dict/words&quot;&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;is_lower&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(x)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; x.lower() == x

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;is_fives&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(text)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; len(text) == &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;to_missings&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(word)&lt;/span&gt;:&lt;/span&gt;
    retval = []
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(len(word)):
        s = word + &lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;
        s = s[:i] + &lt;span class=&quot;string&quot;&gt;&quot;_&quot;&lt;/span&gt; + s[i + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;:]
        retval.append((s, word))
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; retval

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;remove_rares&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(x)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; word_frequency(x, &lt;span class=&quot;string&quot;&gt;'en'&lt;/span&gt;) &amp;gt; &lt;span class=&quot;number&quot;&gt;1.0e-06&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; beam.Pipeline() &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; p:
    fives = ( p |
        beam.io.ReadFromText(dictionary) |
        &lt;span class=&quot;string&quot;&gt;&quot;is lower&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Filter(is_lower) |
        &lt;span class=&quot;string&quot;&gt;&quot;is fives&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Filter(is_fives) |
        &lt;span class=&quot;string&quot;&gt;&quot;is common&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Filter(remove_rares)
    )

    various_lists = (fives |
        &lt;span class=&quot;string&quot;&gt;&quot;create keyed missings&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.FlatMap(to_missings)
        | &lt;span class=&quot;string&quot;&gt;&quot;unique those&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Distinct()
    )

    groups = (various_lists |
        &lt;span class=&quot;string&quot;&gt;&quot;group by missing chars&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.GroupByKey()
    )

    filtered_groups = (groups |
        &lt;span class=&quot;string&quot;&gt;&quot;only baddies&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Filter(&lt;span class=&quot;keyword&quot;&gt;lambda&lt;/span&gt; x: len(x[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;])&amp;gt; &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;)
    )

    output = (filtered_groups |
        &lt;span class=&quot;string&quot;&gt;&quot;hopefully found something&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Map(&lt;span class=&quot;keyword&quot;&gt;print&lt;/span&gt;)
    )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the use of the &lt;code&gt;wordfreq&lt;/code&gt; library, one of my faves, to
remove rare words, based on the heuristic threshold I decided
on of &lt;code&gt;1.0e-06&lt;/code&gt;. This gives a really pleassing (to me at least)
list of diabolical answers 😈:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;_arry: barry, carry, harry, larry, marry, parry&lt;/li&gt;
&lt;li&gt;_atch: batch, catch, hatch, latch, match, patch, watch&lt;/li&gt;
&lt;li&gt;_erry: berry, derry, ferry, jerry, kerry, merry, perry, terry&lt;/li&gt;
&lt;li&gt;_illy: billy, filly, hilly, milly, silly, willy&lt;/li&gt;
&lt;li&gt;_itch: bitch, ditch, fitch, hitch, mitch, pitch, witch&lt;/li&gt;
&lt;li&gt;_ound: bound, found, hound, mound, pound, round, sound, wound&lt;/li&gt;
&lt;li&gt;_ater: cater, eater, hater, later, mater, water&lt;/li&gt;
&lt;li&gt;_over: cover, dover, hover, lover, mover, rover&lt;/li&gt;
&lt;li&gt;_olly: dolly, folly, holly, jolly, molly, polly&lt;/li&gt;
&lt;li&gt;_ight: eight, fight, light, might, night, right, sight, tight, wight&lt;/li&gt;
&lt;li&gt;gra_e: grace, grade, grape, grate, grave, graze&lt;/li&gt;
&lt;li&gt;sha_e: shade, shake, shale, shame, shane, shape, share, shave&lt;/li&gt;
&lt;li&gt;sta_e: stage, stake, stale, stare, state, stave&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of these have 6 or more entries, which would make them very frustrating.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Messing Around In Beam, π Day, And More Wordle</title>
      <link>http://localhost:8080/articles/messing-around-beam/</link>
      <pubDate>Sun, 13 Mar 2022 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/messing-around-beam/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;https://beam.apache.org/&quot;&gt;Apache Beam&lt;/a&gt; is a distributed programming
framework, mostly designed as a counterpart to the DataFlow service in
Google Cloud Platform. In the past I’ve done a fair bit of work on
pipelines in Spark and with a service architecture, but I’ll be needing
Beam for my new job, so Ive been playing around a bit with that.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I’ve may have written a bit about it before, but I think of calculating π
using the Monte Carlo Method to be kind of like the “hello world” of data
pipelines. A quick review of the algorithm:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Select a large number of random &lt;code&gt;x, y ∊ [0, 1]²&lt;/code&gt; from the uniform
  distibution.&lt;/li&gt;
&lt;li&gt;Take the sum of squares of each couple.&lt;/li&gt;
&lt;li&gt;The proportion of sums of squares that are less than one will (very slowly
  converge to π/4).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This works because finding random points withing this quarter arc is analagous
to finding the area of the unit circle. Here’s the code in beam:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; apache_beam &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; beam
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; numpy &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; np

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;in_circle&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(pair)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (pair[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]**&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt; + pair[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]**&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;) &amp;lt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;:
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;:
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; beam.Pipeline() &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; pipeline:
    n_samp = &lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;_000
    X = np.random.uniform(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt; * n_samp).reshape(n_samp, &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;)

    x = pipeline | &lt;span class=&quot;string&quot;&gt;&quot;create xs&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Create(X)

    number = x | &lt;span class=&quot;string&quot;&gt;&quot;calculate it&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Map(in_circle) \
        | &lt;span class=&quot;string&quot;&gt;&quot;sum up&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.CombineGlobally(sum)

    number | &lt;span class=&quot;string&quot;&gt;&quot;writing pi value&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.io.WriteToText(&lt;span class=&quot;string&quot;&gt;&quot;number.txt&quot;&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gave me a value of pi of &lt;code&gt;π is 3.14136&lt;/code&gt;, which any piphile
would tell you is way off. The Monte Carlo Method is great for a
close enough answer, but it’s a terrible way to calculate digits
of π.&lt;/p&gt;
&lt;p&gt;I’ve also written recently about wordle. I’ve been playing every
day for months, and I often get the urge to write a program to cheat
for me. I have thus far resisted the urge to cheat, (unless you count
writing a program to give a good first guess cheating), but I have
gone back several times to re-think word choices.&lt;/p&gt;
&lt;p&gt;The other day I had a clue of &lt;code&gt;_o_us&lt;/code&gt; and I discounted several letters
to get there. Off the top of my head I thought of “bolus”
and “focus” as options. It ended up being “bonus,” but it took me a few
minutes to remember this common word.&lt;/p&gt;
&lt;p&gt;Here’s a beam that calculates some of the words that may match in this
scenario.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; apache_beam &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; beam

&lt;span class=&quot;comment&quot;&gt;# my favorite unix file&lt;/span&gt;
dictionary = &lt;span class=&quot;string&quot;&gt;&quot;/usr/share/dict/words&quot;&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;to_lower&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(x)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; x.lower()

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;is_fives&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(text)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; len(text) == &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;match_greens&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(pattern)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;lambda&lt;/span&gt; x: all([x[idx] == letter &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; idx, letter &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; pattern])

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;non_matches&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(excludes)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;lambda&lt;/span&gt; x: all([ex &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; x &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ex &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; excludes])

&lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; open(&lt;span class=&quot;string&quot;&gt;&quot;beam-output.txt&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;w&quot;&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; f:
    &lt;span class=&quot;keyword&quot;&gt;with&lt;/span&gt; beam.Pipeline() &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; p:
        words = ( p |
            &lt;span class=&quot;string&quot;&gt;&quot;read in words&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.io.ReadFromText(dictionary) |
            &lt;span class=&quot;string&quot;&gt;&quot;to lower&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Map(to_lower)
        )

        fives = (words |
            &lt;span class=&quot;string&quot;&gt;&quot;filter to five letter words&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Filter(is_fives)
        )

        &lt;span class=&quot;comment&quot;&gt;# sample of letters I had tried and discounted.&lt;/span&gt;
        excludes = [&lt;span class=&quot;string&quot;&gt;'t'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'r'&lt;/span&gt;]

        without_exclusions = (fives |
            &lt;span class=&quot;string&quot;&gt;&quot;remove exclusions&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Filter(non_matches(excludes))
        )

        &lt;span class=&quot;comment&quot;&gt;# sample &quot;green letter&quot; pattern _o_us&lt;/span&gt;
        pattern = [(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'o'&lt;/span&gt;), (&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'u'&lt;/span&gt;), (&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'s'&lt;/span&gt;)]

        matches = (without_exclusions |
            &lt;span class=&quot;string&quot;&gt;&quot;get green matches&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Filter(match_greens(pattern))
        )

        (matches 
            |&lt;span class=&quot;string&quot;&gt;&quot;do output&quot;&lt;/span&gt; &amp;gt;&amp;gt; beam.Map(&lt;span class=&quot;keyword&quot;&gt;print&lt;/span&gt;)
        )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And I get these output words with my dictionary:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bogus
bolus
bonus
cobus
comus
conus
copus
focus
fogus
hocus
kobus
locus
momus
mopus
nodus&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As I mentioned before, wordle does use common words, so it would make
sense to either filter or sort these based on word frequency. But as a
quick learning exercise for beam it was decent. One aspect I am really
enjoying about beam so far is that it basically forces you to document
every step of your pipeline, because you can’t use the same operator
twice without doing the &lt;code&gt;&amp;quot;explanation&amp;quot; &amp;gt;&amp;gt; step&lt;/code&gt; thing, which is really
nice.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>BrainF Interpreter In Scratch</title>
      <link>http://localhost:8080/articles/brain-f-interpreter-scratch/</link>
      <pubDate>Wed, 09 Mar 2022 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/brain-f-interpreter-scratch/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Since late 2012, I’ve been a parent. My oldest is an absolutely avid
coder. He loves the scratch programming language, and has made an
incredibly bevy of spectacular games, originally by following
&lt;a href=&quot;https://www.youtube.com/channel/UCawsI_mlmPA7Cfld-qZhBQA&quot;&gt;griffpatch&lt;/a&gt;
tutorials, and then moving on to his own stuff.&lt;/p&gt;
&lt;p&gt;As a way of sharing time with him, I do some scratch of my own. It’s a
fun way of spending time together and encouraging his interest. Of course,
as a professional software developer I like to explore what I can
accomplish in a given environment. So I thought I would implement the
esoteric langage &lt;a href=&quot;https://en.wikipedia.org/wiki/Brainfuck&quot;&gt;BrainFrig&lt;/a&gt;
in &lt;a href=&quot;https://scratch.mit.edu/&quot;&gt;scratch&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;BrainEff is a simple language, with only eight commands. From wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&lt;/code&gt;     Increment the data pointer (to point to the next cell to the right).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;&lt;/code&gt;     Decrement the data pointer (to point to the next cell to the left).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;+&lt;/code&gt;     Increment (increase by one) the byte at the data pointer.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-&lt;/code&gt;     Decrement (decrease by one) the byte at the data pointer.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.&lt;/code&gt;     Output the byte at the data pointer.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;,&lt;/code&gt;     Accept one byte of input, storing its value in the byte at the data pointer.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[&lt;/code&gt;     If the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to the command after the matching ] command.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;]&lt;/code&gt;     If the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the command after the matching [ command.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;BrainFart languages operate similar to a turing machine, with the idea of a single
pointer that moves along a tape, making modifications and performing some basic
conditional logic. Translating this into scratch means setting up a &lt;code&gt;List&lt;/code&gt; variable,
and a variable for the pointer.&lt;/p&gt;
&lt;p&gt;Then initialize the memory:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/brain-f-interpreter-scratch/initialize-mem.png&quot; alt=&quot;initialize memory values&quot;&gt;&lt;/p&gt;
&lt;p&gt;We then need a program to operate on. I thought it would be cute to have
Scratch Cat ask you for your program:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/brain-f-interpreter-scratch/program-ask.png&quot; alt=&quot;scratch cat asking for a program&quot;&gt;&lt;/p&gt;
&lt;p&gt;This is then read into the program variable:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/brain-f-interpreter-scratch/new-program.png&quot; alt=&quot;new program has been entered&quot;&gt;&lt;/p&gt;
&lt;p&gt;Each unit of scratch code is called a block (they look a bit like lego
blocks, and they stick together similarly). Each block is a blocking operation,
that is, no further connected blocks are run until that block is finished. The
ask block is no different in this regard. Scratch has two means of code separation,
by message broadcasting, and by making custom blocks. A custom block is analagous
to making a function.&lt;/p&gt;
&lt;p&gt;After a program is entered, the new program message is broadcast, this will
cause this code to run:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/brain-f-interpreter-scratch/run-program.png&quot; alt=&quot;run a program&quot;&gt;&lt;/p&gt;
&lt;p&gt;This code handle the “parsing and lexing” part of the interpreter, basically.
Next is just the code that runs the functional parts of the input program,
alters the memory, and creates output. Here are the parts for moving the pointer
around on the tape:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/brain-f-interpreter-scratch/move-pointer.png&quot; alt=&quot;code for moving the pointer around&quot;&gt;&lt;/p&gt;
&lt;p&gt;Here’s the code for incrementing and decrementing the memory at the pointer
location:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/brain-f-interpreter-scratch/inc-dec.png&quot; alt=&quot;incrementing and so on&quot;&gt;&lt;/p&gt;
&lt;p&gt;Here’s the IO code:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/brain-f-interpreter-scratch/io.png&quot; alt=&quot;IO&quot;&gt;&lt;/p&gt;
&lt;p&gt;And finally, the tricky bit: the looping code.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/brain-f-interpreter-scratch/loops.png&quot; alt=&quot;code for loops.&quot;&gt;&lt;/p&gt;
&lt;p&gt;This is the second time I’ve written a BrainFrag interpreter, and it’s been fun
both times. BrainFrick is a funny language, as it’s probably a lot more common to
write an interpreter for it than it is to write a program for it to run.
I got a good chortle out of my coding companion when I showed him
I had implemented another programming language in scratch, even if I had to
bowdlerize the name of the language when I was talking about it.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Automatic Word of the Day</title>
      <link>http://localhost:8080/articles/wotd/</link>
      <pubDate>Wed, 02 Mar 2022 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/wotd/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Since 2007 I’ve been keeping up my own personal word of the day
blog. I started it back in the heyday of google reader. In those
days I was subscribed to several word of the day blogs and
wanted to do one of my own. I’ve gone through phases of posting more
and less. Some years I posted every day, and toward the late teens
I had single digits of posts for several years running.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;It’s fun. My favorite words to add are ones that I come across while
reading something, and I either really like the word or have to look
it up. Words that arise organically have a personal touch that is
appropriate for blogging.&lt;/p&gt;
&lt;p&gt;But in the years where I posted every day, I mixed and matched between
organic words and wikipedia crawling. I forget the exact criteria, but
I had a userscript that I would run in a browser that would look for
interesting words, those being wikipedia articles that matched several
criteria:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Single word title, with optional parentheses.&lt;/li&gt;
&lt;li&gt;No proper nouns&lt;/li&gt;
&lt;li&gt;Probably some kind of length limit.&lt;/li&gt;
&lt;li&gt;There were probably other criteria.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It would be interesting to share what I was doing with javascript in 
those days, but alas, whatever that user script did, it’s lost to the
sands of time. Being totally honest I think it was on a work computer,
and this was back in the days when a work computer was a big box that
sat in an office, not a laptop in your own home.&lt;/p&gt;
&lt;p&gt;My enthusiasm for the project waned over the years, but never left. So
last year I was looking to revive the blog. I thought an interesting
way to automate it would be picking random words from the dictionary
with in a given word frequency range.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; wordfreq &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; word_frequency
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; PyDictionary &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; PyDictionary
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; english_words &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; english_words_set
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; random &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; choice
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; wiktionaryparser &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; WiktionaryParser
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; wikipedia
&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; datetime &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; datetime

dictionary=PyDictionary()
english_words = list(english_words_set)
parser = WiktionaryParser()

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;find_interesting_word&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(max_freq=&lt;span class=&quot;number&quot;&gt;5e-07&lt;/span&gt;, min_freq=&lt;span class=&quot;number&quot;&gt;7e-10&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;
    freq = &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt; * max_freq
    &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; freq &amp;lt; min_freq &lt;span class=&quot;keyword&quot;&gt;or&lt;/span&gt; freq &amp;gt; max_freq:
        word = choice(english_words)
        freq = word_frequency(word, &lt;span class=&quot;string&quot;&gt;'en'&lt;/span&gt;)
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; word, freq&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here you see that an interesting word is one whose frequency
lies in the range &lt;code&gt;7e-10&lt;/code&gt; to &lt;code&gt;5e-07&lt;/code&gt;. I found these bounds
by trial-and-error, and even so most of the output words
aren’t great, so pick a bunch of them:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;find_interesting_words&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(num=&lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; [find_interesting_word() &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(num)]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[(&amp;#39;incubate&amp;#39;, 2.88e-07),
 (&amp;#39;rattail&amp;#39;, 3.24e-08),
 (&amp;#39;recondite&amp;#39;, 5.37e-08),
 (&amp;#39;okra&amp;#39;, 4.27e-07),
 (&amp;#39;headdress&amp;#39;, 4.57e-07),
 (&amp;#39;Grosset&amp;#39;, 8.13e-08),
 (&amp;#39;hyperbola&amp;#39;, 1.07e-07)]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Aside from the proper noun “Grosset,” these are basically all
suitable for “words of the day.” But a word of the day isn’t
just a word, you also need a definition, and I liked to include
a picture. I found a function that grabs images for a given
query from wikipedia, and use &lt;code&gt;PyDictionary&lt;/code&gt; and &lt;code&gt;WiktionaryParser&lt;/code&gt;
to give definitions:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(x)&lt;/span&gt;:&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;f&quot;&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;&lt;span class=&quot;subst&quot;&gt;{x[&lt;span class=&quot;string&quot;&gt;'partOfSpeech'&lt;/span&gt;]}&lt;/span&gt;&amp;lt;/i&amp;gt;: &lt;span class=&quot;subst&quot;&gt;{&lt;span class=&quot;string&quot;&gt;' '&lt;/span&gt;.join(x[&lt;span class=&quot;string&quot;&gt;'text'&lt;/span&gt;])}&lt;/span&gt;&amp;lt;/li&amp;gt;&quot;&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;html_of&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(word)&lt;/span&gt;:&lt;/span&gt;
    out_code = &lt;span class=&quot;string&quot;&gt;f'&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;'&lt;/span&gt; \
      &lt;span class=&quot;string&quot;&gt;'&amp;lt;a href=&quot;https://en.wiktionary.org/wiki/{word}&quot;&amp;gt;{word}&amp;lt;/a&amp;gt;'&lt;/span&gt; \
      &lt;span class=&quot;string&quot;&gt;'&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;'&lt;/span&gt;
    meaning = dictionary.meaning(word)
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; meaning:
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (typ, defs) &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; meaning.items():
            out_code += &lt;span class=&quot;string&quot;&gt;f'&amp;lt;p&amp;gt;&amp;lt;i&amp;gt;&lt;span class=&quot;subst&quot;&gt;{typ}&lt;/span&gt;&amp;lt;/i&amp;gt;'&lt;/span&gt;
            lis = &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;.join([&lt;span class=&quot;string&quot;&gt;'&amp;lt;li&amp;gt;'&lt;/span&gt; + x + &lt;span class=&quot;string&quot;&gt;'&amp;lt;/li&amp;gt;'&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; x &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; defs])
            out_code += &lt;span class=&quot;string&quot;&gt;'&amp;lt;ul&amp;gt;'&lt;/span&gt; + lis + &lt;span class=&quot;string&quot;&gt;'&amp;lt;/ul&amp;gt;'&lt;/span&gt;
            out_code += &lt;span class=&quot;string&quot;&gt;'&amp;lt;/p&amp;gt;'&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;:
        meaning = parser.fetch(word)
        out_code += &lt;span class=&quot;string&quot;&gt;'&amp;lt;ul&amp;gt;'&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; defs &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; meaning:
            lis = [li(x) &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; x &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; defs[&lt;span class=&quot;string&quot;&gt;'definitions'&lt;/span&gt;]]
            out_code += &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;.join(lis) + &lt;span class=&quot;string&quot;&gt;'&amp;lt;/ul&amp;gt;'&lt;/span&gt;
        out_code += &lt;span class=&quot;string&quot;&gt;'&amp;lt;/ul&amp;gt;'&lt;/span&gt;
    wikiimage = get_wiki_image(word)
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; wikiimage:
        out_code += &lt;span class=&quot;string&quot;&gt;f'&amp;lt;p&amp;gt;&amp;lt;img width=720 rel=&quot;&lt;span class=&quot;subst&quot;&gt;{word}&lt;/span&gt;&quot; src=&quot;&lt;span class=&quot;subst&quot;&gt;{wikiimage}&lt;/span&gt;&quot; /&amp;gt;&amp;lt;/p&amp;gt;'&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; out_code&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I see a few issues here, but this was meant as a proof-of-concept, so that’s
fine. After running a few tests, I found I was getting results like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;europium&lt;/p&gt;
&lt;p&gt;Noun
   a bivalent and trivalent metallic element of the rare earth group&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is fine, but I feel it’s a bit soul-less. Had this worked out I would
have liked to add blogger API access, including scheduling and tagging, but
I wasn’t happy enough with the results. After reflecting on
what I wanted the blog to be, I decided to just make a better effort
of manually posting things, and I’ve been doing a much better job
since last year.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>What is Canada's Largest Transitless Municipality?</title>
      <link>http://localhost:8080/articles/canadas-biggest-transitless-muncipality/</link>
      <pubDate>Mon, 21 Feb 2022 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/canadas-biggest-transitless-muncipality/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Happy 2s Day.&lt;/p&gt;
&lt;p&gt;I was chatting with my brother the other day, and he opined that I may live in
Canada’s largest municipality that doesn’t have a municipal bus transit system. Of
course I was interested to find out which is the biggest Canadian city without
buses, so &lt;em&gt;here we go&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I was very pleased to find that pandas will read an html page and output a list
of dataframes that it was able to parse from tables. Pair this with wikipedia
keeping a list of Canadian municipalities with public transport and we have a
good start:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; pandas &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; pd
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; requests

transit_url = &lt;span class=&quot;string&quot;&gt;&quot;https://en.wikipedia.org/wiki/Public_transport_in_Canada&quot;&lt;/span&gt;
r = requests.get(transit_url)
df_list = pd.read_html(r.text)
transit_municipalities = df_list[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Municipalstatus[3][6]&lt;/th&gt;
      &lt;th&gt;County[15]&lt;/th&gt;
      &lt;th&gt;Incorporationyear[16]&lt;/th&gt;
      &lt;th colspan=&quot;5&quot; halign=&quot;left&quot;&gt;2021 Census of Population[15]&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Municipalstatus[3][6]&lt;/th&gt;
      &lt;th&gt;County[15]&lt;/th&gt;
      &lt;th&gt;Incorporationyear[16]&lt;/th&gt;
      &lt;th&gt;Population(2021)&lt;/th&gt;
      &lt;th&gt;Population(2016)&lt;/th&gt;
      &lt;th&gt;Change&lt;/th&gt;
      &lt;th&gt;Land area(km²)&lt;/th&gt;
      &lt;th&gt;Populationdensity&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;0&lt;/th&gt;
      &lt;td&gt;Charlottetown&lt;/td&gt;
      &lt;td&gt;City&lt;/td&gt;
      &lt;td&gt;Queens&lt;/td&gt;
      &lt;td&gt;1855&lt;/td&gt;
      &lt;td&gt;38809&lt;/td&gt;
      &lt;td&gt;36094&lt;/td&gt;
      &lt;td&gt;+7.5%&lt;/td&gt;
      &lt;td&gt;44.27&lt;/td&gt;
      &lt;td&gt;2.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1&lt;/th&gt;
      &lt;td&gt;Summerside&lt;/td&gt;
      &lt;td&gt;City&lt;/td&gt;
      &lt;td&gt;Prince&lt;/td&gt;
      &lt;td&gt;1877[c]&lt;/td&gt;
      &lt;td&gt;16001&lt;/td&gt;
      &lt;td&gt;14839&lt;/td&gt;
      &lt;td&gt;+7.8%&lt;/td&gt;
      &lt;td&gt;28.21&lt;/td&gt;
      &lt;td&gt;2.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2&lt;/th&gt;
      &lt;td&gt;Alberton&lt;/td&gt;
      &lt;td&gt;Town&lt;/td&gt;
      &lt;td&gt;Prince&lt;/td&gt;
      &lt;td&gt;1913&lt;/td&gt;
      &lt;td&gt;1301&lt;/td&gt;
      &lt;td&gt;1145&lt;/td&gt;
      &lt;td&gt;+13.6%&lt;/td&gt;
      &lt;td&gt;4.70&lt;/td&gt;
      &lt;td&gt;2.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;3&lt;/th&gt;
      &lt;td&gt;Borden-Carleton&lt;/td&gt;
      &lt;td&gt;Town&lt;/td&gt;
      &lt;td&gt;Prince&lt;/td&gt;
      &lt;td&gt;1995[d]&lt;/td&gt;
      &lt;td&gt;788&lt;/td&gt;
      &lt;td&gt;724&lt;/td&gt;
      &lt;td&gt;+8.8%&lt;/td&gt;
      &lt;td&gt;12.94&lt;/td&gt;
      &lt;td&gt;2.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;4&lt;/th&gt;
      &lt;td&gt;Cornwall&lt;/td&gt;
      &lt;td&gt;Town&lt;/td&gt;
      &lt;td&gt;Queens&lt;/td&gt;
      &lt;td&gt;1995&lt;/td&gt;
      &lt;td&gt;6574&lt;/td&gt;
      &lt;td&gt;5348&lt;/td&gt;
      &lt;td&gt;+22.9%&lt;/td&gt;
      &lt;td&gt;28.21&lt;/td&gt;
      &lt;td&gt;2.0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;


&lt;p&gt;Next, use the same technique to find a list of municipalities in each province.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;
provinces = [&lt;span class=&quot;string&quot;&gt;'British Columbia'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'Alberta'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'Saskatchewan'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'Manitoba'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'Ontario'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'Quebec'&lt;/span&gt;,
            &lt;span class=&quot;string&quot;&gt;'New Brunswick'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'Newfoundland and Labrador'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'Nova Scotia'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'Prince Edward Island'&lt;/span&gt;]

p_dfs = {}
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;p_url&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(p)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;f&quot;https://en.wikipedia.org/wiki/List_of_municipalities_in_&lt;span class=&quot;subst&quot;&gt;{p.replace(&lt;span class=&quot;string&quot;&gt;' '&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'_'&lt;/span&gt;)}&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; province &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; provinces:
    print(&lt;span class=&quot;string&quot;&gt;f&quot;getting municipalities for &lt;span class=&quot;subst&quot;&gt;{province}&lt;/span&gt;&quot;&lt;/span&gt;)
    r = requests.get(p_url(province))
    df_list = pd.read_html(r.text)

    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; province == &lt;span class=&quot;string&quot;&gt;'Ontario'&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;or&lt;/span&gt; province == &lt;span class=&quot;string&quot;&gt;'Manitoba'&lt;/span&gt;: &lt;span class=&quot;comment&quot;&gt;# different html for these two.&lt;/span&gt;
        p_dfs[province] = df_list[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]
    &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;:
        p_dfs[province] = df_list[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]
    print(&lt;span class=&quot;string&quot;&gt;f&quot;&lt;span class=&quot;subst&quot;&gt;{province}&lt;/span&gt; has &lt;span class=&quot;subst&quot;&gt;{len(p_dfs[province])}&lt;/span&gt; municipalities&quot;&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clean that data up a bit, and work around the annoyingness of &lt;code&gt;MultiIndex&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;canada_dfs = []

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;find_series_by_column&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(df, look_for)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; x &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; df.columns:
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; isinstance(x, tuple):
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; look_for &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; x[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]:
                pop_column = x[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]
                &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; df[x[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]][x[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]]
                &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;


&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; province, df &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; p_dfs.items():
    prov_series = pd.Series([province &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; x &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(len(df.index))])
    pop_series = find_series_by_column(df, &lt;span class=&quot;string&quot;&gt;'Population'&lt;/span&gt;)
    name_series = find_series_by_column(df, &lt;span class=&quot;string&quot;&gt;'Name'&lt;/span&gt;)
    canada_dfs.append(pd.DataFrame({&lt;span class=&quot;string&quot;&gt;&quot;Province&quot;&lt;/span&gt;: prov_series, &lt;span class=&quot;string&quot;&gt;&quot;Name&quot;&lt;/span&gt;: name_series, &lt;span class=&quot;string&quot;&gt;&quot;Population&quot;&lt;/span&gt;: pop_series}))
canada_df = pd.concat(canada_dfs)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gives data like this:&lt;/p&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;Province&lt;/th&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Population&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;378&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Timmins&lt;/td&gt;
      &lt;td&gt;41788&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;890&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Saint-Thomas&lt;/td&gt;
      &lt;td&gt;3249&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;145&lt;/th&gt;
      &lt;td&gt;Saskatchewan&lt;/td&gt;
      &lt;td&gt;Tisdale&lt;/td&gt;
      &lt;td&gt;2962.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;827&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Saint-Patrice-de-Sherrington&lt;/td&gt;
      &lt;td&gt;1960&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;45&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Terrace&lt;/td&gt;
      &lt;td&gt;12017&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;41&lt;/th&gt;
      &lt;td&gt;Manitoba&lt;/td&gt;
      &lt;td&gt;Louise&lt;/td&gt;
      &lt;td&gt;2025&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;806&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Saint-Modeste&lt;/td&gt;
      &lt;td&gt;1162&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;88&lt;/th&gt;
      &lt;td&gt;Saskatchewan&lt;/td&gt;
      &lt;td&gt;Langenburg&lt;/td&gt;
      &lt;td&gt;1228.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;395&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Mont-Tremblant&lt;/td&gt;
      &lt;td&gt;9646&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;52&lt;/th&gt;
      &lt;td&gt;Saskatchewan&lt;/td&gt;
      &lt;td&gt;Davidson&lt;/td&gt;
      &lt;td&gt;1044.0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Do an anti-join to find the muncipalities without transit:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;with_transit_df = canada_df.merge(trans_df, on=[&lt;span class=&quot;string&quot;&gt;'Name'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'Province'&lt;/span&gt;], indicator=&lt;span class=&quot;literal&quot;&gt;True&lt;/span&gt;, how=&lt;span class=&quot;string&quot;&gt;'left'&lt;/span&gt;)
without_transit_df = with_transit_df.loc[with_transit_df._merge == &lt;span class=&quot;string&quot;&gt;'left_only'&lt;/span&gt;, :].drop(columns=&lt;span class=&quot;string&quot;&gt;'_merge'&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A little data cleanup:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; re
without_transit_df[&lt;span class=&quot;string&quot;&gt;'Population2'&lt;/span&gt;] = without_transit_df[&lt;span class=&quot;string&quot;&gt;'Population'&lt;/span&gt;].fillna(&lt;span class=&quot;string&quot;&gt;&quot;0&quot;&lt;/span&gt;).map(&lt;span class=&quot;keyword&quot;&gt;lambda&lt;/span&gt; x:
        str(re.sub(&lt;span class=&quot;string&quot;&gt;&quot;\[\d+\]&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;, str(x)))
     )
without_transit_df[&lt;span class=&quot;string&quot;&gt;'Population2'&lt;/span&gt;] = without_transit_df[&lt;span class=&quot;string&quot;&gt;'Population2'&lt;/span&gt;].map(
        &lt;span class=&quot;keyword&quot;&gt;lambda&lt;/span&gt; x: str(x).replace(&lt;span class=&quot;string&quot;&gt;&quot;.0&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;).replace(&lt;span class=&quot;string&quot;&gt;&quot;nan&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;0&quot;&lt;/span&gt;).replace(&lt;span class=&quot;string&quot;&gt;&quot;,&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;)
    ).replace(&lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;).astype(&lt;span class=&quot;string&quot;&gt;'int32'&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And sort:&lt;/p&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;Province&lt;/th&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Population2&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;47&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Vancouver&lt;/td&gt;
      &lt;td&gt;662248&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;44&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Surrey&lt;/td&gt;
      &lt;td&gt;568322&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1186&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Markham&lt;/td&gt;
      &lt;td&gt;328966&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1356&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Vaughan&lt;/td&gt;
      &lt;td&gt;306233&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Burnaby&lt;/td&gt;
      &lt;td&gt;249125&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1156&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Kitchener&lt;/td&gt;
      &lt;td&gt;233222&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;41&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Richmond&lt;/td&gt;
      &lt;td&gt;209937&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1286&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Richmond Hill&lt;/td&gt;
      &lt;td&gt;195022&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1251&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Oshawa&lt;/td&gt;
      &lt;td&gt;159458&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;7&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Coquitlam&lt;/td&gt;
      &lt;td&gt;148625&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;19&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Kelowna&lt;/td&gt;
      &lt;td&gt;144576&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;69&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Langley&lt;/td&gt;
      &lt;td&gt;132603&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1025&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Cambridge&lt;/td&gt;
      &lt;td&gt;129920&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1371&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Whitby&lt;/td&gt;
      &lt;td&gt;128377&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;972&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Ajax&lt;/td&gt;
      &lt;td&gt;119677&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;85&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Saanich&lt;/td&gt;
      &lt;td&gt;117735&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2437&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Terrebonne&lt;/td&gt;
      &lt;td&gt;111575&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2596&lt;/th&gt;
      &lt;td&gt;Newfoundland and Labrador&lt;/td&gt;
      &lt;td&gt;St. John's&lt;/td&gt;
      &lt;td&gt;108860&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;11&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Delta&lt;/td&gt;
      &lt;td&gt;108455&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1360&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Waterloo&lt;/td&gt;
      &lt;td&gt;104986&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2872&lt;/th&gt;
      &lt;td&gt;Nova Scotia&lt;/td&gt;
      &lt;td&gt;Cape Breton&lt;/td&gt;
      &lt;td&gt;94285&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1047&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Clarington&lt;/td&gt;
      &lt;td&gt;92013&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;49&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Victoria&lt;/td&gt;
      &lt;td&gt;91867&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1268&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Pickering&lt;/td&gt;
      &lt;td&gt;91771&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;23&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Maple Ridge&lt;/td&gt;
      &lt;td&gt;90990&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;78&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;North Vancouver&lt;/td&gt;
      &lt;td&gt;88168&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1457&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Brossard&lt;/td&gt;
      &lt;td&gt;85721&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1886&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Repentigny&lt;/td&gt;
      &lt;td&gt;84285&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1221&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Newmarket&lt;/td&gt;
      &lt;td&gt;84224&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2496&lt;/th&gt;
      &lt;td&gt;New Brunswick&lt;/td&gt;
      &lt;td&gt;Moncton&lt;/td&gt;
      &lt;td&gt;79470&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;28&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;New Westminster&lt;/td&gt;
      &lt;td&gt;78916&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1145&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Kawartha Lakes&lt;/td&gt;
      &lt;td&gt;75423&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2497&lt;/th&gt;
      &lt;td&gt;New Brunswick&lt;/td&gt;
      &lt;td&gt;Saint John&lt;/td&gt;
      &lt;td&gt;69895&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1022&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Caledon&lt;/td&gt;
      &lt;td&gt;66502&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1226&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Norfolk&lt;/td&gt;
      &lt;td&gt;64044&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;34&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Port Coquitlam&lt;/td&gt;
      &lt;td&gt;61498&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1113&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Halton Hills&lt;/td&gt;
      &lt;td&gt;61161&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;29&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;North Vancouver&lt;/td&gt;
      &lt;td&gt;58120&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1436&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Blainville&lt;/td&gt;
      &lt;td&gt;56863&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;990&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Aurora&lt;/td&gt;
      &lt;td&gt;55445&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1766&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Mirabel&lt;/td&gt;
      &lt;td&gt;50513&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1526&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Dollard-des-Ormeaux&lt;/td&gt;
      &lt;td&gt;48899&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2881&lt;/th&gt;
      &lt;td&gt;Nova Scotia&lt;/td&gt;
      &lt;td&gt;Kings[g]&lt;/td&gt;
      &lt;td&gt;47404&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1751&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Mascouche&lt;/td&gt;
      &lt;td&gt;46692&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;21&lt;/th&gt;
      &lt;td&gt;British Columbia&lt;/td&gt;
      &lt;td&gt;Langford&lt;/td&gt;
      &lt;td&gt;46584&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2472&lt;/th&gt;
      &lt;td&gt;Quebec&lt;/td&gt;
      &lt;td&gt;Victoriaville&lt;/td&gt;
      &lt;td&gt;46130&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1372&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Whitchurch-Stouffville&lt;/td&gt;
      &lt;td&gt;45837&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1112&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Haldimand&lt;/td&gt;
      &lt;td&gt;45608&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1097&lt;/th&gt;
      &lt;td&gt;Ontario&lt;/td&gt;
      &lt;td&gt;Georgina&lt;/td&gt;
      &lt;td&gt;45418&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;This really isn’t a satisfactory answer for me to be honest. Most of the entries on
this list were either missed in the join (e.g. Metro Vancouver not matching Vancouver,
similar issue for York Region), or the municipalities listed are part of a larger 
municipality that is served by public transit (e.g. Markham). Fixing those issues
would be possible, but a lot of work. It was time for the paretto principle. So I looked through the
list. This isn’t definitive but I think that Kawartha Lakes, Ontario, (population
~75000), is the largest municipality in Canada without a municipal bus service. They do
have a municipal service with these &lt;a href=&quot;https://www.kawarthalakes.ca/en/living-here/resources/Transit/CroppedDSC_1333-high.jpg&quot;&gt;little half-bus, half-van things&lt;/a&gt; though, so maybe that counts.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/canadas-biggest-transitless-muncipality/bus.jpg&quot; alt=&quot;Lindsay / Kawartha Lakes Green Bus&quot;&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>&quot;Infinite Word Ladder&quot;</title>
      <link>http://localhost:8080/articles/infinite-word-ladder/</link>
      <pubDate>Wed, 16 Feb 2022 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/infinite-word-ladder/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;One of the paper handouts my child used to do at school was the
“word ladder.” The exercise is a starting word and a series of
instructions, with a hint/definition of the word that will be
created.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For example, given the starting word “jump”, a sequence like this could be 
created:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replace first letter: get rid of&lt;/li&gt;
&lt;li&gt;Replace last letter: bereft of speech.&lt;/li&gt;
&lt;li&gt;Replace first vowel, add er at end: wetter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And then the obvious answer is “damper”.&lt;/p&gt;
&lt;p&gt;Given the ongoing waves of home / remote schooling we have as a result of
the covid pandemic, parents will often find themselves looking for work-
sheets for their ids to do. So I decided to write some code that could
make these word ladders.&lt;/p&gt;
&lt;p&gt;Firstly, I needed to decide what words would be valid for the puzzles.
Clearly we don’t want words that are above grade level that the kid 
wouldn’t have heard before. So I won’t be giving “clonality” as an answer
in the excercise. My first though was to use word frequencies, under the
assumption that kids would know the most common words. Unfortunately this
assumption did not bear out. There are a lot of commonly used words that
I wouldn’t expect children to know.&lt;/p&gt;
&lt;p&gt;Thankfully some kind folks already realized this and released a dataset
of words kids should know. It’s called the &lt;a href=&quot;https://www.readabilityformulas.com/articles/dale-chall-readability-word-list.php&quot;&gt;Dale-Chall Word List&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Dale-Chall Word List contains approximately three thousand familiar words 
that are known in reading by at least 80 percent of the children in Grade 5.
It gives a significant correlation with reading difficulty. It is not intended
as a list of the most important words for children or adults. It includes words
that are relatively unimportant and excludes some important ones. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So with this dictionary I just needed to write a few lines of code to enact the
logic of the word puzzle.&lt;/p&gt;
&lt;p&gt;First, start with a data class to hold the “rungs” on the ladder:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; collections &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; namedtuple
Rung = namedtuple(&lt;span class=&quot;string&quot;&gt;&quot;Rung&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;word description instructions&quot;&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I needed definitions of the words. This is the worst part of the result, as
the definitions are very dictionary-like.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; PyDictionary &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; PyDictionary
dictionary=PyDictionary()
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;dictionary_meaning&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(word)&lt;/span&gt;:&lt;/span&gt;
    defn = dictionary.meaning(word)
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; defn &lt;span class=&quot;keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;None&lt;/span&gt;:
        print(&lt;span class=&quot;string&quot;&gt;f'no definition for &lt;span class=&quot;subst&quot;&gt;{word}&lt;/span&gt;'&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;
    items = list(defn.items())
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; len(items) == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;:
        print(&lt;span class=&quot;string&quot;&gt;f'no definition for &lt;span class=&quot;subst&quot;&gt;{word}&lt;/span&gt;'&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; items[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;][&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;][&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;' '&lt;/span&gt;.join(items)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A method of deciding which words are valid:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;okay_word&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(word, used_words={})&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (word &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; dale_chall) &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; (word &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; used_words) &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; (&lt;span class=&quot;string&quot;&gt;&quot;'&quot;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; word)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now the fun part, the method with the list of available edits that finds
new rungs to put in the ladder:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;edit_word&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(word, used_words={})&lt;/span&gt;:&lt;/span&gt;
    edits = []
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; letter &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; string.ascii_lowercase:
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; okay_word(letter + word, used_words):
            edits.append((letter + word, &lt;span class=&quot;string&quot;&gt;'add letter at start'&lt;/span&gt;))
        &lt;span class=&quot;comment&quot;&gt;# don't want to just pluralize.&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; letter != &lt;span class=&quot;string&quot;&gt;&quot;s&quot;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; okay_word(word + letter, used_words):
            edits.append((word + letter, &lt;span class=&quot;string&quot;&gt;'add letter at end'&lt;/span&gt;))
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; okay_word(letter + word[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;:], used_words):
            edits.append((letter + word[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;:], &lt;span class=&quot;string&quot;&gt;'change first letter'&lt;/span&gt;))
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; okay_word(word[:&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;] + letter, used_words):
            edits.append((word[:&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;] + letter, &lt;span class=&quot;string&quot;&gt;'change last letter'&lt;/span&gt;))
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; letter1 &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; string.ascii_lowercase:
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; letter1 == word[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]:
            &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; letter2 &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; string.ascii_lowercase:
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; letter2 == word[&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;]:
                &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;
            new_word = letter1 + word[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;:&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;] + letter2
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; okay_word(new_word):
                edits.append((new_word, &lt;span class=&quot;string&quot;&gt;'change first and last letter'&lt;/span&gt;))

    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; pair &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; first_twos:
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; pair[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] == word[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; pair[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] == word[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]:
            &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; pair[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] == word[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; pair[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] != word[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; okay_word(pair + word[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;:]):
            edits.append((pair + word[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;:], &lt;span class=&quot;string&quot;&gt;'change second letter'&lt;/span&gt;))
        &lt;span class=&quot;keyword&quot;&gt;elif&lt;/span&gt; pair[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] != word[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] &lt;span class=&quot;keyword&quot;&gt;and&lt;/span&gt; pair[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] == word[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]:
            &lt;span class=&quot;comment&quot;&gt;# already checked first letter change above.&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;elif&lt;/span&gt; okay_word(pair + word[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;:], used_words):
            edits.append((pair + word[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;:], &lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;))
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; vowel_source &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; [&lt;span class=&quot;string&quot;&gt;'a'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'e'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'i'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'o'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'u'&lt;/span&gt;]:
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; vowel_dest &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; [&lt;span class=&quot;string&quot;&gt;'a'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'e'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'i'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'o'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'u'&lt;/span&gt;]:
            vowel_replaced = word.replace(vowel_source, vowel_dest, &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;)
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; okay_word(vowel_replaced, used_words):
                edits.append((vowel_replaced, &lt;span class=&quot;string&quot;&gt;'change first vowel'&lt;/span&gt;))

    edits = [(w,d) &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (w,d) &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; edits &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; w != word]
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; edits&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I like this and I think it might be fun to try to add new edits.&lt;/p&gt;
&lt;p&gt;Then just a couple methods to glue this crap together and make a ladder:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;find_next_rung&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(rung, used_words={})&lt;/span&gt;:&lt;/span&gt;
    edits = edit_word(rung.word, used_words)
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; len(edits) == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;:
        print(&lt;span class=&quot;string&quot;&gt;f&quot;failed to find a suitable word based on &lt;span class=&quot;subst&quot;&gt;{rung.word}&lt;/span&gt;. :(&quot;&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;None&lt;/span&gt;
    found_word, found_instruction = random.choice(edits)

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; Rung(found_word, dictionary_meaning(found_word), found_instruction)

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_ladder&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(word)&lt;/span&gt;:&lt;/span&gt;
    ladder = [Rung(word, &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;)]
    used_words = {ladder[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;].word}

    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(&lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;):
        next_rung = find_next_rung(ladder[len(ladder) - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;], used_words)
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; next_rung &lt;span class=&quot;keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;None&lt;/span&gt;:
            print(&lt;span class=&quot;string&quot;&gt;'breaking'&lt;/span&gt;)
            &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;
        used_words.add(next_rung.word)
        ladder.append(next_rung)
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; ladder&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here’s an example output:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;[Rung(word=&lt;span class=&quot;string&quot;&gt;'shoe'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'shop'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'a mercantile establishment for the retail sale of goods or services'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change last letter'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'show'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'the act of publicly exhibiting or entertaining'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change last letter'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'meow'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'the sound made by a cat (or any sound resembling this'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'glow'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'an alert and refreshed state'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'know'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'the fact of being aware of information that is known to few people'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'grow'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'pass into a condition gradually, take on a specific property or attribute; become'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'flow'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'the motion characteristic of fluids (liquids or gases'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'snow'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'precipitation falling from clouds in the form of ice crystals'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'plow'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'a farm tool having one or more heavy blades to break the soil and cut a furrow prior to sowing'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'crow'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'black birds having a raucous call'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'crown'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'the Crown (or the reigning monarch'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'add letter at end'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'frown'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'a facial expression of dislike or displeasure'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first letter'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'brown'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'an orange of low brightness and saturation'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first letter'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'clown'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'a rude or vulgar fool'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'drown'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'cover completely or make imperceptible'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;),
 Rung(word=&lt;span class=&quot;string&quot;&gt;'known'&lt;/span&gt;, description=&lt;span class=&quot;string&quot;&gt;'be cognizant or aware of a fact or a specific piece of information; possess knowledge or information about'&lt;/span&gt;, instructions=&lt;span class=&quot;string&quot;&gt;'change first two letters'&lt;/span&gt;)]&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>I Did a Deep Q Learning Course</title>
      <link>http://localhost:8080/articles/deep-q-learning-course/</link>
      <pubDate>Thu, 10 Feb 2022 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/deep-q-learning-course/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I had access to udemy courses back when
I was working at Deloitte Digital. One interesting course I did was
the &lt;a href=&quot;https://www.udemy.com/course/practical-ai-with-python-and-reinforcement-learning/&quot;&gt;introduction to deep q learning from Pieran Data&lt;/a&gt;. Deep Q learning
is a way to use neural nets to do reinforcement learning. It was an interesting course
and I learned a lot, so I’ll give a recap here.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Classical Q learning is a reinforcement learning algorithm that revolves
around making a table of all possible states and actions, and gives an
expected reward for each of these combinations. For problems with a
continuous state or action space, the states and choices are discretized
by bucketing (and bucket distribution is a hyperparameter).&lt;/p&gt;
&lt;p&gt;The table is made iteratively. At first it’s filled with zeroes, as no
rewards are known, and choices are made at random. Expected reward values
are updated using the &lt;a href=&quot;https://en.wikipedia.org/wiki/Bellman_equation&quot;&gt;Bellman Equation&lt;/a&gt;.
As expected reward values are updated, the randomness of action choices is reduced to fine-tune the reward values (this is called the Epsilon Greedy Strategy).&lt;/p&gt;
&lt;p&gt;Classic Q learning is great for a certain class of reinforcement learning problems.
Here’s an example we did in the course of classic q learning beating the “hill
car challenge.”:&lt;/p&gt;
&lt;p&gt;&lt;video controls width=&quot;250&quot;&gt;&lt;source src=&quot;hill-car-classic-q.mp4&quot; type=&quot;video/mp4&quot;&gt;Sorry, your browser doesn’t support embedded videos.&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;This works great but most realistic problems have too large a space of states
and actions, even after bucketing. The key insight of deep Q learning is that
similar states will lead to similar actions, so we can model the states and actions
using neural networks to make it a tractable problem. It’s been almost a year since
I covered this materal , and I feel pretty rusty so I won’t get too deep into it,
but here’s an example we did in the course of getting an AI that can play
Atari games:&lt;/p&gt;
&lt;p&gt;&lt;video controls width=&quot;250&quot;&gt;&lt;source src=&quot;breakout.mp4&quot; type=&quot;video/mp4&quot;&gt;Sorry, your browser doesn’t support embedded videos.&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;Overall it’s a very cool technique but I doubt I’ll ever get much use out of it.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>3D Printed Rocket</title>
      <link>http://localhost:8080/articles/3d-printed-rocket/</link>
      <pubDate>Mon, 24 Jan 2022 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/3d-printed-rocket/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;My old work (&lt;a href=&quot;http://twg.ca&quot;&gt;TWG&lt;/a&gt;) had a 3D printer for employees to play with and use. In
the summer of 2019 my son was getting into model rocket launching, but we kept losing
them in trees. So I decided to try 3d printing some rockets. It never really worked out,
but in my new spirit of blogging failures, I’m posting about it. My goal was to make
my own easily produced reusable rocket.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I am not a rocket scienctist or enginer, but I’ve played a fair bit of
&lt;a href=&quot;https://www.kerbalspaceprogram.com/&quot;&gt;Kerbal Space Program&lt;/a&gt;
and watched a lot of &lt;a href=&quot;https://www.youtube.com/channel/UCxzC4EngIsMrPmbm6Nxvb-A&quot;&gt;Scott Manley&lt;/a&gt;
videos. I didn’t really incorporate any proper rocket design into my ideas here. I
designed the rockets with these over-sized fins to facilitate 3d printing, by having a 
larger contact area on the printing surface.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/3d-printed-rocket/rocket1.jpg&quot; alt=&quot;a 3d printed rocket&quot;&gt;&lt;/p&gt;
&lt;p&gt;In terms of “easily produced” I wanted something I could easily print at work, i.e. I could 
fire something up in a few minutes and have it finish within a morning or afternoon so I
wasn’t wasting a lot of time at work doing this.&lt;/p&gt;
&lt;p&gt;Unfortunately the launch wasn’t a success. It would launch, fly hundreds of feet into the
air, then blow up:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/3d-printed-rocket/failed.jpg&quot; alt=&quot;failed rocket&quot;&gt;&lt;/p&gt;
&lt;p&gt;The issue arises from how a model rocket engine works. After ignition, the engine burns
it’s propellant, launching the rocket high into the sky. After this is burned up, a 
time delaying, non-propelling burn occurs, to allow the rocket to use its forward momentum
up before deploying the parachute at apogee. Once the time delay is used up, a smaller
charge blows upward into the rocket’s body, pushing off the nose cone and the chute. This is
shown in the images below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/3d-printed-rocket/Components-of-a-Model-Rocket-Engine.jpg&quot; alt=&quot;Components of a model rocket engine&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/3d-printed-rocket/Flight-Sequence.jpg&quot; alt=&quot;Flight Sequence&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://estesrockets.com/get-started/&quot;&gt;Image source&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My problem was the my single-walled rocket couldn’t handle the pressure of the chute charge,
so the fuselage would rupture. They were all blowing up at step 4 in the launch
sequence image above. I think this is slightly compounded by the 3d print ridges 
adding more friction to the nose cone removal, but the weak body is probably the main issue.&lt;/p&gt;
&lt;p&gt;I tried iterating on the design by taping the outside of the fuselage to reinforce it (still not strong 
enough), and having a wider diameter of fuselage to reduce internal pressure (also not strong enough). The real solution is 
probably one of: print a thicker fuselage, (but this would have taken too 
long), or to slide a paper tube into the fuselage to handle the
pressure, (but I didn’t want to source those). I shelved the project having run out
of desirable alternatives.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>The Best And Worst Words In Wordle</title>
      <link>http://localhost:8080/articles/best-and-worst-wordle/</link>
      <pubDate>Mon, 17 Jan 2022 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/best-and-worst-wordle/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;https://www.powerlanguage.co.uk/wordle/&quot;&gt;Wordle&lt;/a&gt; is a popular word deduction game. The
aim is to guess a word given six guesses. You can only guess valid English words that
are in wordle’s dictionary. Each wrong guess will yield hints. A letter
highlighted in yellow indicates it matches the target word somewhere. A letter marked in
green indicates the correct letter in the correct position. I feel like a branching
strategy (preferably choosing from common letters) is the best. But what word should you
start with? And what is the worst word to start with?&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Using the timeless magic of “inspect element” I grabbed the complete dictionary of 10657
words wordle considers to be valid (compare this to 10230 in my &lt;code&gt;/usr/share/dict/words&lt;/code&gt;
on mac). Wordle’s word list is pretty liberal with what it considers to be a valid
English word, containing things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://findwords.info/term/owled&quot;&gt;owled&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wiktionary.org/wiki/rusma&quot;&gt;rusma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Sango&quot;&gt;sango&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.collinsdictionary.com/dictionary/english/thymi&quot;&gt;thymi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So what is the best and worst word to start? The rules of the game mean that the first guess
will be best when it draws from the most common letters in the dictionary. So what are the 
most common letters in wordle’s set of five letter words? Here’s the distribution:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/best-and-worst-wordle/letter-frequency.png&quot; alt=&quot;wordle letter frequency&quot;&gt;&lt;/p&gt;
&lt;p&gt;We can see here that z, j, x, q are the least commonly used letters, but words also need
vowels, and y is the least common vowel. Unfortunately, no words use only there letters.
Through trial and error of adding more commonly used letters, I found the word &lt;a href=&quot;https://www.merriam-webster.com/medical/xylyl&quot;&gt;xylyl&lt;/a&gt;, which draws mostly from uncommon letters,
but I wanted to be a bit more sure.&lt;/p&gt;
&lt;p&gt;Here’s a couple methods that calculate two words “yellow” and “green” scores:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;yellow_matches&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(w, x)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; len(set(w).intersection(x))

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;green_matches&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(w, x)&lt;/span&gt;:&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; len([z &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (y, z) &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; zip(w, x) &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; y == z])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using this we can check each words score against all other words. Sorting by yellows, then greens gives these best starting words:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;right&quot;&gt;&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;word&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;yellow&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;green&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;aeros&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20698&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;7505&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;soare&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20698&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;5610&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;reais&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20402&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;7482&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;serai&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20402&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;aesir&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20402&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3618&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;aloes&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20092&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;7774&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;toeas&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19992&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;8021&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;stoae&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19992&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4119&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;lares&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19926&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9414&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;rales&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19926&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9149&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Or sorted by greens, then yellows:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;right&quot;&gt;&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;word&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;yellow&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;green&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;sores&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;16277&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9982&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;sanes&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;16625&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9914&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;sales&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;16854&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9825&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;sones&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;15442&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9772&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;soles&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;15671&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9683&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;bares&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;18712&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9661&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;cares&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;18932&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9649&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;pares&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;18999&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9642&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;sates&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;16754&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9594&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;tares&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19826&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9591&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;So it looks like “aeros” and “sores” are good starting words. I don’t think the
actual winning words ever end with ‘s’, so let’s look at those options. Most yellows:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;right&quot;&gt;&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;word&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;yellow&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;green&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;soare&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20698&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;5610&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;serai&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20402&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;aesir&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20402&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3618&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;stoae&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19992&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4119&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;laser&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19926&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;5371&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;seral&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19926&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4851&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;taser&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19826&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;5548&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;strae&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19826&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4405&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;earst&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19826&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4044&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;resat&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19826&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3747&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Most greens:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;right&quot;&gt;&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;word&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;yellow&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;green&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;saree&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;17460&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;7300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;soree&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;16277&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;7158&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;sared&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;19388&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;6907&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;sored&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;18205&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;6765&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;sooey&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;14819&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;6711&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;saned&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;18553&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;6697&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;boree&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;12211&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;6695&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;raree&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;12142&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;6624&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;laree&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;14608&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;6590&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;samey&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;17572&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;6554&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;And now let’s look at the worst starting options:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;right&quot;&gt;&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;word&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;yellow&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;green&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;xylyl&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4330&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;1425&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;fuffy&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4376&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;2751&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;gyppy&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4396&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;2382&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;hyphy&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4482&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;2118&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;cocco&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4710&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3467&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Those look like some terrible options to start with, but today I started with “aeros”, and the
correct answer was “proxy”. I think I would have been better off starting with the “xy” 
from “xylyl” as those are higher value letters.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Using an Artie 3000 as a Plotter</title>
      <link>http://localhost:8080/articles/artie-300-plotter/</link>
      <pubDate>Tue, 28 Dec 2021 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/artie-300-plotter/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;When I was a child, they had a plotter at my mom’s office. I don’t remember the model, but it was something like a &lt;a href=&quot;http://hpmuseum.net/display_item.php?hw=75&quot;&gt;HP 7550A&lt;/a&gt;. I was fascinated by it, and I’m sure I watched it go for many hours. From that, I’ve always loved plotter technology. I’ve always kind of wanted to make my own. Last year, the urge became too great and I tried out the &lt;a href=&quot;https://www.brachiograph.art/&quot;&gt;branchiograph&lt;/a&gt; project. I didn’t get the best results for various reasons.
&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This Christmas, we got my son an &lt;a href=&quot;http://codewithartie.com/&quot;&gt;Artie 3000&lt;/a&gt; robot. It’s a python-codable (more on this) turtle-graphics-like robot that uses a pen to draw on paper. I decided to try to turn it into a plotter.&lt;/p&gt;
&lt;p&gt;So my first let-down on this project is that, although python is supported, it’s only supported within the web interface you use to interact with the robot. There’s no public library to pip-install that lets you interact with the robot. So even though the box says “code in python” with a little screenshot showing an import command, it’s not really that easy. I thought about inspecting the web-socket traffic that controls the robot, but I thought I would try generating some python code for the robot that should draw something interesting before going to that effort.&lt;/p&gt;
&lt;p&gt;I started by finding a decent image to try to draw. My obvious choice was Mario. I love trying to impress my kids, so I picked Mario. My son is nuts about Mario. I can’t blame him.&lt;/p&gt;
&lt;p&gt;My first thought of row to take an rgb image and prepare it for printing in monochrome was just to do a threshold, but I quickly decided that wouldn’t look good at all. Thankfully I was alive in the 90s, and I remembered how people used to try to make 8-bit images look good: dithering! If it works for 8 bits, why not 1? The &lt;a href=&quot;https://solar.lowtechmagazine.com/&quot;&gt;low-tech magazine&lt;/a&gt; uses the same 1-bit dithering technique to reduce their image sizes.&lt;/p&gt;
&lt;p&gt;Here’s what Mario looks like after resizing and dithering to 1-bit:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/artie-300-plotter/mario.png&quot; alt=&quot;dithered 1-bit Mario&quot;&gt;&lt;/p&gt;
&lt;p&gt;I wrote some fairly trivial code to convert this row-wise into a series of turtle commands. Here is my first result:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/artie-300-plotter/first.png&quot; alt=&quot;first result&quot;&gt;&lt;/p&gt;
&lt;p&gt;I love this cool spiral look, but there’s a clear problem here. You can see that there’s a big spiral. This is because and the end of each row, the robot turns left, moves to the next row, and turns back right. But it has a slight preference to the left, about 4 degrees in my tests. My image was 70 rows, so that means the robot would have turned 210 degrees by the time it finished printing.&lt;/p&gt;
&lt;p&gt;I ran some tests to manually correct for the turning bias, and got more results:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/artie-300-plotter/second.png&quot; alt=&quot;second result&quot;&gt;&lt;/p&gt;
&lt;p&gt;This is two prints over one-another. You can make out Mario’s hat, but the line pitch is all wrong.&lt;/p&gt;
&lt;p&gt;I got a bit discouraged at this point because it seems pretty clear that the robot has a minimum distance it will go forward after turning. I’m not sure why. I experimented with getting it to move forward too far, and backing up to get the desired line pitch, but I couldn’t get it lined up right. It’s probably not insurmountable but I think I may have reached my personal point where this project ceased being fun. Projects that are given up on mid-way can be noteworthy too, so I thought I would put up a post.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Finding Latent Faces-with Non-negative Matrix Factorization</title>
      <link>http://localhost:8080/articles/finding-latent-faces-with-nnmf/</link>
      <pubDate>Mon, 01 Nov 2021 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/finding-latent-faces-with-nnmf/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Non-negative matrix factorization is a fast technique for generating embeddings from a dataset. More concretely, given a matrix you can decompose it into two matrices that are approximattely multiplicands of the matrix. I.e. given matrix &lt;code&gt;M&lt;/code&gt;, it finds matrices &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; such that &lt;code&gt;M ≈ AB&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;A very cool thing about embedding matrices is that the rows and columns that comprise these matrices naturally tend to fill with values that will multiply together to create the values in your data. More concretely again, if your dataset is pictures of faces, and embedding matrix will be composed of face-like images that will be added together in varying amounts to make the faces in the dataset.&lt;/p&gt;
&lt;p&gt;So let’s make some faces.&lt;/p&gt;
&lt;p&gt;Thankfully &lt;code&gt;sklearn.decomposition&lt;/code&gt; has an &lt;code&gt;NMF&lt;/code&gt; class. We can use that to do all the tough work here. I’ll be using the &lt;a href=&quot;https://www.kaggle.com/tavarez/the-orl-database-for-training-and-testing&quot;&gt;ORL images&lt;/a&gt; dataset for this. This is a classic greyscale faces dataset that’s been used in computer vision for decades.&lt;/p&gt;
&lt;p&gt;Here’s an example from the dataset:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/finding-latent-faces-with-nnmf/ORL.jpg&quot; alt=&quot;ORLFaces&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.researchgate.net/publication/221786184_PCA_and_LDA_Based_Neural_Networks_for_Human_Face_Recognition&quot;&gt;source&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here’s the code to load all the images into a big numpy array:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;    images = []
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; file &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; os.listdir(&lt;span class=&quot;string&quot;&gt;'archive'&lt;/span&gt;):
        img = np.array(Image.open(&lt;span class=&quot;string&quot;&gt;'archive/'&lt;/span&gt; + file))
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; len(img.shape) == &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;: &lt;span class=&quot;comment&quot;&gt;# some images come in rgb.&lt;/span&gt;
            img = img[:, :, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] &lt;span class=&quot;comment&quot;&gt;# not really desaturation.&lt;/span&gt;
        images.append(img.flatten())
    images = np.array(images)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s make 20 latent faces:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;    k = &lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;
    nmf_model = NMF(n_components=k, random_state=&lt;span class=&quot;number&quot;&gt;42&lt;/span&gt;)

    nmf_model.fit(images)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can decompose the embeddings to see what the latent faces look like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;    images = []
    i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; image &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; nmf_model.components_:
        image = image.flatten()
        image.resize((&lt;span class=&quot;number&quot;&gt;80&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;70&lt;/span&gt;))
        images.append(image)
        plt.figure()
        plt.savefig(&lt;span class=&quot;string&quot;&gt;f'imgs/&lt;span class=&quot;subst&quot;&gt;{i}&lt;/span&gt;.png'&lt;/span&gt;)
        i += &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here’s the cool generated face image:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/finding-latent-faces-with-nnmf/faces.gif&quot; alt=&quot;faces generated by nnmf from orl dataset&quot;&gt;&lt;/p&gt;
&lt;p&gt;You can see that the faces aren’t entirely novel, and have characteristics of faces from the dataset, such as glasses. Overall it’s a pretty cool technique that shows an interesting aspect of NNMF and embeddings. I tend to work with embeddings a lot more with NLP in my work, so it’s great to have an eye-catching and visual demo of what the technique does.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>A &quot;100 emoji&quot; maker</title>
      <link>http://localhost:8080/articles/100-emoji-maker/</link>
      <pubDate>Sun, 31 Oct 2021 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/100-emoji-maker/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;The 100 emoji is iconic; it’s a symbol recognized across cultures and it has a semiotic impact globally. In a world where most societies have standardized around a base-10 (or decimal) number system, a doubly-underlined 100 is a shining beacon of success, or total mastery. The forthright and striking symbol of flawless execution, total knowledge, and success lends itself naturally, in this remix culture we live in, to imitations. If 100 can be thus underlined, can we convey the same messages by borrowing the style of the emoji but with different content? Of course we can, that’s what cultures do.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So let’s whip up a 100 emoji generator. I do most of my f-around work in python in a notebook these days, for several reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I do most of my day job in python,&lt;/li&gt;
&lt;li&gt;Libraries. As much as I love mucking around in elixir or whatever you can’t beat having numpy and PIL for something like this.&lt;/li&gt;
&lt;li&gt;Jupyter: not having to duck in and out of terminal and preview windows tightens up the cognitive loop of development. You arguably end up with shittier code but who really cares for something like this. It’s better to finish a stupid project than get bogged down with irrelevancies and decide it’s not worth the effort.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So here’s a method that makes 100 emoji:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;# font from https://www.dafont.com/captain-redemption.font?text=100+365&amp;amp;back=theme&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;# copied some stuff from https://stackoverflow.com/a/63005869/973810&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;# reference https://stackoverflow.com/questions/17056209/python-pil-affine-transformation&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; PIL &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; Image, ImageFont, ImageDraw, ImageFilter
    &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; numpy &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; np

    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;make_image&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(number, w=&lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;, h=&lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;

        fill = (&lt;span class=&quot;number&quot;&gt;222&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;comment&quot;&gt;# a nice red&lt;/span&gt;
        img = Image.new(&lt;span class=&quot;string&quot;&gt;'RGB'&lt;/span&gt;, (&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*w, &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*h), (&lt;span class=&quot;number&quot;&gt;255&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;255&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;255&lt;/span&gt;))

        &lt;span class=&quot;comment&quot;&gt;# found this free for personal use font. It't more a 300 vibe, but close enough.&lt;/span&gt;
        font_filename = &lt;span class=&quot;string&quot;&gt;'Captain Redemption.ttf'&lt;/span&gt;
        font_size = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
        number = str(number)

        &lt;span class=&quot;comment&quot;&gt;# find a good font-size to fit the width&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, w):
            font = ImageFont.truetype (font_filename, i)
            x, y = font.getsize(number)
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; x &amp;gt; &lt;span class=&quot;number&quot;&gt;0.9&lt;/span&gt; * w:
                font_size = i
                &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;
        draw = ImageDraw.Draw(img)
        i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;# do the underlines&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; y &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(int(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;0.53&lt;/span&gt;*h), int(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;0.58&lt;/span&gt;*h)):
            draw.arc([(int(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;-0.10&lt;/span&gt;*w), y), (int(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;1.60&lt;/span&gt;*w), int(y + &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;0.20&lt;/span&gt;*w))], start=&lt;span class=&quot;number&quot;&gt;230&lt;/span&gt;, end=&lt;span class=&quot;number&quot;&gt;280&lt;/span&gt;-i, fill=fill)
            i += &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;
        i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; y &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(int(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;0.62&lt;/span&gt;*h), int(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;0.67&lt;/span&gt;*h)):
            draw.arc([(int(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;-0.10&lt;/span&gt;*w), y), (int(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;1.60&lt;/span&gt;*w), int(y + &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;0.20&lt;/span&gt;*w))], start=&lt;span class=&quot;number&quot;&gt;233&lt;/span&gt;, end=&lt;span class=&quot;number&quot;&gt;274&lt;/span&gt;-i, fill=fill)
            i += &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;# Use supersampling to achieve anti-aliased underlines&lt;/span&gt;
        img = img.resize((w, h), Image.ANTIALIAS)
        draw = ImageDraw.Draw(img)        
        font = ImageFont.truetype (font_filename, font_size)
        x, y = font.getsize(number)

        draw.text((&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;), text=number, font=font, fill=fill)

        draw = ImageDraw.Draw(img)
        width = int(w/&lt;span class=&quot;number&quot;&gt;17.5&lt;/span&gt;)

        &lt;span class=&quot;comment&quot;&gt;# warp/sheer the image with more height on the left.&lt;/span&gt;
        img = img.transform((w, h),
                        Image.AFFINE, (&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;-0.1&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;-3&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;0.1&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;0.62&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;),
                        resample=Image.BICUBIC, fillcolor=(&lt;span class=&quot;number&quot;&gt;255&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;255&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;255&lt;/span&gt;))
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; img&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/articles/100-emoji-maker/828.png&quot; alt=&quot;828 emoji&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/100-emoji-maker/yeet.png&quot; alt=&quot;yeet emoji&quot;&gt;&lt;/p&gt;
&lt;p&gt;I like to finish off my blog posts with a list of things I would like to improve, so here goes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first character should be taller, but not rendered with a larger font as that would make it wider. This goes beyond the capabilities of true type fonts.&lt;/li&gt;
&lt;li&gt;It doesn’t work for longer words.&lt;/li&gt;
&lt;li&gt;Related to point 1, a lot of the “math” in the method was trial-and-error. It would be a lot better to have a system of drawing different elements in their own areas. In the 100 emoji these are polygonal, which would get quite complex so I didn’t bother for a joke project.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Fibonacci Spheres in Blender</title>
      <link>http://localhost:8080/articles/fibonacci-spheres-blender/</link>
      <pubDate>Mon, 31  Aug 2020 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/fibonacci-spheres-blender/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I’ve been messing about with blender a bit since the pandemic started. I originally thought I could use it for visualizing data, which is certainly true, but I’ve found more that I’ve been getting in blender-world. I was watching a “coding adevntures” video over the weekend where the author described using fibonacci spheres as a way of evenly distibuting points on a sphere. But I couldn’t find an easy way to do this in blender.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So I made an extension. It’s mostly cobbled together from code snippets I found on-line. You can check it out on &lt;a href=&quot;https://github.com/rbwendt/blender-add-mesh-fibonacci-sphere&quot;&gt;my git hub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/rbwendt/blender-add-mesh-fibonacci-sphere/master/Video.gif&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Archiving photos from iOS to a network drive</title>
      <link>http://localhost:8080/articles/photo-transfer-ios/</link>
      <pubDate>Fri, 31 Jul 2020 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/photo-transfer-ios/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I wrote a while back about a script I wrote to run on my android phone that would sort and archive any photos I had on the device into dated folders I have on a network drive. Privacy and de-googling concerns led me to get an iphone when the time came to upgrade (essential, my old phone’s manufacturer shut down, and faced with an aging battery and a looming lack of support I decided to upgrade). This left me with a problem, how would I sort my images into my archive?&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I’ve found it a bit harder to do fun hacks like the photo sorting hack on iOs as compared to android. My new work flow is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;import (and delete) everything into i photo.&lt;/li&gt;
&lt;li&gt;export everything from there to a folder on my laptop.&lt;/li&gt;
&lt;li&gt;run this script:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'set'&lt;/span&gt;

    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Copier&lt;/span&gt;&lt;/span&gt;

        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(path)&lt;/span&gt;&lt;/span&gt;
            @path = path
            @created_folders = [].to_set
            @path = &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;
            @userhost = &lt;span class=&quot;string&quot;&gt;'network-host'&lt;/span&gt;
            @destpath = &lt;span class=&quot;string&quot;&gt;'/mnt/big-disk/photos'&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;

        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_date&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(file)&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;comment&quot;&gt;# some say Modified, other Modification.&lt;/span&gt;
            mod_date = &lt;span class=&quot;string&quot;&gt;`exiftool &quot;&lt;span class=&quot;subst&quot;&gt;#{file}&lt;/span&gt;&quot; | grep 'Modif'`&lt;/span&gt;
            mod_date = mod_date.split(&lt;span class=&quot;string&quot;&gt;&quot;\n&quot;&lt;/span&gt;)[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] &lt;span class=&quot;comment&quot;&gt;# first line&lt;/span&gt;
                            .split(&lt;span class=&quot;string&quot;&gt;&quot; : &quot;&lt;/span&gt;)[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;comment&quot;&gt;# the date time part&lt;/span&gt;
                            .split(&lt;span class=&quot;string&quot;&gt;&quot; &quot;&lt;/span&gt;)[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] &lt;span class=&quot;comment&quot;&gt;# the date part&lt;/span&gt;
            mod_date.split(&lt;span class=&quot;string&quot;&gt;':'&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;

        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;create_folder_if_need_be&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(date)&lt;/span&gt;&lt;/span&gt;
            year, month, day = date
            &lt;span class=&quot;keyword&quot;&gt;unless&lt;/span&gt; @created_folders.&lt;span class=&quot;keyword&quot;&gt;include&lt;/span&gt;?(date)
                puts &lt;span class=&quot;string&quot;&gt;&quot;creating folder for &lt;span class=&quot;subst&quot;&gt;#{date.join(&lt;span class=&quot;string&quot;&gt;'-'&lt;/span&gt;)}&lt;/span&gt;&quot;&lt;/span&gt;
                &lt;span class=&quot;string&quot;&gt;`ssh &lt;span class=&quot;subst&quot;&gt;#{@userhost}&lt;/span&gt; &quot;mkdir &lt;span class=&quot;subst&quot;&gt;#{@destpath}&lt;/span&gt;/&lt;span class=&quot;subst&quot;&gt;#{year}&lt;/span&gt;&quot; 2&amp;gt; /dev/null`&lt;/span&gt;
                &lt;span class=&quot;string&quot;&gt;`ssh &lt;span class=&quot;subst&quot;&gt;#{@userhost}&lt;/span&gt; &quot;mkdir &lt;span class=&quot;subst&quot;&gt;#{@destpath}&lt;/span&gt;/&lt;span class=&quot;subst&quot;&gt;#{year}&lt;/span&gt;/&lt;span class=&quot;subst&quot;&gt;#{month}&lt;/span&gt;&quot; 2&amp;gt; /dev/null`&lt;/span&gt;
                &lt;span class=&quot;string&quot;&gt;`ssh &lt;span class=&quot;subst&quot;&gt;#{@userhost}&lt;/span&gt; &quot;mkdir &lt;span class=&quot;subst&quot;&gt;#{@destpath}&lt;/span&gt;/&lt;span class=&quot;subst&quot;&gt;#{year}&lt;/span&gt;/&lt;span class=&quot;subst&quot;&gt;#{month}&lt;/span&gt;/&lt;span class=&quot;subst&quot;&gt;#{day}&lt;/span&gt;&quot; 2&amp;gt; /dev/null`&lt;/span&gt;
                @created_folders &amp;lt;&amp;lt; date
            &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;

        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;transfer_file_to_dated_folder&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(file, date)&lt;/span&gt;&lt;/span&gt;
            year, month, day = date
            &lt;span class=&quot;string&quot;&gt;`scp &quot;&lt;span class=&quot;subst&quot;&gt;#{file}&lt;/span&gt;&quot; &lt;span class=&quot;subst&quot;&gt;#{@userhost}&lt;/span&gt;:&lt;span class=&quot;subst&quot;&gt;#{@destpath}&lt;/span&gt;/&lt;span class=&quot;subst&quot;&gt;#{year}&lt;/span&gt;/&lt;span class=&quot;subst&quot;&gt;#{month}&lt;/span&gt;/&lt;span class=&quot;subst&quot;&gt;#{day}&lt;/span&gt;`&lt;/span&gt;
            puts &lt;span class=&quot;string&quot;&gt;&quot;transferred &lt;span class=&quot;subst&quot;&gt;#{file}&lt;/span&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;

        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;delete_local_file&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(file)&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;string&quot;&gt;`rm &quot;&lt;span class=&quot;subst&quot;&gt;#{file}&lt;/span&gt;&quot;`&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;

    path = &lt;span class=&quot;string&quot;&gt;&quot;./photos/&quot;&lt;/span&gt;
    files = Dir[&lt;span class=&quot;string&quot;&gt;&quot;&lt;span class=&quot;subst&quot;&gt;#{path}&lt;/span&gt;*&quot;&lt;/span&gt;].sort_by(&amp;amp;&lt;span class=&quot;symbol&quot;&gt;:downcase&lt;/span&gt;)
    c = Copier.new(path)
    files.each &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;|file|&lt;/span&gt;
        date = c.get_date(file)
        c.create_folder_if_need_be(date)
        c.transfer_file_to_dated_folder(file, date)
        c.delete_local_file(file)
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Looking at this now, it would be great to move the core of the files.each block into the class, and read the path and host from &lt;code&gt;argv&lt;/code&gt; but it works so I’m happy with it.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Uploading and sorting photos from android over sftp using termux</title>
      <link>http://localhost:8080/articles/android-upload/</link>
      <pubDate>Mon, 30 Sep 2019 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/android-upload/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I was super excited to find that I can install bash on my phone, then scp and ruby. It opens up a lot of possibility of what a phone should really be able to do. Too often I feel constrained by limited options in apps.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;An example of this is taking old photos and putting them into my long term storage on my home computer. I backup to google photos, but I like to keep a local copy too. My old workflow for organizing files was to either use usb or “andftp” app on my android to get the files onto my machine, then sort them roughly by date into folders for ease of retrieval. Both of these methods are time consuming and don’t give the best result.&lt;/p&gt;
&lt;p&gt;Here is my new work flow…&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    userhost = &amp;#39;someguy@192.168.0.100&amp;#39;
    destpath = &amp;#39;/mnt/big/camera&amp;#39;

    [&amp;#39;PIC&amp;#39;, &amp;#39;VID&amp;#39;].each do |type|
      transer_files(type)
    end

    def transfer_files(type)
      fs = ` ls storage/dcim/camera/#{t}* `.split(&amp;quot;\n&amp;quot;)

      prefixess = fs.map {|f| f.gsub(/.+#{t}_/, &amp;#39;&amp;#39;).gsub(/_.+/,&amp;#39;&amp;#39;)}.uniq

      years = prefixes.map{|p| p.slice(0,4)}.uniq

      prefixes.each do |p|
        handle_date_prefix(p)
      end
    end

    def handle_date_prefix(p)
      year = p.slice(0,4)

      mth = p.slice(4,2)
      day = p.slice(6,2)


      prefs.each do |p|
        transfer(year, mth, day)
      end
    end

    def transfer(year, mth, day)
     `ssh #{userhost} &amp;quot;mkdir #{destpath}/#{year}&amp;quot; `
     `ssh #{userhost} &amp;quot;mkdir #{destpath}/#{year}/#{mth}&amp;quot; `
     `ssh #{userhost} &amp;quot;mkdir #{destpath}/#{year}/#{mth}/#{day}&amp;quot; `

      c= `scp storage/dcim/camera/#{t}_#{p}* #{user_host}:#{destpath}m/#{year}/#{mth}/#{day} &amp;amp;&amp;amp; rm storage/dcim/camera/#{t}_#{p}*`
      puts c
    end&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This nicely organizes all my files by date and clears out the space on my phone.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Fizzbuzz in Different Paradigms / Techniques</title>
      <link>http://localhost:8080/articles/fizzbuzz/</link>
      <pubDate>Mon, 31 Dec 2018 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/fizzbuzz/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I was reading an &lt;a href=&quot;http://iolivia.me/posts/fizzbuzz-in-10-languages/&quot;&gt;article on Fizzbuzz&lt;/a&gt;. Across the various languages used, the article has two recurring techniques. For each technique listed here, I will give it a rating on a scale of my choosing. The two techniques listed in the article are:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;1-conditional-logic&quot;&gt;1. conditional logic&lt;/h2&gt;
&lt;p&gt;This is the standard technique that everyone, regardless of experience, would probably think of first. The following example will run in every c inspired language known to humankind (actually, unless otherwise noted, all code is js).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; ; i &amp;lt; &lt;span class=&quot;number&quot;&gt;33&lt;/span&gt; ; i++) {
      &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (i % &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
        &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;'fizzbuzz'&lt;/span&gt;)
      } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (i % &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
        &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;'fizz'&lt;/span&gt;)
      } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (i % &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
        &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;'buzz'&lt;/span&gt;)
      } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
        &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(i)
      } 
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;understandableness factor: ⭐⭐⭐&lt;/p&gt;
&lt;p&gt;The cool-ness here is entirely due to being immediately understandable by anyone who has had an intro to programming.&lt;/p&gt;
&lt;h2 id=&quot;2-pattern-match&quot;&gt;2. pattern match&lt;/h2&gt;
&lt;p&gt;Fancy (i.e. “functional”) languages do a fancy thing called pattern matching, which is a lot like coding a conditional, but you let the compiler / runtime / interpreter determine when a variable matches a certain pattern rather than checking whether a certain condition is true. So instead if saying, if x is like this, do that, you would say when x matches this, do that.&lt;/p&gt;
&lt;p&gt;Here’s an example in elixir because I am not smart enough for haskell:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-elixir&quot;&gt;    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;FizzBuzz&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;run&lt;/span&gt;&lt;/span&gt;(x) &lt;span class=&quot;keyword&quot;&gt;when&lt;/span&gt; rem(x, &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;) == 0 &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
            IO.puts(&lt;span class=&quot;string&quot;&gt;&quot;fizzbuzz&quot;&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;run&lt;/span&gt;&lt;/span&gt;(x) &lt;span class=&quot;keyword&quot;&gt;when&lt;/span&gt; rem(x, &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;) == 0 &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
            IO.puts(&lt;span class=&quot;string&quot;&gt;&quot;fizz&quot;&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;run&lt;/span&gt;&lt;/span&gt;(x) &lt;span class=&quot;keyword&quot;&gt;when&lt;/span&gt; rem(x, &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;) == 0 &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
            IO.puts(&lt;span class=&quot;string&quot;&gt;&quot;buzz&quot;&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;run&lt;/span&gt;&lt;/span&gt;(x) &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
            IO.puts(x)
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
    Enum.each(0..&lt;span class=&quot;number&quot;&gt;31&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt;(x)-&amp;gt; 
        FizzBuzz.run(x)
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;cool factor: ⭐⭐⭐⭐&lt;/p&gt;
&lt;p&gt;This is a built in language feature, but pattern matches are definitely more interesting than condtionals.&lt;/p&gt;
&lt;h2 id=&quot;feeling-a-little-let-down-&quot;&gt;Feeling a little let down.&lt;/h2&gt;
&lt;p&gt;Given that there are ten languages in the article and only two techniques, I was disappointed. I’ve done a lot of &lt;em&gt;“write x-in-y”&lt;/em&gt; posts before, but I feel like there isn’t much point in writing the same code in ten different syntaxes. I thought it would be cool to see what other techniques could be devised.&lt;/p&gt;
&lt;h2 id=&quot;0-array-programming&quot;&gt;0. array programming&lt;/h2&gt;
&lt;p&gt;I googled how someone would do this in an array programming language, and found a &lt;a href=&quot;https://wycd.net/posts/2017-01-19-fizz-buzz-and-triangles-in-j.html&quot;&gt;terrific article explaining all about how to do so in j&lt;/a&gt;. The idea is to filter the list by which numbers match which modulus, and then do a lookup into an array to get the correct answer.&lt;/p&gt;
&lt;p&gt;cool factor: ⭐⭐⭐⭐&lt;/p&gt;
&lt;p&gt;Anything in j is super cool.&lt;/p&gt;
&lt;h2 id=&quot;1-exception-handling&quot;&gt;1. exception handling&lt;/h2&gt;
&lt;p&gt;They tell you not to use exception handling for control flow. But everyone keeps doing it, so it must be good. There’s one &lt;code&gt;if&lt;/code&gt; statement in there that I would love to get rid of, but it would be difficult without jumping through more hoops than this jokey article deserves.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;    fbs = [[&lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'fizzbuzz'&lt;/span&gt;], [&lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'fizz'&lt;/span&gt;], [&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'buzz'&lt;/span&gt;]]
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; ; i &amp;lt; &lt;span class=&quot;number&quot;&gt;16&lt;/span&gt;; i++) {
        fails = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt; {
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (e &lt;span class=&quot;keyword&quot;&gt;of&lt;/span&gt; fbs) {

          x = e[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]
          msg = e[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]
          a = [&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; =&amp;gt;&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(msg)]
          &lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt; {
            a[i % x]()
            &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;
          } &lt;span class=&quot;keyword&quot;&gt;catch&lt;/span&gt; (e) {
            fails++
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (fails &amp;gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;) {
              &lt;span class=&quot;keyword&quot;&gt;throw&lt;/span&gt; e
            }
          }
        }
      } &lt;span class=&quot;keyword&quot;&gt;catch&lt;/span&gt; (e) {
        &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(i);
      }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;kludge factor: 🦃🦃🦃🦃🦃&lt;/p&gt;
&lt;p&gt;I give this one five kludge turkeys. Two for using the exception control flow thing, and three for calling the function in an array accessed by modulus that will raise and error when the modulus isn’t zero. I wanted to just divide by zero, but javascript is wrong and thinks that division by zero returns infinity, so I had to kludge it up a notch.&lt;/p&gt;
&lt;h2 id=&quot;2-boolean-operators-ifs-in-disguise-&quot;&gt;2. boolean operators (&lt;code&gt;if&lt;/code&gt;s in disguise)&lt;/h2&gt;
&lt;p&gt;This takes advantage of the short circuiting nature of &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; and &lt;code&gt;||&lt;/code&gt; to simulate the conditional logic.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;     &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; ; i &amp;lt; &lt;span class=&quot;number&quot;&gt;17&lt;/span&gt; ; i++) {
        ((i % &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) &amp;amp;&amp;amp;
          (&lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;'fizzbuzz'&lt;/span&gt;) || &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;))
        || ((i % &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) &amp;amp;&amp;amp;
          (&lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;'fizz'&lt;/span&gt;) || &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;))
        || ((i % &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) &amp;amp;&amp;amp;
          (&lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;'buzz'&lt;/span&gt;) || &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;))
        || &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(i)
      }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;hack factor: 💽💽💽💽&lt;/p&gt;
&lt;p&gt;I give this one four cd-roms. You will honestly see code that uses the short circuiting of boolean operators for control flow, and in fact some languages like php and ruby have special low-priority &lt;code&gt;and&lt;/code&gt; and &lt;code&gt;or&lt;/code&gt; operators to supplement &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; and &lt;code&gt;||&lt;/code&gt; that are specifically meant for control flow. So you’re definitely a hacker if you use this.&lt;/p&gt;
&lt;h2 id=&quot;3-multiplication-ifs-in-a-better-disguise-&quot;&gt;3. multiplication (&lt;code&gt;if&lt;/code&gt;s in a better disguise)&lt;/h2&gt;
&lt;p&gt;Some languages let you multiply strings by integers to make repeated strings, e.g. &lt;code&gt;2 * &amp;#39;oy&amp;#39; == &amp;#39;oyoy&amp;#39;&lt;/code&gt;. Ruby does this.&lt;/p&gt;
&lt;p&gt;We can exploit this to make fizz buzz by doing slightly convoluted things to multiply fizz, buzz, and fizzbuzz by either 1 or 0 times to make the desired strings. This effectively is re-implementing the if conditional by doing something 0 or 1 times:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;fizzbuzz_mult&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(n)&lt;/span&gt;&lt;/span&gt;
      s = (&lt;span class=&quot;string&quot;&gt;'fizzbuzz'&lt;/span&gt;*(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;- [&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,n% &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;].min)) 
      s &amp;lt;&amp;lt; &lt;span class=&quot;string&quot;&gt;'fizz    '&lt;/span&gt; * (&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; - s.length / &lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;) * (&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;- [&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,n% &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;].min)
      s &amp;lt;&amp;lt; &lt;span class=&quot;string&quot;&gt;'buzz    '&lt;/span&gt; * (&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; - s.length / &lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;) * (&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;- [&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,n% &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;].min)
      s &amp;lt;&amp;lt; n.to_s * (&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; - s.length / &lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;)
      s.strip
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;.upto(&lt;span class=&quot;number&quot;&gt;16&lt;/span&gt;).each {&lt;span class=&quot;params&quot;&gt;|n|&lt;/span&gt; puts fizzbuzz_mult(n)}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;hack factor: 💽💽💽💽💽&lt;/p&gt;
&lt;p&gt;This is essentially a hack on top of the boolean method, so it gets one extra hacker cd-rom.&lt;/p&gt;
&lt;h2 id=&quot;4-done-declaratively-in-sql&quot;&gt;4. done declaratively in sql&lt;/h2&gt;
&lt;p&gt;I’m so happy about this one. Every line has a little treat:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;distinct&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;on&lt;/span&gt; (range.num)
      &lt;span class=&quot;keyword&quot;&gt;coalesce&lt;/span&gt;(msg, &lt;span class=&quot;keyword&quot;&gt;cast&lt;/span&gt;(range.num &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;text&lt;/span&gt;))
    &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;select&lt;/span&gt; * &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; generate_series(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;16&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;num&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;range&lt;/span&gt;
      &lt;span class=&quot;keyword&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;join&lt;/span&gt; (
        &lt;span class=&quot;keyword&quot;&gt;values&lt;/span&gt; (&lt;span class=&quot;string&quot;&gt;'fizzbuzz'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;),
          (&lt;span class=&quot;string&quot;&gt;'fizz'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;),
          (&lt;span class=&quot;string&quot;&gt;'buzz'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;)
      ) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; lookup (msg, &lt;span class=&quot;keyword&quot;&gt;num&lt;/span&gt;)
      &lt;span class=&quot;keyword&quot;&gt;on&lt;/span&gt; range.num % lookup.num = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;awesome factor: 🎆🎆🎆🎆🎆&lt;/p&gt;
&lt;p&gt;This one gets full awesome-ness score. With my undying infatuation with SQL, I can’t help but fawn over joining the series generation to a &lt;code&gt;SELECT VALUES&lt;/code&gt;, then using &lt;code&gt;DISTINCT ON&lt;/code&gt; to only return the first joined value, and coalescing in the default case from the nulls. It’s really lovely. Rock on SQL!&lt;/p&gt;
&lt;h2 id=&quot;5-list-reduction&quot;&gt;5. list reduction&lt;/h2&gt;
&lt;p&gt;This is in ruby again. The idea is to evaluate all of the if options until one is found to pass, then short circuit out of the rest of the loop. I really like the &lt;code&gt;1&lt;/code&gt; modulus, &lt;code&gt;n&lt;/code&gt; message part of this that keeps the special default case in the same reduction. The fizzbuzz problem is basic, but in it’s spirit it is really about handling a list of preferred possibilties. In that lens, this is the best solution.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;fizzbuzz&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(n)&lt;/span&gt;&lt;/span&gt;
      [[&lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;, &lt;span class=&quot;symbol&quot;&gt;:fizzbuzz&lt;/span&gt;], [&lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;symbol&quot;&gt;:fizz&lt;/span&gt;], [&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;symbol&quot;&gt;:buzz&lt;/span&gt;], [&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, n]].reduce(&lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;|a, (m, msg)|&lt;/span&gt;
        a &amp;amp;&amp;amp; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; n % m == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
          puts msg
          &lt;span class=&quot;literal&quot;&gt;false&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;
          &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;.upto(&lt;span class=&quot;number&quot;&gt;16&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;|i|&lt;/span&gt;
      fizzbuzz(i)
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Loveability: 💞💞💞💞&lt;/p&gt;
&lt;p&gt;I really like how this hides the conditional logic behind a list reduction. This is actually a really useful technique when you have to evaluate an arbitary number of booleans.&lt;/p&gt;
&lt;h2 id=&quot;6-oop&quot;&gt;6. oop&lt;/h2&gt;
&lt;p&gt;This is, of course, a bunch of java boilerplate wrapped around the original conditional technique. I prefer this in a way though. We’re only ever doing the conditional check once in any of these implementations, but in the real world this technique is better because we isolate that logic in the factory, and the let our polymorphism handle any future differences in behaviour.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;FizzBuzzable&lt;/span&gt; &lt;/span&gt;{
      &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;say&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;&lt;/span&gt;;
    }

    &lt;span class=&quot;keyword&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;FizzBuzzer&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;FizzBuzzable&lt;/span&gt; &lt;/span&gt;{
    }

    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;FizzBuzz&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;FizzBuzzer&lt;/span&gt; &lt;/span&gt;{
      &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;say&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        println(&lt;span class=&quot;string&quot;&gt;&quot;fizzbuzz&quot;&lt;/span&gt;); 
      }
    }

    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Fizz&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;FizzBuzzer&lt;/span&gt; &lt;/span&gt;{
      &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;say&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        println(&lt;span class=&quot;string&quot;&gt;&quot;fizz&quot;&lt;/span&gt;); 
      }
    }

    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Buzz&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;FizzBuzzer&lt;/span&gt; &lt;/span&gt;{
      &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;say&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        println(&lt;span class=&quot;string&quot;&gt;&quot;buzz&quot;&lt;/span&gt;);
      }
    }

    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Other&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;FizzBuzzer&lt;/span&gt; &lt;/span&gt;{
      &lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; n;
      Other(&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; m) {
       n = m; 
      }
      &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;say&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        println(n);
      }
    } 

    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;FizzBuzzFactory&lt;/span&gt; &lt;/span&gt;{
      &lt;span class=&quot;function&quot;&gt;FizzBuzzer &lt;span class=&quot;title&quot;&gt;getFizzBuzzer&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; n)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (n % &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
          &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; FizzBuzz(); 
        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (n % &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
          &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Fizz(); 
        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (n % &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
          &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Buzz(); 
        } 
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Other(n);
      }
    }

    FizzBuzzFactory factory = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; FizzBuzzFactory();
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; i &amp;lt; &lt;span class=&quot;number&quot;&gt;17&lt;/span&gt;; i++) {
      (factory.getFizzBuzzer(i)).say();
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enterprisey-ness score: 🏦🏦🏦&lt;/p&gt;
&lt;p&gt;This is enterprisey, but not that enterprisey. It needs more lines of code.&lt;/p&gt;
&lt;p&gt;Usefulness score: 🛠🛠🛠🛠&lt;/p&gt;
&lt;p&gt;If you were actually coding something with more complex logic than writing out a string given a certain condtion, polymorphism would be a useful tool to reach for.&lt;/p&gt;
&lt;h2 id=&quot;7-functions&quot;&gt;7. functions&lt;/h2&gt;
&lt;p&gt;This one makes use of functions and currying. The checks will only happen if the previous failed.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;    modder = &lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;m&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;x&lt;/span&gt;) =&amp;gt;&lt;/span&gt; x % m == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
    mod15 = modder(&lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;)
    mod5 = modder(&lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;)
    mod3 = modder(&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;)

    fizzbuzzCurry = &lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;fn, msg&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;n, a&lt;/span&gt;) =&amp;gt;&lt;/span&gt; fn(n)? &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(msg) : a[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;](n, a.slice(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;))

    sayFizzbuzz = fizzbuzzCurry(mod15, &lt;span class=&quot;string&quot;&gt;'fizzbuzz'&lt;/span&gt;)
    sayFizz = fizzbuzzCurry(mod5, &lt;span class=&quot;string&quot;&gt;'fizz'&lt;/span&gt;)
    sayBuzz = fizzbuzzCurry(mod3, &lt;span class=&quot;string&quot;&gt;'buzz'&lt;/span&gt;)
    sayDefault = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;n&lt;/span&gt; =&amp;gt;&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(n) &lt;span class=&quot;comment&quot;&gt;// so it does not also output empty array&lt;/span&gt;

    fizzbuzz = &lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;n&lt;/span&gt;) =&amp;gt;&lt;/span&gt; sayFizzbuzz(n, [sayFizz, sayBuzz, sayDefault])

    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; i &amp;lt; &lt;span class=&quot;number&quot;&gt;17&lt;/span&gt;; i++) {
      fizzbuzz(i)
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;functional score: λλλλ&lt;/p&gt;
&lt;p&gt;I really enjoy how this one uses some functional programming concepts to achieve the desired result.&lt;/p&gt;
&lt;h2 id=&quot;8-code-generation&quot;&gt;8. code generation&lt;/h2&gt;
&lt;p&gt;This one is mostly done to be silly. No one would ever do this, but I suppose that if you did it would make sense to only generate this ridiculous code once, to a file, then use that from then on.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;    &lt;span class=&quot;meta&quot;&gt;&amp;lt;?php&lt;/span&gt;

    define(&lt;span class=&quot;string&quot;&gt;'BIGGEST_NUMBER'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;32767&lt;/span&gt;);

    $str = &lt;span class=&quot;string&quot;&gt;'function fizzbuzz($n) {'&lt;/span&gt; . &lt;span class=&quot;string&quot;&gt;&quot;\n&quot;&lt;/span&gt;;

    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; $i &amp;lt; BIGGEST_NUMBER; $i++) {
      $msg = &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;;
      &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($i % &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
        $msg = &lt;span class=&quot;string&quot;&gt;'fizzbuzz'&lt;/span&gt;;
      } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($i % &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
        $msg = &lt;span class=&quot;string&quot;&gt;'fizz'&lt;/span&gt;;
      } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($i % &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
        $msg = &lt;span class=&quot;string&quot;&gt;'buzz'&lt;/span&gt;;
      } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
        $msg = $i;
      }
      $str .= &lt;span class=&quot;string&quot;&gt;'if($n == '&lt;/span&gt; . $i . &lt;span class=&quot;string&quot;&gt;'){echo &quot;'&lt;/span&gt; . $msg  . &lt;span class=&quot;string&quot;&gt;&quot;\\n\&quot;; return;}\n&quot;&lt;/span&gt;;
    }
    $str .= &lt;span class=&quot;string&quot;&gt;'echo(&quot;error: this function only works with positive 16 bit signed integers.\n&quot;);'&lt;/span&gt;;
    $str .= &lt;span class=&quot;string&quot;&gt;&quot;}\n&quot;&lt;/span&gt;;

    &lt;span class=&quot;keyword&quot;&gt;eval&lt;/span&gt;($str);

    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; $i &amp;lt; &lt;span class=&quot;number&quot;&gt;17&lt;/span&gt;; $i++) {
      fizzbuzz($i);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The code that this generates is 32000 lines of:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;fizzbuzz&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($n)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;fizzbuzz\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;1\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;2\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;buzz\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;4\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;fizz\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;6&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;buzz\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;7\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;8\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;9&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;buzz\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;fizz\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;11\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;buzz\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;13&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;13\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;14&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;14\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($n == &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;){&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;fizzbuzz\n&quot;&lt;/span&gt;; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;;}
    ...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;kludgey-ness score: 💩💩💩💩💩&lt;/p&gt;
&lt;p&gt;I only filled this in because it’s another unconventional technique that would solve this question.&lt;/p&gt;
&lt;h2 id=&quot;9-declaratively-in-css&quot;&gt;9. declaratively in css&lt;/h2&gt;
&lt;p&gt;This one uses css’s nth-child formulae, and &lt;code&gt;content&lt;/code&gt; to fill in the values. I kind of hate this one, because I don’t think you can refer to which child is matched in the &lt;code&gt;content&lt;/code&gt; attribute, so you have to set up a separate css rule for each default case, making them totally not default and going against the spirit of the.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;    &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;style&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;css&quot;&gt;
    &lt;span class=&quot;selector-class&quot;&gt;.fizzbuzz&lt;/span&gt; &lt;span class=&quot;selector-pseudo&quot;&gt;:nth-child(15n+1)&lt;/span&gt;&lt;span class=&quot;selector-pseudo&quot;&gt;:after&lt;/span&gt; {
     &lt;span class=&quot;attribute&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'1'&lt;/span&gt;
    }
    &lt;span class=&quot;selector-class&quot;&gt;.fizzbuzz&lt;/span&gt; &lt;span class=&quot;selector-pseudo&quot;&gt;:nth-child(15n+2)&lt;/span&gt;&lt;span class=&quot;selector-pseudo&quot;&gt;:after&lt;/span&gt; {
     &lt;span class=&quot;attribute&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'2'&lt;/span&gt;
    }
    &lt;span class=&quot;selector-class&quot;&gt;.fizzbuzz&lt;/span&gt; &lt;span class=&quot;selector-pseudo&quot;&gt;:nth-child(15n+3)&lt;/span&gt;&lt;span class=&quot;selector-pseudo&quot;&gt;:after&lt;/span&gt; {
     &lt;span class=&quot;attribute&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'buzz'&lt;/span&gt;&lt;span class=&quot;built_in&quot;&gt;WSh-child&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;n+&lt;span class=&quot;number&quot;&gt;9&lt;/span&gt;):after {
     content: &lt;span class=&quot;string&quot;&gt;'9'&lt;/span&gt;
    }
    &lt;span class=&quot;selector-class&quot;&gt;.fizzbuzz&lt;/span&gt; &lt;span class=&quot;selector-pseudo&quot;&gt;:nth-child(15n+10)&lt;/span&gt;&lt;span class=&quot;selector-pseudo&quot;&gt;:after&lt;/span&gt; {
     &lt;span class=&quot;attribute&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'10'&lt;/span&gt;
    }
    &lt;span class=&quot;selector-class&quot;&gt;.fizzbuzz&lt;/span&gt; &lt;span class=&quot;selector-pseudo&quot;&gt;:nth-child(15n+11)&lt;/span&gt;&lt;span class=&quot;selector-pseudo&quot;&gt;:after&lt;/span&gt; {
     &lt;span class=&quot;attribute&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'11'&lt;/span&gt;
    }
    &lt;span class=&quot;selector-class&quot;&gt;.fizzbuzz&lt;/span&gt; &lt;span class=&quot;selector-pseudo&quot;&gt;:nth-child(15n+12)&lt;/span&gt;&lt;span class=&quot;selector-pseudo&quot;&gt;:after&lt;/span&gt; {
     &lt;span class=&quot;attribute&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'12'&lt;/span&gt;
    }
    &lt;span class=&quot;selector-class&quot;&gt;.fizzbuzz&lt;/span&gt; &lt;span class=&quot;selector-pseudo&quot;&gt;:nth-child(15n+13)&lt;/span&gt;&lt;span class=&quot;selector-pseudo&quot;&gt;:after&lt;/span&gt; {
     &lt;span class=&quot;attribute&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'13'&lt;/span&gt;
    }
    &lt;span class=&quot;selector-class&quot;&gt;.fizzbuzz&lt;/span&gt; &lt;span class=&quot;selector-pseudo&quot;&gt;:nth-child(15n+14)&lt;/span&gt;&lt;span class=&quot;selector-pseudo&quot;&gt;:after&lt;/span&gt; {
     &lt;span class=&quot;attribute&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'14'&lt;/span&gt;
    }
    &lt;span class=&quot;selector-tag&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;selector-class&quot;&gt;.fizzbuzz&lt;/span&gt; &lt;span class=&quot;selector-pseudo&quot;&gt;:nth-child(15n+0)&lt;/span&gt;&lt;span class=&quot;selector-pseudo&quot;&gt;:after&lt;/span&gt; {
     &lt;span class=&quot;attribute&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'fizzbuzz'&lt;/span&gt;
    }
    &lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;style&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;'fizzbuzz'&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      as many of these as desired.
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;kludge score: 💩💩&lt;/p&gt;
&lt;p&gt;I give this one two poops of kludge.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I set out to solve this issue in ten different ways, instead of in ten different languages. I ended up stealing one of the techniques, but ended up using 7 languages in this article. It has been a really fun exercise. In the 1992 Remix of &lt;em&gt;Scenario&lt;/em&gt; from &lt;em&gt;A Tribe Called Quest&lt;/em&gt; Cut Monitor Milo asks “What does it take to check a technique?”, the answer: “Many styles, many styles!” I have enjoying checking my technique and working on my many styles while making this. If I ever have to apply for a job again, and they ask me about this chestnut, I may surprise them with 32000 lines of PHP.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Deep Learning Fundamentals</title>
      <link>http://localhost:8080/articles/deep-learning-fundamentals/</link>
      <pubDate>Fri, 31  Aug 2018 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/deep-learning-fundamentals/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Here’s a talk I gave at work that gives a run-down of some fundamental concepts in deep learning, and I finished the talk with an example of a convolutional neural network in keras.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;iframe src=&quot;https://www.youtube.com/embed/NNNEr_5quUw?rel=0&quot; allow=&quot;autoplay; encrypted-media&quot; allowfullscreen=&quot;&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;

</description>
    </item>
    <item>
      <title>A Ruby Pipe</title>
      <link>http://localhost:8080/articles/ruby-pipe/</link>
      <pubDate>Wed, 31 Jan 2018 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/ruby-pipe/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Javascript is going to get a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Pipeline_operator&quot;&gt;pipeline operator&lt;/a&gt; any day now, and I love working with it in elixir, so I thought I’d try to make one in ruby.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So here’s an implementation&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Object&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;pipe&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;arg&lt;/span&gt;&lt;/span&gt;
        arg.(&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;)
      &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it works like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;    plus1 = -&amp;gt; (x) {x+&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;}
    &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;.pipe(plus1) &lt;span class=&quot;comment&quot;&gt;# 2&lt;/span&gt;
    &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;.pipe(plus1).pipe(plus1) &lt;span class=&quot;comment&quot;&gt;# 3&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you can do things like add a logging aspect:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;    putit = -&amp;gt;(x) {puts x; x}
    &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;.pipe(plus1).pipe(putit).pipe(plus1) &lt;span class=&quot;comment&quot;&gt;# outputs 2 and returns 3&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s pretty neat, but it only works with lambdas and procs for now. And it’s obviously not standard ruby so you’d be swimming against the tide if you tried to do anything useful with this.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Introduction to J</title>
      <link>http://localhost:8080/articles/j-intro/</link>
      <pubDate>Sun, 31 Dec 2017 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/j-intro/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I tried using j for some of my &lt;a href=&quot;http://github.com/rbwendt/advent-of-code-2017/&quot;&gt;advent of code&lt;/a&gt; puzzles. I found it wasn’t totally suitable for a lot of the challenges, but I had fun learning about J nonetheless.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;J is a declarative and functional array programming language. I like this quote from &lt;a href=&quot;http://code.jsoftware.com/wiki/Guides/GettingStarted&quot;&gt;J’s new user guide&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;J isn’t just another way to declare variables and write loops. J is a way of thinking big: describing an algorithm by looking at it as a whole and breaking it into its natural parts. You’re going to have to spend some time learning what those natural parts are. Your skill as a program designer will help, but it will be fighting against your learned tendency to think small.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But I won’t be giving an example of that. I’ll just show how some of &lt;a href=&quot;http://www.jsoftware.com/help/dictionary/vocabul.htm&quot;&gt;J’s vocabulary&lt;/a&gt; works.&lt;/p&gt;
&lt;p&gt;Here’s how to multiply two numbers in J:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;       4 * 4
    16&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But let’s look at a silly way of doing the same multiplication:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;       NB. note that comments in J start with NB., for nota bene
       1
    1
       NB. commands read right to left.

       NB. $ is the reshape operator it will take the input and
       NB. change it into an array with the size on the left.
       4 $ 1
    1 1 1 1
       NB. you can reshape to multiple dimensions
       4 4 $ 1
    1 1 1 1
    1 1 1 1
    1 1 1 1
    1 1 1 1
       NB. now we have 4 * 4 = 16 ones above, we need to add them up.

       NB. / is the insert operator. It adds it&amp;#39;s left operand between
       NB. everything in the right operand.
       NB. So this shows the sum of all of the columns:
       + / 4 4 $ 1
    4 4 4 4
       NB. So, to get the result of 4 * 4, we need to apply the + insert twice:
       + / + / 4 4 $ 1
    16&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, let’s imagine Guass knew J &lt;a href=&quot;https://notesonmathematics.wordpress.com/2013/04/01/the-gauss-triangle-trick/&quot;&gt;when he was in school&lt;/a&gt;, he could have done this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;       +/ 1 + i.100
    5050&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which probably isn’t as fun as the original story.&lt;/p&gt;
&lt;p&gt;And for day of of 2017 advent of code, the question was very well suited for J. It gives you a 16 x 16 array of numbers, and asks for the sum of the max of each column minus the minus of each column. So in J, that was:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    e =: 790 ... NB. tonnes of numbers
    NB. reshape the input.
    f =: 16 16 $ e

    NB. insert the minimum into the list
    max =: &amp;gt;./
    NB. insert the maximum into the list
    min =: &amp;lt;./

    NB. sum of maxes minus mins. (|: is transpose)
    +/ (max |: f - min |: f) NB. answer&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And that’s it. I really love J but I doubt I’ll get any chance to use it professionally.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Popping errors out from ruby threads using a Queue</title>
      <link>http://localhost:8080/articles/pop-exception-ruby-thread/</link>
      <pubDate>Tue, 09 May 2017 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/pop-exception-ruby-thread/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I had an issue at work where some database writes were throwing errors within a thread, and the error was being silently eaten when the thread died.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The solution is to use a queue for inter-thread communication, like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;q = Queue.new

Thread.new &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
    i = &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
    loop &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;begin&lt;/span&gt;
        sleep i
        i += &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
        raise &lt;span class=&quot;string&quot;&gt;'whatever'&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;rescue&lt;/span&gt; StandardError =&amp;gt; e
        q &amp;lt;&amp;lt; e
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;

loop &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
    puts q.size
&lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Intro to Bayesian Classifiers</title>
      <link>http://localhost:8080/articles/bayes-classifier/</link>
      <pubDate>Sun, 30 Apr 2017 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/bayes-classifier/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Bayes’ theorem is a way of determining the likelihood of an event A given that another event B has occurred. It’s a way of making an educated guess without much information to go on.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;It’s a way of going from knowing the likelihood of evidence, given a known outcome to knowing the likelihood of a known outcome given existing evidence. E.g. What’s the likelihood tacos are for dinner? If we know the likelihood of tacos, the likelihood of a meal being dinner, and the likelihood of tacos, given that it’s dinner, we can find this out.&lt;/p&gt;
&lt;p&gt;Bayes’ Theorem gives you an idea of how much you should trust the evidence you have. If your evidence is weak, you won’t end up trusting it. For example, I’m sure my neighbours don’t think that our house is on fire every time they hear my fire alarm going off at supper time. (But it is pretty good evidence that I’m a lousy cook.) They’ve lost their trust in the evidence that my fire alarm gives that our house is on fire.&lt;/p&gt;
&lt;p&gt;Say you are looking for &lt;code&gt;P(A|B)&lt;/code&gt;, the probability of event A occurring given the fact that we have the evidence B. For this to work, you need to know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;P(B|A)&lt;/code&gt;: The probability that an event B is an A&lt;/li&gt;
&lt;li&gt;&lt;code&gt;P(A)&lt;/code&gt;: The probability of A occurring. (This is often called the prior probability of A.)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;P(B)&lt;/code&gt;: The probability of B occurring.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Given these data, you can put the numbers into the following equation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;P(A|B) = P(B|A) * P(A) / P(B)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You might ask: “How do we get this equation?” We can start with the axiom of probability: &lt;code&gt;P(A and B) = P(A given B)P(B)&lt;/code&gt;. This axiom is saying that the probability of two things happening is the same as the probability that one thing happened, given that the other already happened.&lt;/p&gt;
&lt;p&gt;This gets us 90% of the way to Bayes’ Theorem. From the axiom, you see that &lt;code&gt;P(A given B) = P(A and B)/P(B)&lt;/code&gt;. Now use &lt;code&gt;P(B and A) = P(A and B)&lt;/code&gt;, and reverse the terms in the axiom to get &lt;code&gt;P(A given B) = P(B given A)P(B)/P(A)&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;a-simple-example&quot;&gt;A Simple Example&lt;/h1&gt;
&lt;p&gt;Suppose you have two bags containing marbles. Bag A contains 2 red balls and 1 yellow ball. Bag B contains 1 red ball and two yellow balls.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/bayes-classifier/urns.png&quot; alt=&quot;urns.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;You don’t know which bag is which.&lt;/p&gt;
&lt;p&gt;If you pull a yellow ball of a bag, what is the probability that it is bag A? We have an intuitive feeling that it’s most likely Bag B, but Bayes’ can give us an exact answer. This will be given by:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;P(Bag A given a yellow ball being pulled) = P(Yellow ball given bag A) * P(bag A) / P(yellow ball)&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;P(yellow ball given bag A)``: This is the number of yellow balls (1) in bag A divided by the total number of balls in bag A (3), so&lt;/code&gt;1/3`.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;P(bag A)&lt;/code&gt;: This is the number of bags that are bag B (1) divided by the number of bags, so ‘1/2’.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;P(yellow ball)&lt;/code&gt;: This is the probability of drawing a yellow ball from any bag. Thus it’s the total number of yellow balls across all bags (3), divided by the total number of balls in all bags (6), so ‘3/6’&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Plugging these values in, we get the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;P(Bag A|yellow) = (1/3) * (1/2) / (3/6)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The result is 1/3. So we know that if we reach our hand into one of bag A and bag B, and draw a yellow ball, that the probability that we reached into bag A was 1/3. This matches our intuition, but Bayes’ Theorem is most well known for it’s intuition defying examples.&lt;/p&gt;
&lt;h1 id=&quot;a-mind-expanding-example&quot;&gt;A mind-expanding example&lt;/h1&gt;
&lt;p&gt;You’re walking down the hall at work. You see someone walk out of the software development wing who is &lt;code&gt;odd&lt;/code&gt;. You wonder to yourself: is this person a Fortan developer? Your sneaking suspicion is that this &lt;code&gt;odd&lt;/code&gt; person is probably a Fortran developer because you have a feeling like Fortran developers are mostly &lt;code&gt;odd&lt;/code&gt;. Let’s work through an example.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;P(fortran developer, given odd) = P(odd, given Fortran developer) * P(fortran developer) / P(odd)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s substitute in some estimates for these values.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;P(odd, given fortran developer)&lt;/code&gt;: Let’s say 85% of fortran developers are &lt;code&gt;odd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;P(fortran developer)&lt;/code&gt;: Most developers are &lt;code&gt;average&lt;/code&gt; and use &lt;code&gt;react&lt;/code&gt;. Only 1% of all developers use Fortran.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;P(odd)&lt;/code&gt;: Across the whole company, you estimate that 10% of developers are &lt;code&gt;odd&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let’s plug the numbers into Bayes’ theorem and find out whether the &lt;code&gt;odd&lt;/code&gt; person we have observed is probably a Fortran developer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;P(fortran developer, given odd) = (0.85) * (0.01) / (0.1)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And the answer is 0.085, or 8.5%. This runs counter to the original intuition that the developer must be a fortran developer because they are odd. While it’s true that most fortran developers are odd, there are so few fortran developers total, meaning that most of the time an odd developer is not a fortran dev.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;odd&lt;/code&gt; Fortran developers are outnumbered by the comparatively less common &lt;code&gt;odd&lt;/code&gt; react developers, but that the total number of &lt;code&gt;odd&lt;/code&gt; react developers is still higher. So just because someone is &lt;code&gt;odd&lt;/code&gt;, it doesn’t make them a Fortran developer.&lt;/p&gt;
&lt;h1 id=&quot;learning-through-bayes-theorem&quot;&gt;Learning Through Bayes’ Theorem&lt;/h1&gt;
&lt;p&gt;This is all super interesting and cool, but there’s an even more cooler application of this theory we can look at. Notice how the prior probabilities we worked with in the examples before were static. We can continually update these to get a better model of our simulation as we encounter new data. Assuming that the model behaves consistently, we will get continually better results.&lt;/p&gt;
&lt;p&gt;A historical example of this line of reasoning comes from a thought experiment performed by Thomas Bayes. The experimenter asks an assistant to throw a ball onto a table (for the sake of the experiment, it doesn’t bounce or roll). The goal of the experiment is to determine the location of this ball without being able to see its location. The assistant would then throw ball after ball onto the table and tell the experimenter whether each successive ball landed to the left or right, and behind or in front of the first ball. By running successive trials, the experimenter can update their view of where the ball might be. For example, if most subsequent balls are reported as being to the left of the first ball, it’s safe to guess it’s near the right side of the table. Bayes’ Theorem lets us quantify this measurement.&lt;/p&gt;
&lt;h1 id=&quot;a-proper-learning-example&quot;&gt;A proper learning example&lt;/h1&gt;
&lt;p&gt;Now we’ve seen how we can apply a learning and Bayes’ to improve our predictions using probability. Let’s apply the same to classifying something a bit more complex. Here we will be tracking multiple probabilities and combining those to predict a classification of a document.&lt;/p&gt;
&lt;p&gt;This technique assumes that we have a training set of data where a human has manually gone through and confirmed the classifications of a group of documents.&lt;/p&gt;
&lt;p&gt;Example of headlines and news category:&lt;/p&gt;
&lt;p&gt;text&lt;/p&gt;
&lt;p&gt;classification&lt;/p&gt;
&lt;p&gt;Local Team Loses Game&lt;/p&gt;
&lt;p&gt;sports&lt;/p&gt;
&lt;p&gt;Player Loses Game&lt;/p&gt;
&lt;p&gt;sports&lt;/p&gt;
&lt;p&gt;Movie breaks box office record&lt;/p&gt;
&lt;p&gt;entertainment&lt;/p&gt;
&lt;p&gt;English team scores goal&lt;/p&gt;
&lt;p&gt;sports&lt;/p&gt;
&lt;p&gt;gravity waves recorded using machine&lt;/p&gt;
&lt;p&gt;science&lt;/p&gt;
&lt;p&gt;New Comedy Is A Good Movie&lt;/p&gt;
&lt;p&gt;entertainment&lt;/p&gt;
&lt;p&gt;New Global Warming Movie&lt;/p&gt;
&lt;p&gt;science&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;Using this data we can train a classifier… Let’s break down the results by word and see which words tend to be in certain categories:&lt;/p&gt;
&lt;p&gt;word&lt;/p&gt;
&lt;p&gt;P(sports)&lt;/p&gt;
&lt;p&gt;P(entertainment)&lt;/p&gt;
&lt;p&gt;P(science)&lt;/p&gt;
&lt;p&gt;Local&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;Team&lt;/p&gt;
&lt;p&gt;2 / 2&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;Loses&lt;/p&gt;
&lt;p&gt;2 / 2&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;Game&lt;/p&gt;
&lt;p&gt;2 / 2&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;Player&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;Movie&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;2 / 3&lt;/p&gt;
&lt;p&gt;1 / 3&lt;/p&gt;
&lt;p&gt;breaks&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;box&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;office&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;record&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;1 / 2&lt;/p&gt;
&lt;p&gt;1 / 2&lt;/p&gt;
&lt;p&gt;English&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;Scores&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;Goal&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;Gravity&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;Waves&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;Using&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;Machine&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;New&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;1 / 2&lt;/p&gt;
&lt;p&gt;1 / 2&lt;/p&gt;
&lt;p&gt;Comedy&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;Good&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;1 / 1&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;(Note that this data will work for an example, but for good results you would want a much larger training set than this.)&lt;/p&gt;
&lt;p&gt;Here we can see the prior probabilities of a given word in a title affecting the classification of the document. Now let’s assume that we fed millions of headlines into this system and ended up with something like this:&lt;/p&gt;
&lt;p&gt;word&lt;/p&gt;
&lt;p&gt;P(sports)&lt;/p&gt;
&lt;p&gt;P(entertainment)&lt;/p&gt;
&lt;p&gt;P(science)&lt;/p&gt;
&lt;p&gt;Local&lt;/p&gt;
&lt;p&gt;33000&lt;/p&gt;
&lt;p&gt;33000&lt;/p&gt;
&lt;p&gt;33000&lt;/p&gt;
&lt;p&gt;Team&lt;/p&gt;
&lt;p&gt;35578&lt;/p&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;p&gt;Loses&lt;/p&gt;
&lt;p&gt;29666&lt;/p&gt;
&lt;p&gt;200&lt;/p&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;And so on. This gives an example of how sports-centric terms will train to give high probabilities of related documents landing in the sports category. The prior evidence here is strong.&lt;/p&gt;
&lt;p&gt;When we want to classify a new document, how do we compute the probability of it being in a given class, now that it has multiple terms? First, let’s think about what it would mean if there were only two terms to worry about.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;P(sports, given win AND team) = P(win, given sports AND team) * P(team given sports) * P(sports) / (P(win AND team) * P(team))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is already complex for only two terms, but let’s look at a simpler way to look at this. We can assume independence of the terms. This may not be the most accurate model but it will give us results that we can work with and evaluate. This assumption that the terms are independent makes calculation simple, but it’s also not entirely accurate, hence why this technique is called ‘naive’. This is the ‘bag of words’ technique commonly used in NLP. For example, headlines that contain ‘delicious’ would tend to occur more often with ‘cake’ than ‘manure’, meaning ‘delicious’ and ‘cake’ have a dependence. Naive Bayes’ classifiers can compete very well against other classifiers in terms of accuracy, but we need to be mindful of this limitation that we have imposed on ourselves.&lt;/p&gt;
&lt;p&gt;If we assume that instances of ‘win’ and ‘team’ in a sentence are independent, (which they aren’t entirely), we get an easier formula where we already have the answers in our table.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;P(sports, given win AND team) = P(win given sports) * P(team given sports) * P(sports) / (P(win) * P(team))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will be a lot easier to calculate. And we can generalize this formula:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;P(sports, given words) = (product of each P(word|sports)) * P(sports) / (product of each P(word))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With this formula in hand, we just have to iterate through each classification to determine if a document is in a given class, then we can report the most likely classification along with it’s probability. If a user confirms the classification, then we can add the new information to the prior probability table.&lt;/p&gt;
&lt;h1 id=&quot;so-how-would-you-implement-this-&quot;&gt;So how would you implement this?&lt;/h1&gt;
&lt;p&gt;Generally as a developer it’s best to reach for a pre-built tool rather than making your own. You don’t usually make yourself a hammer every time you see a loose nail. Similarly it’s best to reach for a pre-built library that can handle this kind of classification for you.&lt;/p&gt;
&lt;p&gt;But there is real value in understanding how algorithms work. So let’s take a look at how one would implement a naive Bayesian classifier.&lt;/p&gt;
&lt;p&gt;What would the psuedo-code look like?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;classify classes = [], document:
  max_class, max_score = null, 0
  for (class : classes) {
    score = get_score(class, d)
    if score &amp;gt; max_score
      max_class = class
      max_score = score
  }
  return max_class;

get_score class, document:
  score = log(get_prior(class))
  features = tokenize(doc)
  for(feature : features) {
    score += log(getProbability(feature))
  }
  return score;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here we have two methods. &lt;code&gt;classify&lt;/code&gt; is pretty self explanatory. It’s just finding the maximum scored class for the given document. &lt;code&gt;get_score&lt;/code&gt; is more interesting. Here is where we apply naive Bayes to calculate the scores for each class. Notice two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We’re using &lt;code&gt;log&lt;/code&gt; and addition instead of multiplication. This is typical in NB implementations. This is done to avoid issues with underflow in floating point numbers. But the result is the same; adding logs is equivalent to multiplication (just ask your slide rule). But this log arithmetic means that the number we’re getting here isn’t a probability. That’s fine because we just want to find with class gives the highest number.&lt;/li&gt;
&lt;li&gt;Notice how we don’t divide by the denominator &lt;code&gt;P(B)&lt;/code&gt;, this is because it’s a constant across all of our documents so there is no need to repeatedly do this calculation since we’re just looking for a the highest number, not a probability.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;An important part is missing here, we didn’t compute the tables of prior probabilities. As mentioned before, we can do that by working through a collection of pre-classified training documents and building up counts of which features lead to which classes. Let’s look at how that might look:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;train class, features:
  increment_class(class)
  for (feature : features) {
    increment_feature(feature, class)
  }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The training will keep track of the occurrence of the different class and the occurrence of different features within each class.&lt;/p&gt;
&lt;p&gt;Here is a working example in old-fashioned javascript that does the same thing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Bayes() {
  this.features = {}
  this.categories = {}
}

Bayes.prototype.getScore = function(category, features) {
  score = Math.log(this.getPrior(category))

  for(var feature of features) {
    score += Math.log(this.getProbability(feature, category))
  }

  return score
}

Bayes.prototype.getPrior = function(category) {
  return (this.categories[category] || 0.1) / this.totalDocuments
}

Bayes.prototype.getProbability = function(feature, category) {
  return (this.features[category][feature] || 0.1) / this.categories[category]
}

Bayes.prototype.classify = function(features) {
  let maxClass = null
  let maxScore = -Infinity
  for (var category in this.categories) {
    const score = this.getScore(category, features)
    if (score &amp;gt; maxScore) {
      maxClass = category
      maxScore = score
    }
  }
  return maxClass
}

Bayes.prototype.incrementTotal = function(category) {
  this.totalDocuments = (this.totalDocuments || 0) + 1
}

Bayes.prototype.incrementCategory = function(category) {
  this.categories[category] = (this.categories[category] || 0) + 1
}

Bayes.prototype.incrementFeature = function(feature, category) {
  if (!this.features[category]) {
    this.features[category] = {}
  }
  this.features[category][feature] = (this.features[category][feature] || 0) + 1
}

Bayes.prototype.train = function(category, features) {
  this.incrementTotal()
  this.incrementCategory(category)
  for (var feature of features) {
    this.incrementFeature(feature, category)
  }
}

b = new Bayes()

b.train(&amp;#39;city&amp;#39;, [&amp;#39;subway&amp;#39;, &amp;#39;tower&amp;#39;, &amp;#39;hotel&amp;#39;])
b.train(&amp;#39;city&amp;#39;, [&amp;#39;opera&amp;#39;, &amp;#39;tower&amp;#39;, &amp;#39;hotel&amp;#39;])
b.train(&amp;#39;city&amp;#39;, [&amp;#39;opera&amp;#39;, &amp;#39;subway&amp;#39;, &amp;#39;hotel&amp;#39;])

b.train(&amp;#39;country&amp;#39;, [&amp;#39;cow&amp;#39;, &amp;#39;field&amp;#39;, &amp;#39;hill&amp;#39;])
b.train(&amp;#39;country&amp;#39;, [&amp;#39;cow&amp;#39;, &amp;#39;field&amp;#39;, &amp;#39;farm&amp;#39;])

// city
console.log(b.classify([&amp;#39;subway&amp;#39;, &amp;#39;hill&amp;#39;, &amp;#39;tower&amp;#39;]))

// country
console.log(b.classify([&amp;#39;farm&amp;#39;, &amp;#39;hill&amp;#39;, &amp;#39;sheep&amp;#39;]))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And that is it. We’ve successfully used Bayes’ Theorem to classify documents.&lt;/p&gt;
&lt;h3 id=&quot;references&quot;&gt;references&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cs.nyu.edu/faculty/davise/ai/bayesText.html&quot;&gt;http://www.cs.nyu.edu/faculty/davise/ai/bayesText.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://php-nlp-tools.com/documentation/bayesian-model.html&quot;&gt;http://php-nlp-tools.com/documentation/bayesian-model.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=YBvilAYd5sE&quot;&gt;https://www.youtube.com/watch?v=YBvilAYd5sE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20160403012037/http://bionicspirit.com/blog/2012/02/09/howto-build-naive-bayes-classifier.html&quot;&gt;https://web.archive.org/web/20160403012037/http://bionicspirit.com/blog/2012/02/09/howto-build-naive-bayes-classifier.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/a/20556654/973810&quot;&gt;http://stackoverflow.com/a/20556654/973810&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://scikit-learn.org/stable/modules/naive_bayes.html&quot;&gt;http://scikit-learn.org/stable/modules/naive_bayes.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=EbyUsf_jUjk&quot;&gt;https://www.youtube.com/watch?v=EbyUsf_jUjk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blogs.scientificamerican.com/cross-check/bayes-s-theorem-what-s-the-big-deal/&quot;&gt;https://blogs.scientificamerican.com/cross-check/bayes-s-theorem-what-s-the-big-deal/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://my.ilstu.edu/~gcramsey/StatOtherPro.html&quot;&gt;http://my.ilstu.edu/~gcramsey/StatOtherPro.html&lt;/a&gt; joke #92&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stats.stackexchange.com/questions/22/bayesian-and-frequentist-reasoning-in-plain-english&quot;&gt;https://stats.stackexchange.com/questions/22/bayesian-and-frequentist-reasoning-in-plain-english&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Adding Database Constraints Using the `rein` Gem</title>
      <link>http://localhost:8080/articles/rein-constraints/</link>
      <pubDate>Mon, 27 Mar 2017 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/rein-constraints/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;https://github.com/nullobject/rein&quot;&gt;rein&lt;/a&gt; is a gem for adding database constraints
in rails migrations. It’s always been possible to set
these up using execute calls in the migration, but rein
makes it look rails-y.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Letting your database manage constraints is often a great
idea. I’m not a huge fan of the rails-way of letting the
application layer manage all relationships between data.
My main concerns with this are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A developer cannot look
at the database and understand the meanings of all the
data it contains. A prime example of this is using rails
enumerations to store integers that have a meaning to
the application. &lt;/li&gt;
&lt;li&gt;Letting the application manage this for you locks you
in to rails, but you really want flexibility in terms of
what technology you want to implement the application in.
If you were to need to add another service with access to
the database, it would need to duplicate the management of
any information it needs access to. The could be a real
pain point when using any other technology than rails (and
even if the other app was in rails). Adding constraints in
the database eases this issue, as regardless of what 
technology is used on the application layer, you will have
guarantees of your data’s consistency from the database.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So let’s take a look at a sample migration using rein,
and what limitations it puts on the application layer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class CreateBooks &amp;lt; ActiveRecord::Migration
  def up
    create_enum_type :binding, [&amp;#39;hardcover&amp;#39;, &amp;#39;softcover&amp;#39;]
    create_table :books
    add_column :books, :name, :string
    add_column :books, :description, :string
    add_column :books, :binding, :binding, :default =&amp;gt; &amp;#39;hardcover&amp;#39;
    add_column :books, :publication_month, :int

    add_numericality_constraint :books, :publication_month,
      greater_than_or_equal_to: 1
  end

  def down
    drop_enum_type :binding
    drop_table :books
  end
end&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will set up a new type called &lt;code&gt;binding&lt;/code&gt;, and a
books table with a numericality constraint on its
publication month field. Let’s see what happens when
we try to save some data that the database doesn’t
like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;irb(main):001:0&amp;gt; b = Book.new
=&amp;gt; #&amp;lt;Book id: nil, name: nil, description: nil, binding: &amp;quot;hardcover&amp;quot;, publication_month: nil&amp;gt;
irb(main):002:0&amp;gt; b.publication_month = -1; b.save
ActiveRecord::StatementInvalid: PG::CheckViolation: ERROR:  new row for relation &amp;quot;books&amp;quot; violates check constraint &amp;quot;books_publication_month&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And with the enum type, you see something similar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;b.binding = &amp;#39;none&amp;#39;; b.save!
ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR:  invalid input value for enum binding: &amp;quot;none&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is great! We can’t save this data to the database. Now,
ideally we would set up validations that mirror these
constraints so that we can handle this data gracefully. Further than
this, we can use a rails enum  in the model:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;enum :binding, {
  &amp;#39;hardcover&amp;#39; =&amp;gt; &amp;#39;hardcover&amp;#39;,
  &amp;#39;paperback&amp;#39; =&amp;gt; &amp;#39;paperback&amp;#39;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will give us methods like &lt;code&gt;book.hardcover?&lt;/code&gt;, &lt;code&gt;book.paperback!&lt;/code&gt;,
scopes like &lt;code&gt;Book.hardcover&lt;/code&gt; and do all of our validations. It’s a
very effective pairing.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>My first slack bot</title>
      <link>http://localhost:8080/articles/my-first-slack-bot/</link>
      <pubDate>Wed, 14 Sep 2016 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/my-first-slack-bot/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I am still working on picking up some &lt;a href=&quot;http://elixir-lang.org/&quot;&gt;elixir&lt;/a&gt;, so when a coworker mentioned
that writing a &lt;a href=&quot;https://api.slack.com/bot-users&quot;&gt;Slack bot&lt;/a&gt; is cool, I decided to give that a try.
&lt;a href=&quot;https://slack.com/&quot;&gt;Slack&lt;/a&gt; is a bit easier to work with than IRC because the communication is done in
JSON so you can skip a step in message parsing.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The login process for a slack bot is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Authenticate over HTTP using your bot’s token.&lt;/li&gt;
&lt;li&gt;Open a websocket connection using the socket url returned in 1.&lt;/li&gt;
&lt;li&gt;Communicate using JSON over the socket.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each of these steps required importing a library (&lt;code&gt;:httpotion&lt;/code&gt;, &lt;code&gt;&amp;quot;meh/elixir-socket&amp;quot;&lt;/code&gt;, and &lt;code&gt;:poison&lt;/code&gt;).
This is a bit of a departure from go where the standard library has HTTP and JSON support, and
there’s an &lt;a href=&quot;https://godoc.org/golang.org/x/net/websocket&quot;&gt;x-package for websockets&lt;/a&gt;. But everything
worked well. It’s three external dependencies instead of two.&lt;/p&gt;
&lt;p&gt;Elixir does have a &lt;a href=&quot;https://hex.pm/&quot;&gt;package repository&lt;/a&gt;, so it’s way ahead of go in that regard.&lt;/p&gt;
&lt;p&gt;You can take a look at &lt;a href=&quot;https://github.com/rbwendt/elixir-slack-bot&quot;&gt;my slack bot here&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>The World's Simplest IRC Bot - Again</title>
      <link>http://localhost:8080/articles/the-worlds-simplest-irc-bot-again/</link>
      <pubDate>Wed, 14 Sep 2016 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/the-worlds-simplest-irc-bot-again/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I was talking to a colleague who was expounding about the coolness of &lt;a href=&quot;http://elixir-lang.org/&quot;&gt;elixir&lt;/a&gt;. So 
I thought I should give it a try. In the spirit of doing something non-trivial to learn a new tool,
I decided to port over the IRC bot I’ve been working on in go and ruby (which passes my bar for
non-triviality).&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can check it out &lt;a href=&quot;https://github.com/rbwendt/elixir-irc-bot&quot;&gt;here&lt;/a&gt;. It does the same super-simple (but
easily extensible) bot behaviour of replying to a specific salutation.&lt;/p&gt;
&lt;p&gt;Elixir seems pretty nice. It’s syntax is clearly influenced by ruby, which is great. It
is familiar enough that you want to be able to pick it up. But once you dig in a little bit you start
finding that nothing is quite what you’d expect. I ended up feeling a bit like I was coding a hybrid
of go and ruby. That was great because those are what I’ve been working on exclusively for the past
eighteen months (ignoring inevitable forays into JS). &lt;/p&gt;
&lt;p&gt;The error messages are pretty helpful, definitely less onerous than those in go. And I didn’t hit any head-wall situations. So far it has been very
developer friendly. The online documentation is good, but there doesn’t seem to be as much on google or stack
overflow as I’m used to seeing in most other languages. I’d love to keep working in elixir if I ever get the
chance.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>The World's Simplest IRC Bot</title>
      <link>http://localhost:8080/articles/the-worlds-simplest-irc-bot/</link>
      <pubDate>Wed, 31  Aug 2016 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/the-worlds-simplest-irc-bot/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I saw an article on twitter about &lt;a href=&quot;https://blog.openshift.com/running-irc-bot-ruby-openshift-v3/&quot;&gt;writing an IRC bot in ruby&lt;/a&gt;. It piqued
my interest because of nostalgia and because I’m a slack curmudgeon. I 
believe that IRC has value. I never actually got around to trying the 
&lt;a href=&quot;https://github.com/cinchrb/cinch&quot;&gt;cinch&lt;/a&gt; gem that the article recommends, although if I ever need
to do anything serious in this realm it wil be the first  tool I turn to.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Instead I found an article about writing a &lt;a href=&quot;http://kevin.glowacz.info/2009/03/simple-irc-bot-in-ruby.html&quot;&gt;really simple ruby class for a
bot&lt;/a&gt;. It never really
occurred to me how simple the actual connection part of IRC is, so after playing 
around with this code for an hour or two I decided to port it to Go.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/rbwendt/an-irc-bot&quot;&gt;What I came up with&lt;/a&gt; is an extremely &lt;a href=&quot;https://github.com/rbwendt/an-irc-bot/blob/master/irc_connection/irc_connection.go&quot;&gt;simple
connection struct&lt;/a&gt;
that wraps a tcp socket with some metadata, and allows for injection of a message handler, while maintaining
the &lt;code&gt;PING&lt;/code&gt; / &lt;code&gt;PONG&lt;/code&gt; keep-alives on its own.&lt;/p&gt;
&lt;p&gt;I spent at least twenty minutes trying to figure out why this wasn’t working before
realizing &lt;code&gt;fmt.Println&lt;/code&gt; puts in a line break, while &lt;code&gt;fmt.Fprintf&lt;/code&gt; does not. Don’t trust
your debugging output too much.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;(c *IrcConnection)&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Say&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(msg &lt;span class=&quot;keyword&quot;&gt;string&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt; {
    fmt.Println(msg)
    fmt.Fprintf(c.conn, fmt.Sprintf(&lt;span class=&quot;string&quot;&gt;&quot;%s\n&quot;&lt;/span&gt;, msg))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For an afternoon project, I like how neat and compartmentalized it is, excusing the
natural verbosity of Go. If I ever put more time into this, I’d like to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Add tests&lt;/em&gt;. I wavered on this because at the end of the day it has to connect to a 
real IRC server so I did all my development against that. Sorry freenode. But it 
would be pretty easy to make an IrcConnection interface, craft a dummy version with
a buffer I can control, and use that to test that things like &lt;code&gt;PONG&lt;/code&gt; work correctly.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Factor code more&lt;/em&gt;. For example, I could definitely use a separate method for all the handshake
messages done during connection.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Change &lt;code&gt;Run&lt;/code&gt; to work in a goroutine&lt;/em&gt;, and make a separate message handler that allows
user input. That would turn this into a single channel IRC client application, which
would not be the least cool thing in the world.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That’s it. Just another fun little side project I thought I would share.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Designing Models for 3D Printing in openSCAD</title>
      <link>http://localhost:8080/articles/3d-printing/</link>
      <pubDate>Thu, 07 Apr 2016 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/3d-printing/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;My work (&lt;a href=&quot;http://twg.ca&quot;&gt;TWG&lt;/a&gt;) has a 3D printer for employees to play with and use. Sometime
last summer I downloaded some train tracks from thingiverse and printed them for my son to play
with. He loves the custom tracks dearly. He’s always excited to visit my work to 
see what a coworker called “the toy factory”. And often he will ask me to print him something
while I’m at work. So I get a lot of emotional reward from using this machine.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Thomas and Friends (based on the books by Rev. Audrey) has a line of toys called “wooden
railway”. The tracks are an ad hoc standard, and work with many different brands including
Brio (my favourite), imaginarium, Melissa and Doug, and (for the most part) Ikea. You can
find lots of designs for &lt;a href=&quot;https://www.thingiverse.com/tag:brio&quot;&gt;brio compatible tracks on thingiverse&lt;/a&gt;.
Seemingly all kids love these.&lt;/p&gt;
&lt;p&gt;Unfortunately for parents, there are also Thomas “Take ‘n Play” trains which are about 70% of the size
of the wooden railway models. The engines and rolling stock don’t fit on the same track, and the track connectors
are incompatible. I accidentally bought my boy a Take ‘n Play engine
once, and my son received a track set as a gift from a grandparent. This was quite a limited set that
didn’t offer much room for creativity.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/3d-printing/take1.jpg&quot; alt=&quot;the set&quot;&gt;&lt;/p&gt;
&lt;p&gt;My son enjoyed it, but he asked me to print tracks that would work for this system.
I checked thingiverse and google and could find none. This provided the challenge I needed to design and
make my own 3D models.&lt;/p&gt;
&lt;p&gt;I chose to use &lt;a href=&quot;http://www.openscad.org/&quot;&gt;openSCAD&lt;/a&gt; for modelling. I was reading a comparison of different
modelling software and it said that openSCAD has &lt;code&gt;for&lt;/code&gt; loops, and I was sold. I love a good &lt;code&gt;for&lt;/code&gt; loop.&lt;/p&gt;
&lt;p&gt;openSCAD has three primitives and extrudable polygon support, as well as several object transformations like
skewing and resizing. It also supports &lt;code&gt;module&lt;/code&gt; which works similar to a function call and allows you to
repeat groupings of commands to repeat code and make it more readable. With these tools you can build up more 
complex designs.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/3d-printing/app.png&quot; alt=&quot;What openSCAD looks like&quot;&gt;&lt;/p&gt;
&lt;p&gt;Designing the object was an interesting process. At first I built a simple version of the object with 
primitives and hard-coded dimension values, which I measured with a micrometer. My next step was to
factor common variables and move objects and transformations out into modules.&lt;/p&gt;
&lt;p&gt;Because I generally have at least a few lines of code in my blog posts, here’s a simple module that
defines the center rails for my track design:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module center_rails(offset, rail_width, length, depth) {
    translate([offset,0,1]) {
        cube([rail_width, length, depth], center=true);
    }

    translate([-offset,0,1]) {
        cube([rail_width, length, depth], center=true);
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can see the &lt;a href=&quot;https://github.com/rbwendt/take-n-play-straight-track&quot;&gt;whole code in a github repo&lt;/a&gt;,
or &lt;a href=&quot;http://www.thingiverse.com/thing:1477289&quot;&gt;get this object on thingiverse&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/3d-printing/train.jpg&quot; alt=&quot;train&quot;&gt;&lt;/p&gt;
&lt;p&gt;Through this process I learned that what you measure with a ruler isn’t necessarily what you need
to print to have a working model. I created about eight prototype pieces before I had compatible male
and female connectors. In my first attempt, I used the same measurements for each, but this didn’t work 
because the connectors need a little bit of space to slide past one another. It was a really fun process
and I’m very much looking forward to showing these to my son tomorrow.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Playing with Vue.js</title>
      <link>http://localhost:8080/articles/playing-with-vue-js/</link>
      <pubDate>Sun, 03 Apr 2016 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/playing-with-vue-js/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;A coworker recently filled my ear with praise for &lt;a href=&quot;http://vuejs.org/&quot;&gt;vue.js&lt;/a&gt;. 
I’m always eager to try new frameworks, and the benefits over angular
(namely performance and simplicity) sound really promising. I haven’t 
had a chance to develop anything serious with this, but my initial
attempt was exhilirating.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I saw a link to the &lt;a href=&quot;https://xkcd.com/json.html&quot;&gt;xkcd api&lt;/a&gt; in a &lt;a href=&quot;https://twitter.com/cecycorrea/status/715918793898270720&quot;&gt;tweet&lt;/a&gt;
the other day, and decided to try it out with vue.js. I don’t really enjoy
the comic strip, but it’s a publicly availably API that isn’t totally
boring. So… what the hell. Why not?&lt;/p&gt;
&lt;p&gt;Vue.js template code looks a lot like angular. So here’s my 
simple template:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;    &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;app&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;v-on:click&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;previous&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;symbol&quot;&gt;&amp;amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;v-on:click&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;next&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;symbol&quot;&gt;&amp;amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;v-if&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;data.img&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;{{ data.img }}&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt; {{ data.safe_title }} &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;
          {{ data.transcript }}
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt; {{ number }} / 1600 &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt; {{ error }}
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;template&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’m impressed by how little code gets this running. A good chunk of my
code is native run-of-the-mill XMLHttpRequest boilerplate:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;      vm = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Vue({
        &lt;span class=&quot;attr&quot;&gt;el&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'#app'&lt;/span&gt;,
        &lt;span class=&quot;attr&quot;&gt;data&lt;/span&gt;: {
          &lt;span class=&quot;attr&quot;&gt;number&lt;/span&gt;: &lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;,
          &lt;span class=&quot;attr&quot;&gt;data&lt;/span&gt;: {}
        },
        &lt;span class=&quot;attr&quot;&gt;methods&lt;/span&gt;: {
          &lt;span class=&quot;attr&quot;&gt;previous&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
            &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.number --
            &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.fetchData()
          },
          &lt;span class=&quot;attr&quot;&gt;next&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
            &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.number ++
            &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.fetchData()
          },
          &lt;span class=&quot;attr&quot;&gt;fetchData&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
            &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; xhr = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; XMLHttpRequest()
            &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; self = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;
            xhr.open(&lt;span class=&quot;string&quot;&gt;'GET'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'xkcdpass.php?n='&lt;/span&gt; + self.number)
            xhr.onload = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
              self.data = &lt;span class=&quot;built_in&quot;&gt;JSON&lt;/span&gt;.parse(xhr.responseText)
            }
            xhr.send()
          }
        }
      })
      vm.fetchData()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can try it out &lt;a href=&quot;http://benwendt.ca/xkcdexplore.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Relevance Graphing</title>
      <link>http://localhost:8080/articles/relevance-graph/</link>
      <pubDate>Sat, 26 Mar 2016 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/relevance-graph/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Last month a workmate and I flew down to San Francisco to go to elasticon.&lt;/p&gt;
&lt;p&gt;I attended an interesting talk given two employees of &lt;a href=&quot;http://giantoak.com&quot;&gt;Giant Oak&lt;/a&gt;.
Giant Oak does contracting for government agencies to try to solve social problems. I
am not sure if this is their motto but one of the speakers say that they “see the people
behind the data,” which sounds really cool.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Their work involves things like trying to answer questions about war insurgency, or 
terrorism. They don’t work on computer science questions, but social science
questions. Some of their analytical tools for social scientists are built on ElasticSearch.&lt;/p&gt;
&lt;p&gt;One of the tools used to reveal data poaching data was a graph
representation of their data.&lt;/p&gt;
&lt;p&gt;The graph databases I’ve used, like neo4j, allow a user to define
entities and create a graph by defining relationships between those
entities. But elasticsearch has a new feature coming out in version 5 for
auto generating edges based on relevance. A user will not have to manually
set up these relations when creating data. One of the developers
Giant Oak made an elasticsearch reporting tool, similar to kibana,
called &lt;a href=&quot;https://github.com/giantoak/unicorn&quot;&gt;unicorn&lt;/a&gt;.
It is built for revealing relationships between records in the database, and
uses existing elasticsearch technology.&lt;/p&gt;
&lt;p&gt;As opposed to standard graph databases
where the relationships on the edges of graphs are explicitly
defined, this tool generates entity relationships based on relevance. So
when different documents share attributes, they are linked.&lt;/p&gt;
&lt;p&gt;This work has led to over 100 arrests of human
traffickers and poachers. Revealing the stories hidden the data,
can be fun or informative, or even save people’s lives and make the
world a better place.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Fun with `fork`</title>
      <link>http://localhost:8080/articles/fun-with-fork/</link>
      <pubDate>Mon, 01 Feb 2016 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/fun-with-fork/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;In &lt;code&gt;irb&lt;/code&gt;,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;fork&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now typing &lt;code&gt;exit&lt;/code&gt; will not work because your keystrokes might go to either
the parent process or the forked child process. I found it to be impossible
to get the characters &lt;code&gt;exit&lt;/code&gt; to coherently all go to the same process.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Getting a sum of durations in rails</title>
      <link>http://localhost:8080/articles/ruby-duration-sum/</link>
      <pubDate>Sun, 31 Jan 2016 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/ruby-duration-sum/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;For my “I had trouble finding this on google” series, here’s a 
solution I found to getting a total duration from a collection
of objects with durations stored as &lt;code&gt;Time&lt;/code&gt; objects.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;total_duration = durations.reduce(Time.gm(&lt;span class=&quot;number&quot;&gt;2000&lt;/span&gt;)) &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;|total, time|&lt;/span&gt;
  total += time.to_i
&lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are two little tricks happening here. The first is that 
durations are stored as a time of day on January 1st, 2000, so
we use that as the reduce seed. The second thing is that the 
&lt;code&gt;Time&lt;/code&gt; class defines addition for integer objects, but not for
other times, so you have to convert your duration to an integer
first.&lt;/p&gt;
&lt;p&gt;No rocket science here, but a couple little quirks that made it
a little harder to add two times together than I expected.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Brainfuck Interpreter</title>
      <link>http://localhost:8080/articles/brainfuck-interpreter/</link>
      <pubDate>Fri, 22 Jan 2016 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/brainfuck-interpreter/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Every programmer has some level of interest in knowing how to write a language. I’ve always 
wanted to tinker with this level of software development, but even after years of development
experience you never really get exposed to this stuff because what’s already there generally
just works. On top of that, it’s a somewhat complex process involving several steps with
intimidating terminology.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;But the best defense against not knowing how to do something that you want to do is always 
jumping in and doing it. So, with help from an excellent article by Ben Johnson about &lt;a href=&quot;https://blog.gopheracademy.com/advent-2014/parsers-lexers/&quot;&gt;writing
your own parser in go&lt;/a&gt;, I dived in.
This article has easily digestable definitions and example of the different steps of the parsing
and lexing process.&lt;/p&gt;
&lt;h2 id=&quot;lexing&quot;&gt;lexing&lt;/h2&gt;
&lt;p&gt;Lexing is the process of converting a steam of structured text, like the programming language
code you want to interpret, into a list of pre-defined symbols. So you could take a string like
&lt;code&gt;&amp;quot;while&amp;quot;&lt;/code&gt; and convert it into something your compiler / interpreter undestands as a &lt;code&gt;while&lt;/code&gt; symbol.&lt;/p&gt;
&lt;h2 id=&quot;parsing&quot;&gt;parsing&lt;/h2&gt;
&lt;p&gt;Parsing is taking a bunch of symbols generated by the lexer and turning them into a structure 
that your compiler / interpreter will be able to work with. So it takes something like
&lt;code&gt;[IF, CONDITION(true), START_BLOCK, PRINT, STRING(hello), END_BLOCK]&lt;/code&gt; and changes it into
something more like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if condition(true)
  print &amp;#39;hello&amp;#39;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;choosing-brainfuck&quot;&gt;choosing brainfuck&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Brainfuck&quot;&gt;brainfuck&lt;/a&gt; is an esoteric programming language,
meaning no one uses it for any serious work. I chose to write an interpreter for it because
it has only eight commands, and it is very conceptually simple. Most compilers and
interpreters will parse lexed tokens into something called an “abstract syntax tree”. Since
brainfuck is so simple, I was able to skip this step and make a &lt;code&gt;struct&lt;/code&gt; with methods that
act on the &lt;code&gt;struct&lt;/code&gt;s state in place. Brainfuck also has lots of example code online that was
very useful for writing my tests (more on that later). Brainfuck is also a fairly minimal
language that is still Turing-complete, which is a desirable quality to have in a language
for which you are writing an interpreter.&lt;/p&gt;
&lt;p&gt;Brainfuck is also really nice because it doesn’t have a context aware grammar, meaning that
you don’t have to keep track of when you’re in string. There are no variables or functions,
so you don’t need a symbol table. In all, it’s a simple featureless language perfect for
this kind of task.&lt;/p&gt;
&lt;p&gt;What I came up with probably wouldn’t get a great grade if it was what I handed in for what
I assume might be the first assignment in a compilers course, but I learned a lot that was
worthwhile, so I’ll discuss those findings here.&lt;/p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;implementation&lt;/h2&gt;
&lt;p&gt;Implementation was actually a bit easier than I expected. With a bit of help writing the lexer
from the aforementioned blog post, I was able to create a &lt;code&gt;Machine&lt;/code&gt; struct with a series of 
operations. Each of these operates on the state of the struct, which contains operations,
current operation, a sequence of bytes that can be manipulated, a reference to the current
byte being processed, input, and output:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-golang&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; Machine &lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; {
    Position &lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt;
    Operation &lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt;
    State []&lt;span class=&quot;keyword&quot;&gt;byte&lt;/span&gt;
    Output []&lt;span class=&quot;keyword&quot;&gt;byte&lt;/span&gt;
    Input *bytes.Reader
    Operations []Token
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The operation array is filled with a collection of tokens, and as the machine moves through the
operations, each token is mapped to a method that operates on the object. Most of these alter the
&lt;code&gt;State&lt;/code&gt; slice or position in some way, except for the control flow methods &lt;code&gt;[&lt;/code&gt; and &lt;code&gt;]&lt;/code&gt;, which
read the current position and jump to the corresponding bracket if the value at the current position
is zero or non-zero respectively. &lt;/p&gt;
&lt;p&gt;Because there is only one control flow operation in brainfuck, and with it being so simple, I saw this
as an opportunity to “get my feet wet” writing an interpreter that doesn’t use an abstract syntax tree.
It’s a barrier to learning about this technology that I didn’t have to hurdle to get this working. My
implementation just does the control flow manually in place on the &lt;code&gt;Machine&lt;/code&gt; struct by moving the 
&lt;code&gt;Position&lt;/code&gt; value.&lt;/p&gt;
&lt;h2 id=&quot;tests&quot;&gt;tests&lt;/h2&gt;
&lt;p&gt;The last time I was playing with brainfuck, I wrote a &lt;a href=&quot;http://benwendt.ca/articles/converting-to-bf/&quot;&gt;string to brainfuck “compiler”&lt;/a&gt;
that gave me some simple test cases for outputting text. It’s also pretty easy to test the input case:
just pre-populate your input, then output it, and assert equality. &lt;/p&gt;
&lt;p&gt;I was able to find many “Hello world” examples for brainfuck. The first time I put one in it dropped my
interpreter into an infinite loop. Resolving this was definitely that hardest part of this process.
I ended up just mentally thinking through what would be wrong until I figured it out: it was an off by one error. Once that worked, some of my “hello world” tests almost worked! I was very excited.
But they had an unexpected character with byte code 10 at the end. I was pulling my hair out. A quick check
of my ascii table answered the question. Whoever coded these put a new line at the end of the output.&lt;/p&gt;
&lt;p&gt;(Thinking back I remember seeing &lt;code&gt;CHAR(10)&lt;/code&gt; or similar in an old SQLServer database eons ago, but I must
have erased that experience from memory.)&lt;/p&gt;
&lt;p&gt;After that I put in a program on esolangs.org listed as “&lt;a href=&quot;https://esolangs.org/wiki/Brainfuck#Hello.2C_World.21&quot;&gt;often triggers interpreter bugs&lt;/a&gt;.”
It worked on the first go and I was happy.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;conclusion&lt;/h2&gt;
&lt;p&gt;It’s an interpreter no one will ever use for a language that no one ever uses, but I’m happy with it. I
learned enough and had a pleasant experience, with only one ruined sleep. I think esolangs offer a great
opportunity for writing interpreters because the languages generally don’t have many commands. Maybe I will
try writing one for &lt;a href=&quot;https://esolangs.org/wiki/Piet&quot;&gt;Piet&lt;/a&gt; next.&lt;/p&gt;
&lt;p&gt;You can check out &lt;a href=&quot;https://github.com/rbwendt/bfhopefully&quot;&gt;my brainfuck interpreter on github&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Republished</title>
      <link>http://localhost:8080/articles/republished/</link>
      <pubDate>Fri, 27 Nov 2015 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/republished/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;My old “attach a camera to your RC car” tutorial has been republished into a “&lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/1680450441/boingboing&quot;&gt;1-2-3 Projects&lt;/a&gt;” anthology by maker media.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/republished/1.jpg&quot; alt=&quot;make 1-2-3 Projects&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/republished/2.jpg&quot; alt=&quot;make 1-2-3 Projects&quot;&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Restricting post-deployment tasks to certain roles using capistrano</title>
      <link>http://localhost:8080/articles/restricting/</link>
      <pubDate>Mon, 09 Nov 2015 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/restricting/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;If you need to only run some tasks on a certain subset of servers in your inventory, first add a role to your inventory file deploy/whatever-environment.rb:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;server &lt;span class=&quot;string&quot;&gt;'1.2.3.4'&lt;/span&gt;, &lt;span class=&quot;symbol&quot;&gt;roles:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;%w{my_role}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can set up your command to run in one of your tasks in &lt;code&gt;deploy.rb&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;on roles(&lt;span class=&quot;symbol&quot;&gt;:my_role&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
  within release_path &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
    with &lt;span class=&quot;symbol&quot;&gt;rails_env:&lt;/span&gt; fetch(&lt;span class=&quot;symbol&quot;&gt;:rails_env&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
      execute &lt;span class=&quot;symbol&quot;&gt;:bundle&lt;/span&gt;, &lt;span class=&quot;symbol&quot;&gt;:exec&lt;/span&gt;, &lt;span class=&quot;symbol&quot;&gt;:&lt;span class=&quot;string&quot;&gt;'script/bend-girders.py'&lt;/span&gt;&lt;/span&gt;, args, &lt;span class=&quot;symbol&quot;&gt;:all&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Converting strings to bf code</title>
      <link>http://localhost:8080/articles/converting-to-bf/</link>
      <pubDate>Sat, 10 Oct 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/converting-to-bf/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I was playing around with the &lt;a href=&quot;https://en.wikipedia.org/wiki/Brainfuck&quot;&gt;esoteric programming language brainfuck&lt;/a&gt;. I found that it was pretty time consuming writing out strings of text using only increments and decrements of the data pointer.&lt;/p&gt;
&lt;p&gt;So I decided to write a bf string maker in go. Code generation is pretty important in go, so it is fun to generate code for another language using go.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; (
    &lt;span class=&quot;string&quot;&gt;&quot;os&quot;&lt;/span&gt;
    &lt;span class=&quot;string&quot;&gt;&quot;fmt&quot;&lt;/span&gt;
    &lt;span class=&quot;string&quot;&gt;&quot;strings&quot;&lt;/span&gt;
)

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;&lt;/span&gt; {
    buffer := &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;len&lt;/span&gt;(os.Args) &amp;gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; {
        in := strings.Join(os.Args[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;:], &lt;span class=&quot;string&quot;&gt;&quot; &quot;&lt;/span&gt;)
        runes := []&lt;span class=&quot;keyword&quot;&gt;rune&lt;/span&gt;(in)
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; _, &lt;span class=&quot;keyword&quot;&gt;rune&lt;/span&gt; := &lt;span class=&quot;keyword&quot;&gt;range&lt;/span&gt; runes {
            current := &lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;rune&lt;/span&gt;)
            symbols := &lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; current &amp;gt; buffer {
                symbols = strings.Repeat(&lt;span class=&quot;string&quot;&gt;&quot;+&quot;&lt;/span&gt;, current - buffer)
            } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
                symbols = strings.Repeat(&lt;span class=&quot;string&quot;&gt;&quot;-&quot;&lt;/span&gt;, buffer - current)
            }
            fmt.Println(symbols + &lt;span class=&quot;string&quot;&gt;&quot;.&quot;&lt;/span&gt;)
            buffer = current
        }
    } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
        fmt.Println(&lt;span class=&quot;string&quot;&gt;&quot;no params&quot;&lt;/span&gt;)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The idea is that any acscii string (a collection of runes in go) can be translated to bf by playing with the bf data pointer. This pointer starts at zero, and we just walk through the string moving the pointer: increments are + commands and decrements are - commands. The . operator outputs the current data pointer.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Search Index Internals</title>
      <link>http://localhost:8080/articles/search-internals/</link>
      <pubDate>Sat, 26 Sep 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/search-internals/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Watch me discuss how a search engine works.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;iframe src=&quot;https://player.vimeo.com/video/140575093&quot; width=&quot;500&quot; height=&quot;281&quot; frameborder=&quot;0&quot; webkitallowfullscreen mozallowfullscreen allowfullscreen&gt;&lt;/iframe&gt;

</description>
    </item>
    <item>
      <title>A Random Password Generator</title>
      <link>http://localhost:8080/articles/random-password/</link>
      <pubDate>Thu, 03 Sep 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/random-password/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I’ve posted a &lt;a href=&quot;https://github.com/rbwendt/golang-password-gen&quot;&gt;random password generator&lt;/a&gt; I’ve written to github. The impetus for this was me accidentally posting one of my passwords in an open chat channel at work. I decided it was time to change my password. &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I found a python library that generated xkcd style passwords a while back, which I can no longer find. So, as part of my ongoing quest to have fun and program a lot I decided to whip one up myself.&lt;/p&gt;
&lt;p&gt;Two glaring improvements are:&lt;/p&gt;
&lt;h1 id=&quot;the-dictionary-path-is-currently-hard-coded-for-ubuntu-which-probably-north-of-90-of-people-are-using-by-now-but-it-would-be-great-to-make-it-configurable-for-people-stuck-on-older-machines-&quot;&gt;The dictionary path is currently hard-coded for ubuntu, which probably north of 90% of people are using by now, but it would be great to make it configurable for people stuck on older machines.&lt;/h1&gt;
&lt;h1 id=&quot;i-d-like-a-text-munging-option-that-would-randomly-replace-the-occasional-x-with-a-and-the-odd-s-with-a-and-so-on-&quot;&gt;I’d like a “text-munging” option that would randomly replace the occasional x with a %, and the odd s with a $, and so on.&lt;/h1&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
</description>
    </item>
    <item>
      <title>NLP Essentials</title>
      <link>http://localhost:8080/articles/nlp-essentials/</link>
      <pubDate>Fri, 17 Jul 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/nlp-essentials/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Here’s a talk I gave at work.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;iframe src=&quot;https://player.vimeo.com/video/133815185&quot; width=&quot;500&quot; height=&quot;281&quot; frameborder=&quot;0&quot; webkitallowfullscreen mozallowfullscreen allowfullscreen&gt;&lt;/iframe&gt;

</description>
    </item>
    <item>
      <title>A Comparison of Stemmers</title>
      <link>http://localhost:8080/articles/a-comparison-of-stemmers/</link>
      <pubDate>Tue, 07 Jul 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/a-comparison-of-stemmers/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;The goal of stemming is to reduce derived forms of a word to something that could be a root form. For example a possible stem of &amp;#8220;lighting&amp;#8221; or &amp;#8220;lighted&amp;#8221; is &amp;#8220;light&amp;#8221;. This is generally done by applying a list of fairly simple rules to a word, possibly recursively, until the algorithm is done and a root form is returned.
&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/a-comparison-of-stemmers/1.png&quot; alt=&quot;1.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;There are several reasons for stemming a word. The primary concern is to increase the recall of a search index. The most basic case here is the handling of plurals; a user generally expects the same result when searching for &amp;#8220;nachos dip&amp;#8221; as when they search for &amp;#8220;nacho dip.&amp;#8221; But recall can be improved in other cases as well, for example a user searching for &amp;#8220;democracy&amp;#8221; is probably also interested in results for &amp;#8220;democratic&amp;#8221;. Another concern is reducing index size; this can increase search speed and reduce storage usage (both of these are good for reducing costs).&lt;/p&gt;
&lt;p&gt;But stemming is an inexact science. Most stemming algorithms don&amp;#8217;t attempt to extract morphological information about the word to determine the stem, so unrelated terms can be conflated. While working at an old employer, one of my colleagues found an interesting issue caused by imprecise stemming. A client was complaining that a search for &amp;#8220;rug&amp;#8221; was matching most of the items in their catalog, even though most of them didn&amp;#8217;t have anything to do with rugs. It turns out that, as an outdoor gear supplier, the client had the term &amp;#8220;rugged&amp;#8221; in most of the product descriptions on their site. The solution to this issue was to tweak the stemmer used for this index.&lt;/p&gt;
&lt;p&gt;This example shows that, while stemming can improve recall, it reduces precision. As software developers, we are used to making these trade offs. The effectiveness of a given stemming method will vary depending on your corpus. So it&amp;#8217;s important to learn the ins and outs of your stemmers, and learn when to tweak them.&lt;/p&gt;
&lt;p&gt;I found an interesting &lt;a href=&quot;http://www.gossamer-threads.com/lists/lucene/java-user/173564&quot;&gt;comparison of stemmer results&lt;/a&gt; in an elastic search user forum.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Original&lt;/th&gt;
&lt;th&gt;porter&lt;/th&gt;
&lt;th&gt;kstem&lt;/th&gt;
&lt;th&gt;minStem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;country&lt;/td&gt;
&lt;td&gt;countri&lt;/td&gt;
&lt;td&gt;country&lt;/td&gt;
&lt;td&gt;country&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;run&lt;/td&gt;
&lt;td&gt;run&lt;/td&gt;
&lt;td&gt;run&lt;/td&gt;
&lt;td&gt;run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;runs&lt;/td&gt;
&lt;td&gt;run&lt;/td&gt;
&lt;td&gt;runs&lt;/td&gt;
&lt;td&gt;run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;running&lt;/td&gt;
&lt;td&gt;run&lt;/td&gt;
&lt;td&gt;running&lt;/td&gt;
&lt;td&gt;running&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;read&lt;/td&gt;
&lt;td&gt;read&lt;/td&gt;
&lt;td&gt;read&lt;/td&gt;
&lt;td&gt;read&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reading&lt;/td&gt;
&lt;td&gt;read&lt;/td&gt;
&lt;td&gt;reading&lt;/td&gt;
&lt;td&gt;reading&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reader&lt;/td&gt;
&lt;td&gt;reader&lt;/td&gt;
&lt;td&gt;reader&lt;/td&gt;
&lt;td&gt;reader&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;association&lt;/td&gt;
&lt;td&gt;associ&lt;/td&gt;
&lt;td&gt;association&lt;/td&gt;
&lt;td&gt;association&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;associate&lt;/td&gt;
&lt;td&gt;associ&lt;/td&gt;
&lt;td&gt;associate&lt;/td&gt;
&lt;td&gt;associate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;listing&lt;/td&gt;
&lt;td&gt;list&lt;/td&gt;
&lt;td&gt;list&lt;/td&gt;
&lt;td&gt;listing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;water&lt;/td&gt;
&lt;td&gt;water&lt;/td&gt;
&lt;td&gt;water&lt;/td&gt;
&lt;td&gt;water&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;watered&lt;/td&gt;
&lt;td&gt;water&lt;/td&gt;
&lt;td&gt;water&lt;/td&gt;
&lt;td&gt;watered&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sure&lt;/td&gt;
&lt;td&gt;sure&lt;/td&gt;
&lt;td&gt;sure&lt;/td&gt;
&lt;td&gt;sure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;surely&lt;/td&gt;
&lt;td&gt;sure&lt;/td&gt;
&lt;td&gt;surely&lt;/td&gt;
&lt;td&gt;surely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fred&amp;#8217;s&lt;/td&gt;
&lt;td&gt;fred&amp;#8217;&lt;/td&gt;
&lt;td&gt;fred&amp;#8217;s&lt;/td&gt;
&lt;td&gt;fred&amp;#8217;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;roses&lt;/td&gt;
&lt;td&gt;rose&lt;/td&gt;
&lt;td&gt;rose&lt;/td&gt;
&lt;td&gt;rose&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;You can see here that Porter earns its aggressive reputation. Aggressiveness leads to more matches, but also more false matches.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Setting a custom response header in a Gin response</title>
      <link>http://localhost:8080/articles/gin-header/</link>
      <pubDate>Wed, 03 Jun 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/gin-header/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I’m using &lt;a href=&quot;https://github.com/gin-gonic/gin&quot;&gt;Gin Gonic&lt;/a&gt; on a project I’m working on at work these days. I was in a bit of a pickle where I had to specify a response body that I already had as a string, but I needed to put the correct content type header on the response (meaning I couldn’t use the built in .String or .JSON methods.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I had to dig around a bit in the source code a bit to figure this one out. So, If you want to set a custom response header on a gin response, do it like this&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;imports (
    &lt;span class=&quot;string&quot;&gt;&quot;github.com/gin-gonic/gin&quot;&lt;/span&gt;
    &lt;span class=&quot;string&quot;&gt;&quot;github.com/gin-gonic/gin/render&quot;&lt;/span&gt;
)
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;whatever&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;&lt;/span&gt; {
    ...
    c.Render(
        http.StatusOK, render.Data{
            ContentType: &lt;span class=&quot;string&quot;&gt;&quot;application/json&quot;&lt;/span&gt;,
            Data:        []&lt;span class=&quot;keyword&quot;&gt;byte&lt;/span&gt;(response),
        })
    ...
}&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>An interesting example of using a closure for memoization</title>
      <link>http://localhost:8080/articles/an-interesting-example-of-using-a-closure-for-memoization/</link>
      <pubDate>Thu, 14 May 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/an-interesting-example-of-using-a-closure-for-memoization/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Long ago I wrote about the &lt;a href=&quot;http://benwendt.ca/blog/2013/07/24/a-demonstration-of-the-usefulness-of-memoization-in-lua/&quot;&gt;benefits of memoization&lt;/a&gt;. It&amp;#8217;s a simple idea: a time vs. space trade off. Trade time in CPU for space in memory. A pretty classic example is the massive speed benefit you can get while calculating the Fibonacci sequence by saving values you have already found. (The naive recursive approach recalculates values an exponential number of times.) It&amp;#8217;s a toy example but it definitely exhibits the power of the technique.
&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I have to learn &lt;a href=&quot;http://golang.org/&quot;&gt;Go&lt;/a&gt; for an upcoming project at work. I&amp;#8217;m excited about it, and I&amp;#8217;ve been starting out by working through the &lt;a href=&quot;https://tour.golang.org/&quot;&gt;Go Tour&lt;/a&gt; lesson series. I was pretty interested to see &lt;a href=&quot;https://tour.golang.org/moretypes/22&quot;&gt;slide 22 in the more types lesson&lt;/a&gt;, an exercise instructing the reader to write a function that calculates Fibonacci numbers using a closure. The way this is set up gently nudges the reader toward writing an answer that uses memoization through a closure.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s what I came up with:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;fmt&quot;&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;// fibonacci is a function that returns&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;// a function that returns an int.&lt;/span&gt;
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;fibonacci&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;int&lt;/span&gt;&lt;/span&gt; {
    a := [&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;]&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt;{&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;}
    b := &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
    f := &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;int&lt;/span&gt;&lt;/span&gt; {
        val := a[b]
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; val == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; {
            val = a[b - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] + a[b - &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;]
            a[b] = val
        }
        b ++
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; val
    }
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; f
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;&lt;/span&gt; {
    f := fibonacci()
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; i := &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; i &amp;amp;lt; &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;; i++ {
        fmt.Println(f())
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I really liked the way that the solution uses a built in array and a closure to accomplish memoization. It&amp;#8217;s very clean. Coming from doing a lot of PHP it&amp;#8217;s nice to see because a fairly standard way of implementing this technique in that language is to use the &lt;code&gt;static&lt;/code&gt; keyword which always felt a bit hacky (on a side note, you could do this in PHP, but you&amp;#8217;d need the &lt;code&gt;use&lt;/code&gt; feature on the closure, which I am also not a fan of). The same technique would definitely work in javascript as well. It&amp;#8217;s a welcome addition to my toolset.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Using a motion detector with the espruino pico</title>
      <link>http://localhost:8080/articles/using-a-motion-detector-with-the-espruino-pico/</link>
      <pubDate>Wed, 06 May 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/using-a-motion-detector-with-the-espruino-pico/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;This is a simple modification of the &lt;a href=&quot;http://www.espruino.com/Motion+Sensing+Lights&quot;&gt;espruino motion detector&lt;/a&gt; tutorial to work with the espruino pico. The main difference is which pins things are hooked up to, and my not using the LED strips, which I don&amp;#8217;t own (hint hint, Santa).&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;First off, using your espruino pico, set it up at the standard left-most position on the bread board.&lt;/p&gt;
&lt;p&gt;Then wire up as follows:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;HC-SR501&lt;/th&gt;
&lt;th&gt;Espruino&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;VCC&lt;/td&gt;
&lt;td&gt;VBAT (5v)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OUT&lt;/td&gt;
&lt;td&gt;A7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GND&lt;/td&gt;
&lt;td&gt;GND&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The main difference here is that we use &lt;code&gt;A7&lt;/code&gt; instead of &lt;code&gt;A1&lt;/code&gt; because on the pico, &lt;code&gt;A1&lt;/code&gt; doesn&amp;#8217;t come with a pin soldered on, so you can&amp;#8217;t just plug a jumper into the bread board.&lt;/p&gt;
&lt;p&gt;The code is basically the same as the tutorial, with the updates of removing the LED strip code and updating &lt;code&gt;A1&lt;/code&gt; to &lt;code&gt;A7&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; timeout;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;lightsOn&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
  digitalWrite(LED1, &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;);
  &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;'light on '&lt;/span&gt; + (&lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;().toString()));
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;lightsOff&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
  digitalWrite(LED1,&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;);
}

setWatch(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;e&lt;/span&gt;) &lt;/span&gt;{
  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (timeout!==&lt;span class=&quot;literal&quot;&gt;undefined&lt;/span&gt;)
    clearTimeout(timeout);
  &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
    lightsOn();
  }
  timeout = setTimeout(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    timeout = &lt;span class=&quot;literal&quot;&gt;undefined&lt;/span&gt;;
    lightsOff();
  }, &lt;span class=&quot;number&quot;&gt;1500&lt;/span&gt;);
}, A7, { &lt;span class=&quot;attr&quot;&gt;repeat&lt;/span&gt;:&lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;edge&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;rising&quot;&lt;/span&gt; });&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This thing is so much fun to toy around with. I had fun putting together the &lt;a href=&quot;http://www.espruino.com/Pico+Piano&quot;&gt;pico piano&lt;/a&gt; project too.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Playing with my espruino pico</title>
      <link>http://localhost:8080/articles/playing-with-my-espruino-pico/</link>
      <pubDate>Sat, 02 May 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/playing-with-my-espruino-pico/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;About a year ago I had a little fun using an &lt;a href=&quot;http://benwendt.ca/blog/2014/02/07/getting-started-with-espruino/&quot;&gt;espruino&lt;/a&gt;. I recently &amp;#8220;kick-started&amp;#8221; their more recent product the espruino pico. This one did really well on kickstarter and I got some great &amp;#8220;boost&amp;#8221; rewards like an LCD screen and some relays. It should be fun to see what this thing can do.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/playing-with-my-espruino-pico/setup.jpg&quot; alt=&quot;setup espruino pico&quot;&gt;&lt;/p&gt;
&lt;p&gt;Below is a simple program that makes a spot spin around on the LED display that came with the kit. Variables like &lt;code&gt;A5&lt;/code&gt; or &lt;code&gt;B10&lt;/code&gt; represent pins on the board, which can be seen in the &lt;a href=&quot;http://www.espruino.com/Pico&quot;&gt;pico schematic&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This makes use of the &lt;a href=&quot;http://www.espruino.com/PCD8544&quot;&gt;PCD8544 driver&lt;/a&gt;, which works with the &lt;a href=&quot;http://www.espruino.com/Graphics&quot;&gt;espruino graphics library&lt;/a&gt;. This is loosely based on some of the examples on the pico site.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;A5.write(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;); &lt;span class=&quot;comment&quot;&gt;// GND&lt;/span&gt;
A7.write(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;); &lt;span class=&quot;comment&quot;&gt;// VCC&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;// http://www.espruino.com/SPI&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; spi = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; SPI();
spi.setup({ &lt;span class=&quot;attr&quot;&gt;sck&lt;/span&gt;:B1, &lt;span class=&quot;attr&quot;&gt;mosi&lt;/span&gt;:B10 });

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; height = &lt;span class=&quot;number&quot;&gt;48&lt;/span&gt;; &lt;span class=&quot;comment&quot;&gt;// these are the resolution of the Nokia 5110.&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; width = &lt;span class=&quot;number&quot;&gt;88&lt;/span&gt;;

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; rate = &lt;span class=&quot;number&quot;&gt;140&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; theta = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; cx = width / &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; cy = height / &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt; - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; r = cy - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; rx = r * &lt;span class=&quot;number&quot;&gt;1.6&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; dTheta = &lt;span class=&quot;number&quot;&gt;0.1&lt;/span&gt;;

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; g = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;PCD8544&quot;&lt;/span&gt;).connect(spi,B13,B14,B15, &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
  setInterval(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    g.clear();
    theta += dTheta;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; x = cx + rx * &lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.cos(theta);
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; y = cy + r * &lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.sin(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt; * theta);
    g.drawLine(x + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, y, x + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, y + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;);
    g.drawLine(x, y + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, x + &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, y + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;);
    g.flip();
  }, rate);
});&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Using Angular-UI and Restangular To Interact With WordPress API</title>
      <link>http://localhost:8080/articles/using-angular-ui-and-restangular-to-interact-with-wordpress-api/</link>
      <pubDate>Fri, 24 Apr 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/using-angular-ui-and-restangular-to-interact-with-wordpress-api/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;At my new job I&amp;#8217;ve been working a fair bit with &lt;a href=&quot;https://github.com/angular-ui/ui-router&quot;&gt;ui router&lt;/a&gt;. It&amp;#8217;s a fun library and I thought I would brush up a bit and have some fun practice interfacing it with the &lt;a href=&quot;https://wordpress.org/plugins/json-rest-api/&quot;&gt;wordpress api plugin&lt;/a&gt; through &lt;a href=&quot;https://github.com/mgonto/restangular&quot;&gt;restangular&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So let&amp;#8217;s take a quick look at how this very simple process works.&lt;/p&gt;
&lt;p&gt;First, I installed all the dependencies using bower.&lt;/p&gt;
&lt;p&gt;Next, set up a simple index.html file:&lt;/p&gt;
&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html ng-app=&quot;blog&quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;script src=&quot;bower_components/angular/angular.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;bower_components/angular-ui-router/release/angular-ui-router.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;bower_components/lodash/lodash.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;bower_components/restangular/dist/restangular.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;app.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div&amp;gt;
&amp;lt;div ui-view&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;

&lt;p&gt;And here&amp;#8217;s app.js:&lt;/p&gt;
&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;var myApp = angular.module('blog', ['ui.router', 'restangular']);
myApp.config(function($stateProvider, $urlRouterProvider, RestangularProvider) {

RestangularProvider.setBaseUrl('http://benwendt.ca/blog/wp-json/')

$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
  url: '/',
  templateUrl: 'posts.html',
  resolve: {
    posts:function(Restangular) {
      return Restangular.all('posts').getList()
     }
  },
  controller($scope, $sce, $filter, posts) {
    $scope.posts = posts
  }
})
}).filter('unsafe', function($sce) { return $sce.trustAsHtml })


&lt;/pre&gt;

&lt;p&gt;The two main takeaways here are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Set up the base api url using &lt;code&gt;RestangularProvider.setBaseUrl()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use ui-router&amp;#8217;s &lt;code&gt;$stateProvider&lt;/code&gt; to set up which template, api requests, and controller to use.
Also I&amp;#8217;m using a nifty filter I found for running &lt;code&gt;&amp;lt;A href=&amp;quot;http://stackoverflow.com/a/19705096/973810&amp;quot;&amp;gt;$sce.trustAsHtml&amp;lt;/a&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And the template is super simple, but here it is:&lt;/p&gt;
&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;div ng-repeat=&quot;post in posts&quot;&amp;gt;
  &amp;lt;div class=&quot;post&quot;&amp;gt;
    &amp;lt;h1 ng-bind-html=&quot;post.title | unsafe&quot;&amp;gt;&amp;lt;/h1&amp;gt;
    &amp;lt;div ng-bind-html=&quot;post.content | unsafe&quot;&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;So, in conclusion, these technologies make it really easy to pull data off a json api and throw it into the browser. It&amp;#8217;s wonderful.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Finding Semordnilaps</title>
      <link>http://localhost:8080/articles/finding-semordniaps/</link>
      <pubDate>Fri, 17 Apr 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/finding-semordniaps/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;My wife recently developed an interest in semordnilaps, so I thought I would take a stab at writing a script that will find some. What I came up with finds a subset of all two word to two word semordnilaps. Generally you don&amp;#8217;t consider whitespace and punctuation in palindromes and semordnilaps, so this code doesn&amp;#8217;t either.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;It turns out that filtering out proper names vastly reduces the number of semordnilaps found, and I didn&amp;#8217;t really appreciate the ones which contained proper names anyway, so I took those out.&lt;/p&gt;
&lt;pre class=&quot;brush: ruby; title: ; notranslate&quot; title=&quot;&quot;&gt;words = {}
File.open(&quot;/usr/share/dict/words&quot;) do |file|
  file.each do |line|
    if line.length &amp;gt; 4 # don't accept one or two letter words.
      word = line.strip
      next if word.downcase != word # proper names have capitals, exclude those.
      words[word.downcase.gsub(/[^a-z]/, '')] = true
    end
  end
end

words.each do |word1, k|  
  p_words = {}
  word_finds = 0

  word1 = word1.reverse
  first_words = []
  # skip words that when reversed don't match the ending of another word.
  (1 .. (word1.length - 1)).each do |i|
    if words[word1[0..i]]
      first_words &amp;lt;&amp;lt; word1[0..i]
    end
  end
  if first_words.count == 0
    next
  end

  words.each do |word2, k|  
    two_words = word1 + word2.reverse    
    (2 .. two_words.length).each do |i|
       if words[two_words[0..(i - 1)]] &amp;&amp; words[two_words[i..(two_words.length-1)]]
         p_words[two_words[0..(i - 1)] + ' ' + two_words[i..(two_words.length-1)]] = word2 + ' ' + word1.reverse
         word_finds += 1
       end
    end
  end
  if word_finds &amp;gt; 0
    puts p_words
  end
end

&lt;/pre&gt;

&lt;p&gt;And this gives you some great semordnilaps like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;#8220;cite catnip&amp;#8221;=&amp;gt;&amp;#8221;pint acetic&amp;#8221;&lt;/li&gt;
&lt;li&gt;&amp;#8220;stub aloof&amp;#8221;=&amp;gt;&amp;#8221;fool abuts&amp;#8221;&lt;/li&gt;
&lt;li&gt;&amp;#8220;tubas gals&amp;#8221;=&amp;gt;&amp;#8221;slags abut&amp;#8221;&lt;/li&gt;
&lt;li&gt;&amp;#8220;sane railed&amp;#8221;=&amp;gt;&amp;#8221;deli arenas&amp;#8221;&lt;/li&gt;
&lt;li&gt;&amp;#8220;reis trailed&amp;#8221;=&amp;gt;&amp;#8221;deli artsier&amp;#8221;&lt;/li&gt;
&lt;li&gt;&amp;#8220;diva lived&amp;#8221;=&amp;gt;&amp;#8221;devil avid&amp;#8221;&lt;/li&gt;
&lt;li&gt;&amp;#8220;stabs faced&amp;#8221;=&amp;gt;&amp;#8221;decafs bats&amp;#8221;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All told, I got a 2.7MB text file. I am sure that there are better ones in there.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>PHP’s traits vs. ruby’s modules: Battle of the mix-ins</title>
      <link>http://localhost:8080/articles/phps-traits-vs-rubys-modules-battle-of-the-mix-ins/</link>
      <pubDate>Thu, 09 Apr 2015 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/phps-traits-vs-rubys-modules-battle-of-the-mix-ins/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;A mixin is a class-like language construct meant to add functionality to another class. They are not meant to stand on their own, and generally speaking they cannot. Mixins can be used to give different classes the same interface. Mixins can be compared to multiple inheritence in what they let you accomplish, but they don&amp;#8217;t work the same way. Rather than inheriting from multiple classes, you mix them in. (Hence the obvious name.)&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;PHP, always a late-comer feature-wise in terms of object oriented goodness, got traits in version 5.4.0. Traits allow the developer to add methods to a class with the &lt;code&gt;use&lt;/code&gt; statement, like this:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;interface Vehicle {
    public function move();
}

trait Wheel {
    public function move() {
        // roll.
    }
}

class Bicycle implements Vehicle {
    use Wheel;
}

$bicycle = new Bicycle;

$bicycle-&amp;gt;move();

&lt;/pre&gt;

&lt;p&gt;At this point, Bicycle will implement Vehicle. Even though you a &lt;code&gt;move&lt;/code&gt; method is not explicitly specified in the class, the call on the object will work. Traits can only be assigned to a class in the class definition.&lt;/p&gt;
&lt;p&gt;Ruby supports mixins using modules. That can be done like this:&lt;/p&gt;
&lt;pre class=&quot;brush: ruby; title: ; notranslate&quot; title=&quot;&quot;&gt;module Wheel
  def move
    # roll.
  end
end

class Bicycle
  include Wheel
end

bicycle = Bicycle.new

bicycle.move
&lt;/pre&gt;

&lt;p&gt;At this point, an instance of &lt;code&gt;Bicycle&lt;/code&gt; will have a &lt;code&gt;roll&lt;/code&gt; method, but the class &lt;code&gt;Bicycle&lt;/code&gt; will not. This is because mixins get attached to the instance, not the class. This is the opposite of what happens in PHP.&lt;/p&gt;
&lt;p&gt;In this way, PHP&amp;#8217;s trait design differs fairly substantially from ruby&amp;#8217;s mixin. In my mind, this is most likely because in PHP ideally all of your classes implement an interface. This is a nice feature because it helps a lot with static analysis. Ruby, on the other hand, doesn&amp;#8217;t have interfaces as a language construct; classes do, of course, have interfaces but no part of the interpreter is enforcing signatures like the &lt;code&gt;implements&lt;/code&gt; keyword makes PHP enforce method signatures. The standard argument against enforcing interfaces is that two unrelated classes can share a signature, so the signature doesn&amp;#8217;t really tell you anything about the class.&lt;/p&gt;
&lt;p&gt;In the end, neither approach is the ideal case for adding functionality to classes. I can&amp;#8217;t think of an object oriented language that doesn&amp;#8217;t support dependency injection. As long as you can set properties on an object and call methods, you should be able to do dependency injection. Developers should prefer composition over inheritance. It prevents code coupling: better to couple to a class in one decision than have coupled classes throughout your code base. Inheritance should be a fall-back, but you should always try to implement composition first.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>A Whitespace + Punctuation Tokenizer</title>
      <link>http://localhost:8080/articles/a-whitespace-punctuation-tokenizer/</link>
      <pubDate>Fri, 13 Feb 2015 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/a-whitespace-punctuation-tokenizer/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;In my previous post, I discussed some tokenization techniques and mentioned that a whitespace-only tokenizer will make tokens that are sub-optimal for indexing. I also mentioned that a simple solution to this is created a whitespace + punctuation tokenizer.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So let&amp;#8217;s take a look at how that might work.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; re

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;whitespace_punctuation_tokenize&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(str, punctuation = &lt;span class=&quot;string&quot;&gt;&quot;[\.,\&quot;']&quot;&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;
    tokens = re.split(punctuation + &lt;span class=&quot;string&quot;&gt;&quot;*\s+&quot;&lt;/span&gt; + punctuation + &lt;span class=&quot;string&quot;&gt;&quot;*&quot;&lt;/span&gt;, str)
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (tokens[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]):
        tokens[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] = re.sub(&lt;span class=&quot;string&quot;&gt;&quot;^&quot;&lt;/span&gt; + punctuation + &lt;span class=&quot;string&quot;&gt;&quot;+&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;, tokens[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;])
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (tokens[&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;]):
        tokens[&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;] = re.sub(punctuation + &lt;span class=&quot;string&quot;&gt;&quot;+$&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;, tokens[&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;])
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; tokens&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You would run that code with something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;str = &lt;span class=&quot;string&quot;&gt;&quot;&quot;&quot;'abc-123' is a cool one. It's far and away the
    ring-tossingest toy this year.&quot;&quot;&quot;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;print&lt;/span&gt; whitespace_punctuation_tokenize(str)
&lt;span class=&quot;keyword&quot;&gt;print&lt;/span&gt; whitespace_punctuation_tokenize(str, &lt;span class=&quot;string&quot;&gt;&quot;[\.,\&quot;]&quot;&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From this, you would see output like the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[&amp;#8216;abc-123&amp;#8242;, &amp;#8216;is&amp;#8217;, &amp;#8216;a&amp;#8217;, &amp;#8216;cool&amp;#8217;, &amp;#8216;one&amp;#8217;, &amp;#8220;It&amp;#8217;s&amp;#8221;, &amp;#8216;far&amp;#8217;, &amp;#8216;and&amp;#8217;, &amp;#8216;away&amp;#8217;, &amp;#8216;the&amp;#8217;, &amp;#8216;ring-tossingest&amp;#8217;, &amp;#8216;toy&amp;#8217;, &amp;#8216;this&amp;#8217;, &amp;#8216;year&amp;#8217;]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[&amp;#8220;&amp;#8216;abc-123&amp;#8242;&amp;#8221;, &amp;#8216;is&amp;#8217;, &amp;#8216;a&amp;#8217;, &amp;#8216;cool&amp;#8217;, &amp;#8216;one&amp;#8217;, &amp;#8220;It&amp;#8217;s&amp;#8221;, &amp;#8216;far&amp;#8217;, &amp;#8216;and&amp;#8217;, &amp;#8216;away&amp;#8217;, &amp;#8216;the&amp;#8217;, &amp;#8216;ring-tossingest&amp;#8217;, &amp;#8216;toy&amp;#8217;, &amp;#8216;this&amp;#8217;, &amp;#8216;year&amp;#8217;] &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here we see a function that does a regular expression split on an input string and accepts a configurable parameter of which characters to consider as punctuation. In this way, we can specify how want tokens to be delimited with a bit more granular control.&lt;/p&gt;
&lt;p&gt;The function makes this split, then corrects and leading punctuation on the first element and any trailing punctuation on the last element. At this point you would have higher quality tokens to pass into your analysis chain.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Android Game Development</title>
      <link>http://localhost:8080/articles/android-game-development/</link>
      <pubDate>Fri, 13 Feb 2015 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/android-game-development/</guid>
      <author></author>
      <description>&lt;p&gt;Wanting to expand my horizons a little, I decided to give android game development a try. I quickly prototyped a game in canvas + js called &lt;a href=&quot;http://localhost:8080/protet.html&quot;&gt;protect your thing&lt;/a&gt; to give myself an idea of how it would work on the android platform. This was a natural prototyping choice for me because I&amp;#8217;ve been working with JS code daily for at least a decade now, and I love playing with canvas. (I frequently will whip up a &lt;a href=&quot;http://localhost:8080/flashy32.html&quot;&gt;little graphic&lt;/a&gt; in canvas reminiscent of my early QBasic coding days, but flavoured by the years of studying mathematics that followed).&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://benwendt.ca/blog/wp-content/uploads/2015/02/Screenshot_2015-02-13-22-22-57.png&quot;&gt;&lt;img src=&quot;http://benwendt.ca/blog/wp-content/uploads/2015/02/Screenshot_2015-02-13-22-22-57-576x1024.png&quot; alt=&quot;Screenshot_2015-02-13-22-22-57&quot; width=&quot;576&quot; height=&quot;1024&quot; class=&quot;alignnone size-large wp-image-450&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://benwendt.ca/blog/wp-content/uploads/2015/02/Screenshot_2015-02-13-22-23-56.png&quot;&gt;&lt;img src=&quot;http://benwendt.ca/blog/wp-content/uploads/2015/02/Screenshot_2015-02-13-22-23-56-576x1024.png&quot; alt=&quot;Screenshot_2015-02-13-22-23-56&quot; width=&quot;576&quot; height=&quot;1024&quot; class=&quot;alignnone size-large wp-image-451&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With a prototype of a &lt;span title=&quot;I'm not a gamer&quot;&gt;slightly enjoyable&lt;/span&gt; game complete, I set out on the path of android game development. Sereptitiously, the android graphics library has a &lt;a href=&quot;http://developer.android.com/reference/android/graphics/Canvas.html&quot;&gt;canvas&lt;/a&gt; class that enabled all the stuff I&amp;#8217;m used to being able to do in js. Beyond that, I looked up how to make an event loop and started hacking. The result is half-decent. It&amp;#8217;s not a AAA game, and it has a few warts, but it was an excellent learning experience and I&amp;#8217;m happy and proud to have made it. Check it out:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a style=&quot;font-size:24px&quot; href=&quot;https://play.google.com/store/apps/details?id=ca.benwendt.protectyourthing&amp;#038;hl=en&quot;&gt;Protect Your Thing!&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Basic Concepts of a Search Index</title>
      <link>http://localhost:8080/articles/basic-concepts-of-a-search-index/</link>
      <pubDate>Fri, 30 Jan 2015 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/basic-concepts-of-a-search-index/</guid>
      <author>Ben Wendt</author>
      <description>&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;A text index is a way to store information about textual data to improve ease of retrieval. The basic idea is to store the information in such a way that it is possible to retrieve what you are looking for without doing a full scan of the data. A text index will do this by storing information about each indexed word separately. So where in the raw text you might have a text field with the contents &amp;#8220;this is a description&amp;#8221;, a full text index would store information about each individual word separately, so it would store a form of &amp;#8220;this&amp;#8221;, &amp;#8220;is&amp;#8221;, &amp;#8220;a&amp;#8221;, and &amp;#8220;description&amp;#8221;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;There are two motivations to using an indexing engine: speed and quality of results. Generally speaking, sifting through a massive amount of text is a slow process. (We discussed that earlier on this blog when we looked at the &lt;a href=&quot;http://localhost:8080/blog/?p=265&quot;&gt;Knuth-Morris-Pratt algorithm&lt;/a&gt;). There are also numerous intricacies of language that can trip up a naive search that a search index can work around.&lt;/p&gt;
&lt;p&gt;So let&amp;#8217;s dive in, shall we?&lt;/p&gt;
&lt;h3 id=&quot;tokenizing&quot;&gt;Tokenizing&lt;/h3&gt;
&lt;p&gt;The first stage of generating an index is to split the source text up into individual words or phrases. This stage is called &amp;#8220;tokenizing.&amp;#8221; A simple way of tokenizing text is the &amp;#8220;white space tokenizing&amp;#8221; technique, which basically splits text up by whitespace, as I did with &amp;#8220;this is a description&amp;#8221; earlier. But punctuation is a pitfall here. Without considering punctuation, tokenizing a phrase like &amp;#8220;this is a pizza, and the pizza is good&amp;#8221; would create separate and distinct tokens for each &amp;#8220;pizza,&amp;#8221; and &amp;#8220;pizza&amp;#8221;. This is generally not a desired outcome, so most tokenization algorithms will allow for a whitespace tokenizer that also accepts a list of punctuation characters. &lt;/p&gt;
&lt;p&gt;There is a lot more room for nuance in tokenization: for example what if you want to use a whitespace+punctuation tokenizer, but you have IP addresses that you want to be searchable in your data? Then tokenizing something like &amp;#8220;The IP was 127.0.0.1&amp;#8243; would yield separate tokens for &amp;#8220;127&amp;#8221;, &amp;#8220;0&amp;#8221; and &amp;#8220;1&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Another possible issue is that you may want multiple terms to be treated like single terms. For example, records that contain the phrase &amp;#8220;magnetic resonance imaging&amp;#8221; should be treated as more relevant in searches when the terms all appear together than when they are apart. There are different ways to approach this problem, but one is &amp;#8220;NGram&amp;#8221; tokenizing (this is a fancy way of saying that a given number N of adjacent terms will each be treated as one token).&lt;/p&gt;
&lt;p&gt;The myriad nuances of tokenization are why industry leading search indices allow a developer to define their own tokenizing routine.&lt;/p&gt;
&lt;h3 id=&quot;analysis&quot;&gt;Analysis&lt;/h3&gt;
&lt;p&gt;Fully featured search indices like ElasticSearch or Solr will allow a software developer to define an analysis chain on their indexed data. The analysis chain is a way of normalizing the language that will be indexed so that related terms will be able to match after the index has been created.&lt;/p&gt;
&lt;p&gt;Once a collection of tokens is generated, further processing is generally desired before storing indexed terms. If a user searches for &amp;#8220;skeet shooting&amp;#8221;, records with &amp;#8220;skeet shoot&amp;#8221; should probably match. Generally this issue is tackled by storing &amp;#8220;stemmed&amp;#8221; words in the index, where the &amp;#8220;stem&amp;#8221; of a word is generally a form of the word with any suffixes removed. A popular stemmer is the &amp;#8220;&lt;a href=&quot;http://snowball.tartarus.org/texts/introduction.html&quot;&gt;Lovins Snowball stemmer&lt;/a&gt;.&amp;#8221; (I recommend reading this link; it&amp;#8217;s well-written and highly fascinating.)&lt;/p&gt;
&lt;p&gt;There are two important points to consider here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stemming is language specific. Suffixes that denote different meaning vary from language to language. And pictogram based languages are (to my knowledge) practically immune to this approach to stemming.&lt;/li&gt;
&lt;li&gt;Simple suffix removal is not a foolproof method of word stemming, for example &amp;#8220;flammable&amp;#8221; and &amp;#8220;inflammable&amp;#8221; have precisely the same meaning, but removing their suffixes leaves different stems. You wouldn&amp;#8217;t want someone using your index to search for whether a product is flammable, and find no results because it is inflammable.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The solution to the first issue is to use different stemming algorithms for different languages. The solution to the second issue is to support synonyms in the search index; if the system is aware that flammable and inflammable represent the same thing, your users will find the safety information they need even if they use the term that isn&amp;#8217;t in your data.&lt;/p&gt;
&lt;p&gt;Proper analysis is where an indexing engine will beat out a text search in terms of quality of results.&lt;/p&gt;
&lt;h3 id=&quot;storing&quot;&gt;Storing&lt;/h3&gt;
&lt;p&gt;Storing indexed data can be done in any number of ways. The important thing is that lookups should be fast. Index sizes and data concerns will determine which data structure is best. For my demo code below I am using PHP so that basically limits me to using PHP&amp;#8217;s built-in &lt;code&gt;array&lt;/code&gt; data structure as a hash map.&lt;/p&gt;
&lt;h3 id=&quot;an-example-index&quot;&gt;An example index&lt;/h3&gt;
&lt;p&gt;Here is a couple functions that create a simple index:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;file_put_contents('index.dat', serialize(createIndex($records));

/**
* @param $record array collection of records
* @return array record collection combined with indices
*/
function createIndex($record) {
    $output = ['records' =&amp;gt; $records, 'index' =&amp;gt; []];
    foreach($records as $recordKey =&amp;gt; $record) {
        $record = str_replace(array('.', ','), ' ', $record);
        $record = strtolower($record);
        $tokens = whitespaceTokenize($record);

        foreach($tokens as $token) {
            if (!isset($output['index'][$token])) {
                $output['index'][$token] = [];
            }
            $output['index'][$token][$recordKey] = 1;
        }
    }
    return $output;
}

/**
* @param $records array|string record or records to be split by white space.
* @return array tokenized collection
*/
function whitespaceTokenize($records) {
    $out = [];
    if (is_string($records)) {
        $records = [$records];
    }
    foreach($records as $record) {

        $out = array_merge($out, preg_split('/\s+/', $record));
    }
    return $out;
}
&lt;/pre&gt;

&lt;p&gt;Note how the indexer splits out terms then stores them in a hash that maps back to which record the term can be found in. This is the basic idea of a search index.&lt;/p&gt;
&lt;p&gt;And here is a quick way to read matches from the index:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;$index = unserialize(file_get_contents('index.dat'));

$keywords = strtolower($argv[1]);

$matches = array_keys($index['index'][$keywords]);
echo count($matches) . ' matches' . &quot;\n&quot;;
foreach($matches as $matchKey =&amp;gt; $match) {
    echo &quot;$match =&amp;gt; &quot; . $index['records'][$match] . &quot;\n&quot;;
}
&lt;/pre&gt;

&lt;p&gt;You will note here that I did not create a configurable punctuation + whitespace tokenizer. And in fact, none of the more advanced features I discussed earlier are implemented. This code is only meant to illustrate how an index works, not be fully featured. The basic concept here could be cleaned up, coded to a &lt;a href=&quot;https://groups.google.com/forum/#!topic/php-fig/mBP6PmG0TqU&quot;&gt;generalized storage interface&lt;/a&gt;, and then the more advanced features could be added as needed to make a functioning search index written in pure PHP. &lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;We have seen a mile-high overview of how a search index works, discussed the tokenization and analysis processes, briefly discussed storage, and seen just about the most basic working example of a search index. Search indices are a fascinating technology that empower users through services like Bing, Million Short, and Duck Duck Go to find information on the internet, but we have also identified some issues in the technology and hinted at some methods of dealing with these problems. We may take a more in-depth look at some of those solutions in a future post.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Installing VLC on an ADT-1</title>
      <link>http://localhost:8080/articles/installing-vlc-on-an-adt-1/</link>
      <pubDate>Tue, 21 Oct 2014 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/installing-vlc-on-an-adt-1/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;The ADT-1 is a neat little machine. It&amp;#8217;s very sleak and designy.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/installing-vlc-on-an-adt-1/adt-1.jpg&quot; alt=&quot;adt-1 in box&quot;&gt;&lt;/p&gt;
&lt;p&gt;I signed up for the developer version of Android TV because I&amp;#8217;d like to port a game I wrote to the platform. And Google was nice enough to send one over.&lt;/p&gt;
&lt;p&gt;But out of the box it doesn&amp;#8217;t allow streaming videos over your home network, which seems like a must for an HTPC. The user interface on the ADT-1 is pretty much locked down. Google play is limited to very few titles. So let&amp;#8217;s set up VLC.&lt;/p&gt;
&lt;p&gt;Enable USB debugging on your ADT-1. Just go into your developer settings and turn it on.
&lt;a href=&quot;https://developer.android.com/tv/adt-1/index.html#faq&quot;&gt;Connect to the ADT-1 using &lt;code&gt;adb&lt;/code&gt;&lt;/a&gt;. I did this over my network with the following command: &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;adb connect {ip}:4321&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://nightlies.videolan.org/build/android-armv7/&quot;&gt;Download a VLC nightly APK.&lt;/a&gt;
Install the apk using &lt;code&gt;adb&lt;/code&gt;: &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;adb install *.apk&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This might take a minute. My wi-fi is as slow as molasses.&lt;/li&gt; &lt;/p&gt;
&lt;p&gt;If you want to be fancy and start VLC over the network. This can be done in two stages. First, shell in to your ADT-1: &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;adb shell&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/mstorsjo/vlc-android/blob/master/Makefile&quot;&gt;Now you can load VLC with &lt;code&gt;am&lt;/code&gt;&lt;/a&gt;: &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;am start -n org.videolan.vlc/org.videolan.vlc.gui.MainActivity&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or if you&amp;#8217;re into doing things the easy way, you to Apps under settings and you should see VLC.&lt;/p&gt;
&lt;p&gt;And that&amp;#8217;s it. Now if you walk over to your ADT-1 you will see the bright orange face of VLC smiling at you. Have a nice day!&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Canvas Spinny</title>
      <link>http://localhost:8080/articles/canvas-spinny/</link>
      <pubDate>Thu, 04 Sep 2014 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/canvas-spinny/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;This will make a nice semi transparent spinner for you.
&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; spinnyCanvas = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;left, top&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; conti = &lt;span class=&quot;literal&quot;&gt;false&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; self = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.stop = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.conti = &lt;span class=&quot;literal&quot;&gt;false&lt;/span&gt;;
    }
    &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.start = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(self.conti)
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!self.conti) {
            self.conti = &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;;
            draw();
        }
    }
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; dim = &lt;span class=&quot;number&quot;&gt;48&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; canvas = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createElement(&lt;span class=&quot;string&quot;&gt;'canvas'&lt;/span&gt;)
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; context = canvas.getContext(&lt;span class=&quot;string&quot;&gt;'2d'&lt;/span&gt;)
    &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.body.appendChild(canvas)
    canvas.height= dim
    canvas.width = dim
    canvas.theta = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
    canvas.dtheta = &lt;span class=&quot;number&quot;&gt;-.09&lt;/span&gt;
    canvas.style.position = &lt;span class=&quot;string&quot;&gt;'fixed'&lt;/span&gt;
    canvas.style.top = top + &lt;span class=&quot;string&quot;&gt;'px'&lt;/span&gt;
    canvas.style.left= left + &lt;span class=&quot;string&quot;&gt;'px'&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; draw = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        canvas.width = canvas.width
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; r = dim / &lt;span class=&quot;number&quot;&gt;16&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; x, y
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; i, L = &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; i &amp;amp;lt; L; i++) {
            x = dim / &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt; + dim * &lt;span class=&quot;number&quot;&gt;.3&lt;/span&gt; * &lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.sin(canvas.theta + i * &lt;span class=&quot;number&quot;&gt;1.1&lt;/span&gt; * &lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.PI / L)
            y = dim / &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt; + dim * &lt;span class=&quot;number&quot;&gt;.3&lt;/span&gt; * &lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.cos(canvas.theta + i * &lt;span class=&quot;number&quot;&gt;1.1&lt;/span&gt; * &lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.PI / L)
            context.beginPath()
            context.fillStyle = &lt;span class=&quot;string&quot;&gt;&quot;rgba(128,128,128,&quot;&lt;/span&gt; + (&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; - i / L) + &lt;span class=&quot;string&quot;&gt;&quot;)&quot;&lt;/span&gt;
            context.arc(x, y, r, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.PI, &lt;span class=&quot;literal&quot;&gt;false&lt;/span&gt;)
            context.fill()
            context.closePath()
        }
        canvas.theta += canvas.dtheta
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (self.conti) {    
            requestAnimationFrame(draw)
        }
    }
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;
}

&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Emulating the Javascript With Statement in PHP</title>
      <link>http://localhost:8080/articles/emulating-the-javascript-with-statement-in-php/</link>
      <pubDate>Tue, 01 Jul 2014 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/emulating-the-javascript-with-statement-in-php/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with&quot;&gt;Javascript has a &lt;code&gt;with&lt;/code&gt; statement&lt;/a&gt; that you probably shouldn&amp;#8217;t use. I&amp;#8217;ve never seen it used non-jokingly in JavaScript in the past decade or so, other than the occasional &lt;a href=&quot;http://jsfiddle.net/ondras/hYfN3/&quot; title=&quot;Tiny Excel-like app in vanilla JS&quot;&gt;clever hack&lt;/a&gt;. &lt;a href=&quot;http://msdn.microsoft.com/en-ca/library/wc500chb.aspx&quot;&gt;Visual Basic also has a &lt;code&gt;with&lt;/code&gt; statement&lt;/a&gt;, and I did see it used a fair bit in that realm, back in the day. In my experience it&amp;#8217;s not something that developers are clamoring for.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The main advantage of using &lt;code&gt;with&lt;/code&gt; is not having to retype the name of the object you are working with repeatedly in a block of code. The drawback is that this harms readability; an assortment of new variables are presented in the block, and the scope has metaphorically changed gears. A big part of writing readable code is maintaining a good flow and preventing &lt;a href=&quot;http://en.wikipedia.org/wiki/Human_multitasking&quot;&gt;context switches&lt;/a&gt;. Because of this, &lt;code&gt;with&lt;/code&gt; use is rare.&lt;/p&gt;
&lt;p&gt;However, suppose you did want to implement some PHP code where you didn&amp;#8217;t want repeated array or object references and you didn&amp;#8217;t want to pollute your scope with a call to &lt;code&gt;extract&lt;/code&gt;. You could use the following abomination:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;call_user_func(function () use ($withVariable) {
    if (is_object($withVariable)) {
        $withVariable= get_object_vars($withVariable);
    }
    extract($withVariable);
    // do stuff.
});
&lt;/pre&gt;

&lt;p&gt;The cumbersome &lt;code&gt;use&lt;/code&gt; keyword and its white-list approach to close scope make this a difficult and cumbersome block of code. PHP doesn&amp;#8217;t allow immediate execution of anonymous functions directly, so we have to pass the function to &lt;code&gt;call_user_func&lt;/code&gt;. In other languages, &lt;code&gt;with&lt;/code&gt; will bring variables from the outer scope into the &lt;code&gt;with&lt;/code&gt; scope, but that will not happen here unless you add the desired variables into to &lt;code&gt;use&lt;/code&gt; arguments.&lt;/p&gt;
&lt;p&gt;In conclusion, &lt;code&gt;with&lt;/code&gt; is a misfeature and attempting to implement it in PHP is neither very fruitful or elegant.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Migrating SQLite for PHP 5.2 to PHP 5.4 on Ubuntu</title>
      <link>http://localhost:8080/articles/migrating-sqlite-for-php-5-2-to-php-5-4-on-ubuntu/</link>
      <pubDate>Fri, 13 Jun 2014 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/migrating-sqlite-for-php-5-2-to-php-5-4-on-ubuntu/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;PHP 5.4 discontinued support for SQLite 2 databases. Updating an old legacy PHP application with a SQLite database to a new server is not very difficult.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To start off, you will need the SQLite binaries so that you can convert the database between versions:&lt;/p&gt;
&lt;pre class=&quot;brush: bash; title: ; notranslate&quot; title=&quot;&quot;&gt;sudo apt-get install sqlite sqlite3
&lt;/pre&gt;

&lt;p&gt;Now that you have the binaries installed, you can convert your version 2 SQLite database to version 3:&lt;/p&gt;
&lt;pre class=&quot;brush: bash; title: ; notranslate&quot; title=&quot;&quot;&gt;sqlite version2.db .dump | sqlite3 version3.db
&lt;/pre&gt;

&lt;p&gt;Now you will need to update your PHP script with the following translations&lt;/p&gt;
&lt;div class=&quot;clearer&quot;&gt;
  &lt;div class=&quot;move&quot;&gt;
    Old command
  &lt;/div&gt;

  &lt;div class=&quot;move&quot;&gt;
    New command
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;clearer&quot;&gt;
  &lt;div class=&quot;move&quot;&gt;
    &lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
sqlite_escape_string()
&lt;/pre&gt;
  &lt;/div&gt;

  &lt;div class=&quot;move&quot;&gt;
    &lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
SQLite3::escapeString()
&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;clearer&quot;&gt;
  &lt;div class=&quot;move&quot;&gt;
    &lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
sqlite_fetch_array($result)
&lt;/pre&gt;
  &lt;/div&gt;

  &lt;div class=&quot;move&quot;&gt;
    &lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
$result-&amp;gt;fetchArray()
&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;clearer&quot;&gt;
  &lt;div class=&quot;move&quot;&gt;
    &lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
sqlite_exec($handle, $query)
&lt;/pre&gt;
  &lt;/div&gt;

  &lt;div class=&quot;move&quot;&gt;
    &lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
$handle-&amp;gt;exec($query)
&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;clearer&quot;&gt;
  &lt;div class=&quot;move&quot;&gt;
    &lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
sqlite_query($handle, $query)
&lt;/pre&gt;
  &lt;/div&gt;

  &lt;div class=&quot;move&quot;&gt;
    &lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
$handle-&amp;gt;query($query)
&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;clearer&quot;&gt;
  &lt;div class=&quot;move&quot;&gt;
    &lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
$handle = sqlite_open($file)
&lt;/pre&gt;
  &lt;/div&gt;

  &lt;div class=&quot;move&quot;&gt;
    &lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
$handle = new SQLite3($file)
&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    <item>
      <title>A Lottery Model</title>
      <link>http://localhost:8080/articles/a-lottery-model/</link>
      <pubDate>Wed, 11 Jun 2014 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/a-lottery-model/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Having studied math in university, I am well aware that buying lottery tickets is a losing proposition. In Ontario, where I live, there is a lottery called 6/49. The rules are simple: pick 6 numbers out of 49 possibilities, if your choice matches a random choice of 6 numbers made in the draw, you win the jackpot. The probability of winning this is:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/a-lottery-model/never-tell-me-the-odds.png&quot; alt=&quot;never tell me the odds&quot;&gt;&lt;/p&gt;
&lt;p&gt;I.e. the odds are roughly one in 14 million. &lt;/p&gt;
&lt;p&gt;However, when you live in a densely populated city like Toronto, you notice that a lot of convenience stores have signs up in their windows proclaiming the jackpot winners who have bought tickets there. Generally these take the form of big banners reading something along the lines of &amp;#8220;&amp;dollar;16 million dollar ticket sold here!&amp;#8221;&lt;/p&gt;
&lt;p&gt;Each neighbourhood in the city only has so many convenience stores, each serving a neighbourhood that only has so many people buying lottery tickets, each of whom may or may not play in every draw. It was enough to make me wonder how long a given population size of occasional lottery players would take before one of their members recorded a win.&lt;/p&gt;
&lt;p&gt;So I set up a model with the following characteristics:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A configurable population size, I start with a population of 100,000, roughly the population of Guelph, which is a city near where I grew up.&lt;/li&gt;
&lt;li&gt;A configurable probability for population wide ticket buying. For the sake of my model, I chose 1/8, which is slightly more than one ticket buy per month (there are bi-weekly draws).&lt;/li&gt;
&lt;li&gt;Every week there is a draw, and 6 numbers are chosen from the 49. Every member of the population may or may not play. If they play, they also choose 6 numbers randomly from the 49, if these match, they win and the simulation ends. &lt;/ol&gt; 
Here&amp;#8217;s my PHP code that represents the model I&amp;#8217;ve described.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;meta&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getRandomChoice&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($from, $number, $min = &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;{
    $from = range($min, $from);
    $choices = [];
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; $i &amp;amp;lt; $number; $i++) {
        $index = mt_rand(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, count($from) - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;);
        $choices[] = $from[$index];
        &lt;span class=&quot;keyword&quot;&gt;unset&lt;/span&gt;($from[$index]);
        $from = array_values($from);
    }
    sort($choices);
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $choices;
}

$population = &lt;span class=&quot;number&quot;&gt;100000&lt;/span&gt;;
$playProbability = &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; / &lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;;

$match_found = &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;;
$count = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt;(!$match_found) {
    $r = getRandomChoice(&lt;span class=&quot;number&quot;&gt;49&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;6&lt;/span&gt;);
    $bought = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; $i &amp;amp;lt; $population; $i++) {

        $rand = mt_rand() / mt_getrandmax();
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($rand &amp;amp;gt; $playProbability) {
            &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;;
        }
        $s = getRandomChoice(&lt;span class=&quot;number&quot;&gt;49&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;6&lt;/span&gt;);
        $bought ++;
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($r == $s) {
            &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;match after $count draws, population member $i\n&quot;&lt;/span&gt;;
            &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; implode(&lt;span class=&quot;string&quot;&gt;&quot; &quot;&lt;/span&gt;, $r) . &lt;span class=&quot;string&quot;&gt;&quot;, &quot;&lt;/span&gt;  . implode(&lt;span class=&quot;string&quot;&gt;&quot; &quot;&lt;/span&gt;, $s) . &lt;span class=&quot;string&quot;&gt;&quot;\n&quot;&lt;/span&gt;;
            &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;;
        }

    }
    $count++;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($count % &lt;span class=&quot;number&quot;&gt;52&lt;/span&gt; == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
        $year = $count / &lt;span class=&quot;number&quot;&gt;52&lt;/span&gt;;
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;tried $count times, $bought bought, year $year.\n&quot;&lt;/span&gt;;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What I found from this was not very heartening for lottery players. It generally takes several years for even one member of the 100000 population to ever win the jackpot. But I do think that the results demonstrate why there are so many of those jackpot banners around town.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Counting sort</title>
      <link>http://localhost:8080/articles/counting-sort/</link>
      <pubDate>Thu, 08 May 2014 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/counting-sort/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I have a thing for sorting algorithms. They’re fairly accessible as far as algorithms go, and it’s always fun to look under the hood of how computers go about their business. Thinking algorithmically makes you a better programmer too.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So I was interested to see this post on hacker news about &lt;a href=&quot;http://austingwalters.com/counting-sort-in-c/&quot;&gt;count sort in C&lt;/a&gt;, and decided to implement it in languages more within my milieu.&lt;/p&gt;
&lt;h3 id=&quot;php&quot;&gt;PHP&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;count_sort&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($in)&lt;/span&gt; &lt;/span&gt;{
    $counting = array_fill(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, max($in), &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;);

    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, $l = count($in); $i &amp;amp;lt; $l; $i++) {
        $counting[$in[$i] - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]++;
    }
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, $j = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, $l = count($counting); $i &amp;amp;lt; $l; $i++) {
        &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; ($counting[$i] &amp;amp;gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
            $in[$j] = $i + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
            $counting[$i]--;
            $j++;
        }
    }

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $in;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;javascript&quot;&gt;Javascript&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;count_sort&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;a&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; i, j, l = &lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.max.apply(&lt;span class=&quot;literal&quot;&gt;null&lt;/span&gt;, a), counting = [];    
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; i &amp;amp;lt; l; i++) {
        counting[i] = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
    }
    l = a.length;

    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; i &amp;amp;lt; l; i++) {
        counting[a[i] - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]++;
    }
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, j = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, l = counting.length; i &amp;amp;lt; l; i++) {
        &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; (counting[i] &amp;amp;gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
            a[j] = i + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
            counting[i]--;
            j++;
        }
    }

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; a;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;python&quot;&gt;python&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;countsort&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(a)&lt;/span&gt;:&lt;/span&gt;
    counts = [&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] * max(a)
    l = len(a) 
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, l):
        counts[a[i] - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] += &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
    j = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
    l = len(counts)
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; range(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, l):
        &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; counts[i] &amp;amp;gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;:
            a[j] = i + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
            counts[i] -= &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
            j += &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; a&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;c&quot;&gt;c&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c-sharp&quot;&gt;static int[] countSort(int[] a) {
            int i, j, l = a.Count();
            int[] counting = new int[a.Max()];    
            for (i = 0; i &amp;amp;lt; l; i++) {
                counting[i] = 0;
            }

            for (i = 0; i &amp;amp;lt; l; i++) {
                counting[a[i] - 1]++;
            }
            for (i = 0, j = 0, l = counting.Count(); i &amp;amp;lt; l; i++) {
                while (counting[i] &amp;amp;gt; 0) {
                    a[j] = i + 1;
                    counting[i]--;
                    j++;
                }
            }

            return a;
        }&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;powershell&quot;&gt;powershell&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;Function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;countSort&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;(&lt;span class=&quot;variable&quot;&gt;$in&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt; {
    &lt;span class=&quot;variable&quot;&gt;$l&lt;/span&gt; = &lt;span class=&quot;variable&quot;&gt;$in&lt;/span&gt; | Measure &lt;span class=&quot;literal&quot;&gt;-Maximum&lt;/span&gt;
    &lt;span class=&quot;variable&quot;&gt;$l&lt;/span&gt; = &lt;span class=&quot;variable&quot;&gt;$l&lt;/span&gt;.Maximum
    &lt;span class=&quot;variable&quot;&gt;$counting&lt;/span&gt; = &lt;span class=&quot;selector-tag&quot;&gt;@&lt;/span&gt;()

    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt; = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-lt&lt;/span&gt; &lt;span class=&quot;variable&quot;&gt;$l&lt;/span&gt;; &lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt;++) {
        &lt;span class=&quot;variable&quot;&gt;$counting&lt;/span&gt; += &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
    }

    &lt;span class=&quot;variable&quot;&gt;$l&lt;/span&gt; = &lt;span class=&quot;variable&quot;&gt;$in&lt;/span&gt;.length

    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt; = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-lt&lt;/span&gt; &lt;span class=&quot;variable&quot;&gt;$l&lt;/span&gt;; &lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt;++) {
        &lt;span class=&quot;variable&quot;&gt;$counting&lt;/span&gt;[&lt;span class=&quot;variable&quot;&gt;$in&lt;/span&gt;[&lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt;] - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]++;
    }

    &lt;span class=&quot;variable&quot;&gt;$l&lt;/span&gt; = &lt;span class=&quot;variable&quot;&gt;$counting&lt;/span&gt;.length
    &lt;span class=&quot;variable&quot;&gt;$j&lt;/span&gt; = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt; = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-lt&lt;/span&gt; &lt;span class=&quot;variable&quot;&gt;$l&lt;/span&gt;; &lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt;++) {
        &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; (&lt;span class=&quot;variable&quot;&gt;$counting&lt;/span&gt;[&lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt;] &lt;span class=&quot;operator&quot;&gt;-gt&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
            &lt;span class=&quot;variable&quot;&gt;$in&lt;/span&gt;[&lt;span class=&quot;variable&quot;&gt;$j&lt;/span&gt;] = &lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt; + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
            &lt;span class=&quot;variable&quot;&gt;$counting&lt;/span&gt;[&lt;span class=&quot;variable&quot;&gt;$i&lt;/span&gt;]--;
            &lt;span class=&quot;variable&quot;&gt;$j&lt;/span&gt;++;
        }
    }

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;variable&quot;&gt;$in&lt;/span&gt;;

}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;The sort only works with positive integers.&lt;/p&gt;
&lt;p&gt;As it mentions in the blog I linked that inspired this column, the time and space of the algorithm are O(n + k), where k is the maximum element size in the array. That&amp;#8217;s the real problem with the algorithm. If you sort something like &lt;code&gt;[1, 3, 5, 1287614]&lt;/code&gt;, you end up with a count array of 1287614 elements, which is definitely excessive for the array being sorted. Sorting an array shouldn’t fail because the elements in the array are too big. Running the PHP sort in a standard configuration with 5000000 in the input array will cause an out of memory exception.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Using the HSL colour space on Android</title>
      <link>http://localhost:8080/articles/using-the-hsl-colour-space-in-java/</link>
      <pubDate>Tue, 22 Apr 2014 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/using-the-hsl-colour-space-in-java/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;For my fun projects that include color, I like to use the following palette in the HSL space:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;random hue&lt;/li&gt;
&lt;li&gt;full saturation&lt;/li&gt;
&lt;li&gt;50% lightness&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is easy in HTML because HSL is in the CSS specification and it has great cross browser support.&lt;/p&gt;
&lt;p&gt;It’s a tiny bit harder in an Android app.&lt;/p&gt;
&lt;p&gt;Java on Android uses the rgb color space by default, but there are some handy methods for using HSL.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;float&lt;/span&gt;[] colors = {(&lt;span class=&quot;keyword&quot;&gt;float&lt;/span&gt;)Math.random() * &lt;span class=&quot;number&quot;&gt;360&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;255&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;127&lt;/span&gt;}; 
&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; rgb = Color.HSVToColor(colors); 
r = Color.red(rgb); 
g = Color.green(rgb); 
b = Color.blue(rgb);&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Using Underscore.PHP and Newton's Method to approximate pi</title>
      <link>http://localhost:8080/articles/using-underscore-php-and-newtons-method-to-approximate-pi/</link>
      <pubDate>Tue, 15 Apr 2014 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/using-underscore-php-and-newtons-method-to-approximate-pi/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;http://underscorejs.org/&quot;&gt;Underscore.js&lt;/a&gt; has been ported to &lt;a href=&quot;https://github.com/brianhaveri/Underscore.php&quot;&gt;Underscore.PHP&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For a simple example, let’s using Newton’s method to approximate pi.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$iterations = &lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;;
$x = &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;;

$_ = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; __();

$f = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($x)&lt;/span&gt; &lt;/span&gt;{&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; + cos($x);};
$g = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($x)&lt;/span&gt; &lt;/span&gt;{&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; -sin($x);};
$h = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;global&lt;/span&gt; $x;
    &lt;span class=&quot;keyword&quot;&gt;global&lt;/span&gt; $f;
    &lt;span class=&quot;keyword&quot;&gt;global&lt;/span&gt; $g;
    $x = $x - $f($x)/$g($x);
};

$j = [];

&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; $i &amp;amp;lt; $iterations; $i++) {
    $j[] = $h;
}

$_-&amp;gt;each($j, &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($k)&lt;/span&gt; &lt;/span&gt;{$k();});

&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $x;&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Setting up a simple blog using laravel</title>
      <link>http://localhost:8080/articles/setting-up-a-simple-blog-using-laravel/</link>
      <pubDate>Tue, 08 Apr 2014 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/setting-up-a-simple-blog-using-laravel/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Setting up a very simple blog with laravel is quite easy.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;installing-laravel&quot;&gt;Installing Laravel&lt;/h4&gt;
&lt;p&gt;The easiest install method is to use &lt;a href=&quot;https://getcomposer.org/download/&quot;&gt;composer&lt;/a&gt;. &lt;/p&gt;
&lt;h4 id=&quot;setting-up-routing&quot;&gt;Setting up routing&lt;/h4&gt;
&lt;p&gt;Edit your &lt;code&gt;/app/routes.php&lt;/code&gt; and add the following routes:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;Route::get('/', function()
{
    $posts = Post::orderBy('id', 'DESC')-&amp;gt;get();
    return View::make('blog')-&amp;gt;with('posts', $posts);
});


Route::get('post/{id}', function($id) {
    $post = Post::find($id);
    return View::make('post')-&amp;gt;with('post', $post);
})-&amp;gt;where('id', '[0-9]+');
&lt;/pre&gt;

&lt;p&gt;What this is saying is that the root request should use the &amp;#8220;blog&amp;#8221; view, using the collection of all blog posts, ordered by descending id.&lt;/p&gt;
&lt;p&gt;It also sets up an option to load individual posts at &lt;code&gt;/post/{id}&lt;/code&gt;, and the id is validated to be only integers.&lt;/p&gt;
&lt;h4 id=&quot;setting-up-views&quot;&gt;Setting up views&lt;/h4&gt;
&lt;p&gt;In &lt;code&gt;/app/views&lt;/code&gt; create a file called &lt;code&gt;layout.blade.php&lt;/code&gt; which contains the following:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;@yield('title')&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;h1&amp;gt;@yield('title')&amp;lt;/h1&amp;gt;

        @yield('content')
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;

&lt;p&gt;This is just a wrapper template where the title and yield values can be swapped in from other templates.&lt;/p&gt;
&lt;p&gt;Next, in &lt;code&gt;/app/views&lt;/code&gt; create a file called &lt;code&gt;blog.blade.php&lt;/code&gt;, which contains the following:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;@extends('layout')
@section('title')
    The Blog @stop
@section('content')
    @foreach($posts as $post) 
        &amp;lth2&amp;gt;
            &amp;lt;a href=&quot;/laravel-blog/post/{{ $post-&amp;gt;id }}&quot;&amp;gt;
                {{ $post-&amp;gt;title }}
            &amp;lt;/a&amp;gt;
        &amp;lt;/h2&amp;gt;
        &amp;lt;div class=&quot;post&quot;&amp;gt;{{ $post-&amp;gt;content }}&amp;lt;/div&amp;gt;
    @endforeach
@stop
&lt;/pre&gt;

&lt;p&gt;And make another view called &lt;code&gt;post.blade.php&lt;/code&gt; containing the following:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;@extends('layout')
@section('title')
    {{ $post-&amp;gt;title }} @stop
@section('content')
    {{ $post-&amp;gt;content }}
@stop
&lt;/pre&gt;

&lt;p&gt;These view set up values for title and content. In the blog view, we show all the posts, and in the post view, we only show one. This mirrors what we set up in the routes.&lt;/p&gt;
&lt;h4 id=&quot;setting-up-the-database&quot;&gt;Setting up the database&lt;/h4&gt;
&lt;p&gt;First, configure your MySQL database in &lt;code&gt;app/config/database.php&lt;/code&gt;. Now you have to set up a &lt;em&gt;migration&lt;/em&gt;. The migration that you set up will create the tables. When you installed laravel, you will have had the &lt;code&gt;artisan&lt;/code&gt; command line app set up for you. Run the following command:&lt;/p&gt;
&lt;pre&gt;php artisan migrate:make create_posts_table&lt;/pre&gt;

&lt;p&gt;This will have made a file in the &lt;code&gt;/app/database/migrations&lt;/code&gt; folder with a name like &lt;code&gt;{datetime}_create_posts_table.php&lt;/code&gt;. In this file, there will be a class &lt;code&gt;CreatePostsTable&lt;/code&gt; which will have an &lt;code&gt;up&lt;/code&gt; and a &lt;code&gt;down&lt;/code&gt; method. Replace these methods with the following:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;public function up()
    {
        Schema::create('posts', function($table)
        {
            $table-&amp;gt;increments('id');
            $table-&amp;gt;string('title');
            $table-&amp;gt;string('content');
            $table-&amp;gt;timestamps();
        });
    }

    public function down()
    {
        Schema::drop('posts');
    }
&lt;/pre&gt;

&lt;p&gt;Save the file, then from your command line, run:&lt;/p&gt;
&lt;pre&gt;php artisan migrate
&lt;/pre&gt;

&lt;p&gt;This will create the table in your database (as configured in &lt;code&gt;app/config/database.php&lt;/code&gt;) as configured in the &lt;code&gt;up&lt;/code&gt; method of your migration class.&lt;/p&gt;
&lt;h4 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;You have now set up a very simple, non-user friendly, and extremely plain-looking blog. You could add posts by making inserts directly to the table, or by setting up a new route that creates a &lt;code&gt;Post&lt;/code&gt; then calls the &lt;code&gt;save()&lt;/code&gt; method on it.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Check out my FirefoxOS game Protect Your Thing!</title>
      <link>http://localhost:8080/articles/check-out-my-firefoxos-game-protect-your-thing/</link>
      <pubDate>Sun, 23 Mar 2014 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/check-out-my-firefoxos-game-protect-your-thing/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Firefox_OS&quot;&gt;FirefoxOS&lt;/a&gt; development is really easy if you have experience with front-end web development. Apps are very similar to chrome extensions, with &lt;code&gt;.manifest&lt;/code&gt; files set up to control the application, and html / css to handle the content and appearance.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;
&lt;img src=&quot;/articles/check-out-my-firefoxos-game-protect-your-thing/1.png&quot; alt=&quot;&amp;quot;protect your thing...&amp;quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;With this technology, it’s pretty easy to shoehorn a webpage into an app. So if created an HTML app using canvas, as I have done with my &lt;a href=&quot;http://localhost:8080/protet.html&quot;&gt;Protect Your Thing&lt;/a&gt; game, you can use something like the &lt;a href=&quot;https://github.com/robnyman/Firefox-OS-Boilerplate-App&quot;&gt;FirefoxOS boilerplate app&lt;/a&gt; to get yourself up and running quickly. Adding your app to the marketplace is as easy as uploading a zip file and filling out a form. Unlike the Google Play Store, all apps are QA checked before going online, so expect a 12-24 hour delay.&lt;/p&gt;
&lt;p&gt;If you have a FirefoxOS device, you can install &lt;a href=&quot;https://marketplace.firefox.com/app/protect-your-thing&quot;&gt;Protect Your Thing! for FirefoxOS&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>A key-value store that forgets</title>
      <link>http://localhost:8080/articles/a-key-value-store-that-forgets/</link>
      <pubDate>Wed, 26 Feb 2014 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/a-key-value-store-that-forgets/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Humans, like computers, have long term and short term memory. An interesting feature of human memory is that if you don&amp;#8217;t use a memory for a while, you will eventually forget it.&lt;/p&gt;
&lt;p&gt;So, for example, assume that 20 years ago you read &lt;em&gt;War and Peace&lt;/em&gt;. Rather than keep the details of all 1000 pages in your memory, your brain sees that the memory hasn&amp;#8217;t been used in a while, and eventually it forgets the details of the book.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This memory feature could be useful for AI in a video game, or for clearing out old memory that hasn&amp;#8217;t been used in a while. In the latter case, you&amp;#8217;d want to have some re-lookup functionality added to your code. In our analogy this would be akin to re-reading the book after having forgotten the details.&lt;/p&gt;
&lt;p&gt;We can model this behaviour in javascript using an interval that clears out old unused memories.&lt;/p&gt;
&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;var Forgettable = function(duration) {
    var forgettable = {
        &quot;duration&quot; : duration,
        &quot;values&quot; : {},
        &quot;timeouts&quot; : {}
    };
    forgettable.set = function (k, v) {
        if (!v) {
            return;
        }
        this.values[k] = v;
        this.timeouts[k] = this.duration;
    };
    forgettable.check = function() {
        var i;
        for (i in this.timeouts) if (this.timeouts.hasOwnProperty(i)) {
            if (this.timeouts[i] == 0) {
                delete this.timeouts[i];
                delete this.values[i];
            } else {
                this.timeouts[i] --;
            }
        }
    };
    forgettable.get = function(k) {
        var value = this.values[k];
        this.set(k, value);
        return value;
    };
    (function(f) {
        setInterval(function() {
            f.check();
        }, 1000);
    })(forgettable);
    return forgettable;
};
&lt;/pre&gt;

&lt;p&gt;The data structure above works by having a duration of time that it will retain a memory. When a certain memory hasn&amp;#8217;t been looked up in a certain amount of time, it will be deleted.&lt;/p&gt;
&lt;p&gt;Rather than using the interval, the same code could be implemented by moving the contents of the check function in before the contents of the get function, or using timeouts.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Getting Started With Espruino</title>
      <link>http://localhost:8080/articles/getting-started-with-espruino/</link>
      <pubDate>Thu, 06 Feb 2014 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/getting-started-with-espruino/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I was excited yesterday to see that my &lt;a href=&quot;http://www.espruino.com/&quot;&gt;Espruino&lt;/a&gt;, which I backed on Kick Starter, had arrived in the mail. Espruino is micro controller that is controlled via JavaScript. I&amp;#8217;ve long wanted to experiment with micro controllers, having visions of working with arduinos or a raspberry pi, but the JavaScript control combined with the reasonable price tipped the scale in favour of Espruino.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://benwendt.ca/images/IMG_20140207_092616-2.jpg&quot; alt=&quot;my new Espruino&quot;&gt;&lt;/p&gt;
&lt;p&gt;There is an excellent &lt;a href=&quot;http://www.espruino.com/Quick+Start&quot;&gt;Quick Start Guide&lt;/a&gt; on the Espruino site that got me started in a flash. You can control the LED lights on the board by calling things like &lt;code&gt;digitalWrite(LED1, 1)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There are three LED variables, so I decided to write an interval to loop through them:&lt;/p&gt;
&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;var state = 0,
    interval = setInterval(function() {
      state = (state + 1) %3;
      digitalWrite(LED1, 0);
      digitalWrite(LED2, 0);
      digitalWrite(LED3, 0);
      switch (state) {
        case 0:
          digitalWrite(LED1, 1);
          break;
        case 1:
          digitalWrite(LED2, 1);
          break;
        case 2:
          digitalWrite(LED3, 1);
          break;
      }
    }, 50);
&lt;/pre&gt;

&lt;p&gt;And here it is in action:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://benwendt.ca/images/base2.gif&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;And here is code to turn on and off LED1 when BTN1 is pressed:&lt;/p&gt;
&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;var on = false;
setWatch(function(e) {
  on = !on;

  digitalWrite(LED1, on);
}, A1, { repeat: true, edge: &quot;falling&quot; });

&lt;/pre&gt;

</description>
    </item>
    <item>
      <title>Interfacing with an Espruino from c#</title>
      <link>http://localhost:8080/articles/interfacing-with-an-espruino-from-c/</link>
      <pubDate>Thu, 06 Feb 2014 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/interfacing-with-an-espruino-from-c/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Communication with an Espruino is done by sending JavaScript in string format over a serial port interface. This can be done in c# using the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.io.ports.serialport%28v=vs.110%29.aspx&quot;&gt;&lt;code&gt;System.IO.Ports.SerialPort&lt;/code&gt;&lt;/a&gt; class. You can see the default serial port connection settings for &lt;a href=&quot;http://www.espruino.com/Interfacing&quot;&gt;interfacing on the Espruino site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The following code will check &lt;a href=&quot;http://www.abevigoda.com/&quot;&gt;abevigoda.com&lt;/a&gt; to see if &lt;a href=&quot;http://en.wikipedia.org/wiki/Abe_Vigoda&quot;&gt;Abe Vigoda&lt;/a&gt; is still alive. If he is still alive, a blue light will turn on. If he has passed away, a red light will display.&lt;/p&gt;
&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.IO;
using System.Net;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            WebClient client = new WebClient();

            Stream Abe = client.OpenRead(&quot;http://www.abevigoda.com/&quot;);
            StreamReader reader = new StreamReader(Abe);
            string HTML = reader.ReadToEnd();

            int LEDNumber;
            if (HTML.Contains(&quot;alive&quot;))
            {
                LEDNumber = 3;
            }
            else
            {
                LEDNumber = 1;
            }

            SerialPort port = new SerialPort(
                &quot;COM4&quot;,
                9600,
                Parity.None,
                8,
                StopBits.One
            );

            port.Open();
            port.Write(&quot;digitalWrite(LED&quot; + LEDNumber + &quot;, 1);n&quot;);
            port.Close();

        }
    }
}

&lt;/pre&gt;

&lt;p&gt;Here&amp;#8217;s the current results:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.benwendt.ca/images/IMG_20140207_141030.jpg&quot; alt=&quot;espruino with blue light&quot;&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Adding Arbitrary Code to your &lt;head&gt; in Magento</title>
      <link>http://localhost:8080/articles/adding-arbitrary-code-to-your-in-magento/</link>
      <pubDate>Wed, 05 Feb 2014 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/adding-arbitrary-code-to-your-in-magento/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Magento&amp;#8217;s built in &lt;code&gt;addJs&lt;/code&gt; method in the &lt;code&gt;Mage_Page_Block_Html_Head&lt;/code&gt; class assumes that files will be hosted locally. This isn&amp;#8217;t always desirable. E.g. you may want to use Google&amp;#8217;s CDN to host jQuery.&lt;/p&gt;
&lt;p&gt;This can be accomplished by adding the following to your layout xml:&lt;/p&gt;
&lt;pre&gt;&amp;lt;reference name=&quot;head&quot;&gt;
            &amp;lt;block type=&quot;core/text&quot; name=&quot;my_head&quot;&gt;&amp;lt;/block&gt;
        &amp;lt;/reference&gt;
&lt;/pre&gt;

&lt;p&gt;Now, in your controller you can add anything into this block that you want, like so:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;$google_url = 'http://google.com/jquery.js';
$this-&amp;gt;getLayout()-&amp;gt;getBlock('my_head')-&amp;gt;setText(&quot;

            &amp;lt;script src='$google_url'&amp;gt;&amp;lt;/script&amp;gt;

        &quot;);

&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>An implementation of the memento pattern in PHP</title>
      <link>http://localhost:8080/articles/an-implementation-of-the-memento-pattern-in-php/</link>
      <pubDate>Sun, 08 Dec 2013 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/an-implementation-of-the-memento-pattern-in-php/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;The memento pattern is a design pattern used to store and revert states for objects which support this capacity. It is accomplished by having a &lt;code&gt;Caretaker&lt;/code&gt; object which manages a set of states, encoded in &lt;code&gt;Memento&lt;/code&gt; objects. The &lt;code&gt;Memento&lt;/code&gt; objects handle the storage of state; the implementation of this can vary, but it necessitates some level of deep-copying the object. A shallow copy will not suffice in general because it will not always capture the whole state of an object, due to the fact that most languages implement memory access for objects as references. Because of this, I use &lt;code&gt;serialize&lt;/code&gt; and &lt;code&gt;unserialize&lt;/code&gt; in my example below. Of course you could use other methods, like &lt;code&gt;clone&lt;/code&gt; or just copying what you know you will need if memory is a concern.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s take a look at how it works&amp;#8230;&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;/**
* The memento class is very simple; it simply serializes and
* unserializes incoming data.
*/

class Memento {
    private $state = null;
    public function __construct($state) {
        $this-&amp;gt;state = serialize($state);
    }
    public function revertState() {
        return unserialize($this-&amp;gt;state);
    }
}

/**
* The Caretaker class manages a group of Memento objects.
*/

class Caretaker {

    private $states = array();

    public function set($state) {
        $this-&amp;gt;states[] = new Memento($state);
    }

    public function get() {
        $memento = array_pop($this-&amp;gt;states);
        return $memento-&amp;gt;revertState();
    }

}
&lt;/pre&gt;

&lt;p&gt;And here is a sample of usage:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;$ct = new Caretaker();

$ct-&amp;gt;set('3');
$ct-&amp;gt;set('2');
$ct-&amp;gt;set('1');
$ct-&amp;gt;set(new stdClass);

var_dump($ct-&amp;gt;get());
echo $ct-&amp;gt;get() . &quot;n&quot;;
echo $ct-&amp;gt;get() . &quot;n&quot;;
echo $ct-&amp;gt;get() . &quot;n&quot;;
&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Weighted merging of multiple Markov Chains</title>
      <link>http://localhost:8080/articles/weighted-merging-of-multiple-markov-chains/</link>
      <pubDate>Tue, 03 Dec 2013 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/weighted-merging-of-multiple-markov-chains/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Suppose you have ten text sources, and you generate a new block of text trained from each, and you want to give each its own weighting. You have to weave multiple markov chains together.
&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;
Here is a class that does just that.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;MultiMarkov&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $files;
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $chains = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $weights = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $total_weight = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($init)&lt;/span&gt; &lt;/span&gt;{
        $total_weight = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
        &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($init &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $label =&amp;gt; $file_settings) {
            $file = $file_settings[&lt;span class=&quot;string&quot;&gt;'file'&lt;/span&gt;];
            $weight = $file_settings[&lt;span class=&quot;string&quot;&gt;'weight'&lt;/span&gt;];
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_integer($weight) || $weight &amp;amp;lt;= &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
                &lt;span class=&quot;keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;Exception&lt;/span&gt; (
                    &lt;span class=&quot;string&quot;&gt;&quot;Weight $weight is not a positive integer.&quot;&lt;/span&gt;);
            }
            $total_weight += $weight;
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;weights[$label] = $weight;
            $words = get_all_words_in_file($file);
            $chain = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Chain($words);
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;chains[$label] = $chain;
        }
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;total_weight = $total_weight;
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;setWeights&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($weights)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($weights &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $label =&amp;gt; $weight) {
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;weights[$label] = $weight;
        }
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getWeightedRandomChain&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        $rand = rand(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;total_weight);
        $running_total = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
        &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;weights &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $label =&amp;gt; $weight) {
            $running_total += $weight;
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($running_total &amp;gt; $rand) {
                &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;;
            }
        }
        &lt;span class=&quot;comment&quot;&gt;// echo &quot;$labeln&quot;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;chains[$label];
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getRandomWord&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        $from_chain = &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;getWeightedRandomChain();
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $from_chain-&amp;gt;getRandomWord();
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getChainOfLength&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($in_word, $length)&lt;/span&gt; &lt;/span&gt;{

        &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; (!&lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;($word) || $word == &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;) {
            $from_chain = &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;getWeightedRandomChain();
            $word = $from_chain-&amp;gt;getNextWord($in_word);

        } 
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($length &amp;gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;) {
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $word . &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;getChainOfLength($word, $length - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;);
        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $word;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To use this class you could do something like so:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;
&lt;span class=&quot;meta&quot;&gt;&amp;lt;?php&lt;/span&gt; 

&lt;span class=&quot;keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'markov.php'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'multi-markov.php'&lt;/span&gt;;

$files = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(
    &lt;span class=&quot;string&quot;&gt;'joyce'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(
        &lt;span class=&quot;string&quot;&gt;'file'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;string&quot;&gt;'text/joyce.txt'&lt;/span&gt;,
        &lt;span class=&quot;string&quot;&gt;'weight'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;
    ),
    &lt;span class=&quot;string&quot;&gt;'weitz'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(
        &lt;span class=&quot;string&quot;&gt;'file'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;string&quot;&gt;'text/weitz.txt'&lt;/span&gt;,
        &lt;span class=&quot;string&quot;&gt;'weight'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;
    ),
    &lt;span class=&quot;string&quot;&gt;'sontag'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(
        &lt;span class=&quot;string&quot;&gt;'file'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;string&quot;&gt;'text/sontag.txt'&lt;/span&gt;,
        &lt;span class=&quot;string&quot;&gt;'weight'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;
    ),
    &lt;span class=&quot;string&quot;&gt;'berger'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(
        &lt;span class=&quot;string&quot;&gt;'file'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;string&quot;&gt;'text/berger.txt'&lt;/span&gt;,
        &lt;span class=&quot;string&quot;&gt;'weight'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;
    ),
    &lt;span class=&quot;string&quot;&gt;'tolstoy'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(
        &lt;span class=&quot;string&quot;&gt;'file'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;string&quot;&gt;'text/tolstoy.txt'&lt;/span&gt;,
        &lt;span class=&quot;string&quot;&gt;'weight'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;number&quot;&gt;19&lt;/span&gt;
    ),

);

$builder = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; MultiMarkov($files);
$starting_word = $builder-&amp;gt;getRandomWord();

$newSentence = $builder-&amp;gt;getChainOfLength($starting_word, &lt;span class=&quot;number&quot;&gt;160&lt;/span&gt;);
&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; wordwrap($newSentence, &lt;span class=&quot;number&quot;&gt;70&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;n&quot;&lt;/span&gt;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This text is trained from a variety of great writers writing about aesthetics and the nature of art. Here&amp;#8217;s a sample of the output:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;praise worthy on the conditions
under which has drawn it seemed to
me that of reassembling what we would call these conditions ù a novel,
painting, to its subject, remains the concept shows, has hardly broken
into the standard of all other world, have painted the result of color
that &amp;#8220;This is often experienced as to himself; so, thanks
to fate or love to see in the faculty of a common properties of the
world that supreme quality
of true painting or theory again. Of course,&amp;#8221;Art is very perception of
art. Whatis central as a fading coal. The destiny of the word has
experienced, and everything else&amp;#8230; For myself, I am speaking now
that basket from everything else. Each claims that are made by
accident when he experiences the oar or that its claim to be answered
yes or even seem to be maintained is definable as works of application
of movements, lines, colors, shapes, volumes &amp;#8211; and sufficient
conditions.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    <item>
      <title>Registry Pattern</title>
      <link>http://localhost:8080/articles/registry-pattern/</link>
      <pubDate>Sun, 17 Nov 2013 19:00:00 -0500</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/registry-pattern/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Here&amp;#8217;s another super-simple design pattern, implemented in PHP.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;class Registry {
    private $values = array();

    public function get($key) {
        if (!isset($this-&amp;gt;values-&amp;gt;$key)) {
            throw new OutOfBoundsException(&quot;$key not in registry&quot;);
        }
        return $this-&amp;gt;values-&amp;gt;$key;
    }

    public function set($key, $val) {
        if (!isset($this-&amp;gt;values-&amp;gt;$key)) {
            throw new OverflowException(&quot;$key already in registry&quot;);
        }
        $this-&amp;gt;values-&amp;gt;$key = $val;
    }
}
&lt;/pre&gt;

&lt;p&gt;The registry pattern is used to store information that can be used throughout your application. You could use a registry to store a bunch of application settings, for example.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve seen this implemented with the magic getters and setters in php, but then you end up with an object that appears to just be setting public properties. It&amp;#8217;s not the most readable solution and it is unintuitive to expect an exception when setting a public property.&lt;/p&gt;
&lt;p&gt;It is often implemented as a singleton, but it doesn&amp;#8217;t have to be. In general singletons are bad because they introduce global state into your code and are hard to write test cases for. If you don&amp;#8217;t want to use your registry as a singleton, just do an inversion of control. The downside is having to pass around the registry as a parameter, but trust me: it&amp;#8217;s worth the effort.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Generating the vertices and edges of an n-cube in javascript</title>
      <link>http://localhost:8080/articles/generating-the-vertices-and-edges-of-an-n-cube-in-javascript/</link>
      <pubDate>Fri, 25 Oct 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/generating-the-vertices-and-edges-of-an-n-cube-in-javascript/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;An &lt;a href=&quot;http://en.wikipedia.org/wiki/Hypercube&quot;&gt;n-cube&lt;/a&gt; is a geometric shape analogous to a cube, but in an arbitrary number of dimensions.&lt;/p&gt;
&lt;p&gt;The algorithm I&amp;#8217;ve laid out does a recursive routine for finding the vertices and then looks for all edges within one unit of each to define the edges.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The function becomes non-response with values over 14. This is because the number of points in an n-cube is given by 2&lt;sup&gt;n&lt;/sup&gt; and the number of edges is n2&lt;sup&gt;n-1&lt;/sup&gt;. So the expected memory usage of this function is O(2&lt;sup&gt;n&lt;/sup&gt;), which is going to blow up with any fairly large value.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; nCube = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;n&lt;/span&gt;) &lt;/span&gt;{

    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (n == &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;) {
      &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; {
        &lt;span class=&quot;string&quot;&gt;&quot;points&quot;&lt;/span&gt; :[[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;], [&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]],
        &lt;span class=&quot;string&quot;&gt;&quot;edges&quot;&lt;/span&gt; : [[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]]
      };
    } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
      &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; L, i, j, prev = nCube(n - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;), out = {
        &lt;span class=&quot;string&quot;&gt;&quot;dimensions&quot;&lt;/span&gt; : n,
        &lt;span class=&quot;string&quot;&gt;&quot;points&quot;&lt;/span&gt; : [],
        &lt;span class=&quot;string&quot;&gt;&quot;edges&quot;&lt;/span&gt; : []
      };

      &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; i &amp;lt; prev.points.length; i++) {
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (j = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; j &amp;lt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;; j++) {
          (&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
            &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; fit = prev.points[i].slice();
            fit.push(j);
            out.points.push(fit);

          })();
        }
      }
      &lt;span class=&quot;comment&quot;&gt;// surely there is a faster recursive method of defining edges, but...&lt;/span&gt;
      &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; i &amp;lt; out.points.length; i++) {
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (j = i; j &amp;lt; out.points.length; j++) {
          &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (i == j) &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;;
          &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (distance(out.points[i], out.points[j]) == &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;) {
            out.edges.push([i,j]);
          }
        }
      }

      &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; out;
    }
  };

&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>A PHP spell checker</title>
      <link>http://localhost:8080/articles/a-php-spell-checker/</link>
      <pubDate>Sun, 20 Oct 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/a-php-spell-checker/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;http://norvig.com/spell-correct.html&quot;&gt;How to Write a Spelling Corrector&lt;/a&gt;, by Peter Norvig, is a popular resource for instructions on how to produce spell check functionality. That page does some statistical Analysis of how this algorithm works and is definitely worth reading.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve rewritten this alghorithm in PHP. It&amp;#8217;s not as eloquent as the python code in the original, but I suspect it gains a tiny bit of readability in the trade-off for terseness.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;
A basic outline of the routine is as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Train the spell checker in what words it should know. Any large block of text in the desired language that contains all the words you want to be spell-checkable, and no others, will do. This introduces a chicken-egg issue as you may have misspellings in your training text. Ideally, you would use a previously verified dictionary for this step. But you could use anything, like a bunch of crawled text from wikipedia, or this blog, or the complete works of Charles Dickens, or whatever reference you choose.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate a list of candidate words within a given &lt;a href=&quot;http://en.wikipedia.org/wiki/Levenshtein_distance&quot;&gt;Levenshtein distance&lt;/a&gt; of the word you are attempting to correct. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All candidate words will be found within a predefined number of character deletions, character transpositions, and character insertions on the original word.&lt;/li&gt;
&lt;li&gt;Candidates will be in the trained text.&lt;/li&gt;
&lt;li&gt;A given candidate can be reached in more than one way depending on which deletions, transpositions, and insertions are performed. We will exploit this fact.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The list of suggestions will be ranked by which suggestions arise most frequently.&lt;/li&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Choose one or more suggestions from your list as required&lt;/ol&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;#8217;s the PHP class:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;?php

&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;class checker {
    private $nwords = array();
    private function words($text) {
        return preg_split(‘/s+/‘, $text);
    }
    public function train($words) {
        $this-&amp;gt;nwords = array_flip($this-&amp;gt;words($words));
    }
    private function edits1($word) {
        $word = strtolower($word);
        $alphabet = range(‘a’, ‘z’);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    $splits = array();
    for ($i = 1; $i &amp;amp;lt; strlen($word); $i++) {
        $splits[] = array(substr($word, 0, $i), substr($word, $i));
    }
    $deletes = array();
    foreach($splits as $split) {
        $deletes[] = $split[0] . substr($split[1], 1);
    }
    $transposes = array();
    foreach($splits as $split) {
        if (isset($split[1][1])) {
            $transposes[] = $split[0] . $split[1][1] . $split[1][0] . substr($split[1], 2);
        }
    }
    $replaces = array();
    foreach($alphabet as $letter) {
        foreach($splits as $split) {
            $replaces[] = $split[0] . $letter . substr($split[1], 1);
        }
    }
    $inserts = array();
    foreach($alphabet as $letter) {
        foreach($splits as $split) {
            $inserts[] = $split[0] . $letter . $split[1];
        }
    }
    return array_merge($deletes, $transposes, $replaces, $inserts);
}
private function edits2($word) {
    $edits2 = array();
    foreach($this-&amp;amp;gt;edits1($word) as $e1) {
        foreach($this-&amp;amp;gt;edits1($e1) as $e2) {
            if (isset($this-&amp;amp;gt;nwords[$e2])) {
                $edits2[] = $e2;
            }
        }
    }
    return $edits2;
}
private function known($word) {
    $known = array();
    if (isset($this-&amp;amp;gt;nwords[$word])) {
        $known[] = $word;
    }
    return $known;
}
public function correct($word) {
    $candidates = array();
    if ($this-&amp;amp;gt;known($word)) {
        $candidates[] = $word;
    }
    foreach($this-&amp;amp;gt;edits1($word) as $possible) {
        if ($this-&amp;amp;gt;known($possible)) {
            $candidates[] = $possible;
        }
    }
    foreach($this-&amp;amp;gt;edits2($word) as $possible) {
        if ($this-&amp;amp;gt;known($possible)) {
            $candidates[] = $possible;
        }
    }
    $counts = array();
    foreach($candidates as $candidate) {
        if (!isset($counts[$candidate])) {
            $counts[$candidate] = 0;
        } else {
            $counts[$candidate]++;
        }
    }
    $most = 0;
    $word = &amp;#39;&amp;#39;;
    foreach($counts as $candidate =&amp;amp;gt; $count) {
        if ($count &amp;amp;gt; $most) {
            $most = $count;
            $word = $candidate;
        }
    }
    return $word;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;}
&lt;/pre&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Usage:

&amp;lt;pre class=&amp;quot;brush: php; title: ; notranslate&amp;quot; title=&amp;quot;&amp;quot;&amp;gt;$spell = new checker();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;$spell-&amp;gt;train(file_get_contents(‘dictionary.txt’));&lt;/p&gt;
&lt;p&gt;$corrections = $spell-&amp;gt;correct(‘speling’);&lt;/p&gt;
&lt;p&gt;echo “$correctionsn”;
&lt;/pre&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>A Lattice class</title>
      <link>http://localhost:8080/articles/a-lattice-class/</link>
      <pubDate>Tue, 08 Oct 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/a-lattice-class/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Consider if you need a 7-dimensional lattice data structure. An array is great for one-dimensional data but once you add dimensions things quickly get difficult to manage. Here&amp;#8217;s a data structure that takes away some of that headache:
&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;?php

class Lattice {

    private $lattice = null;
    private $dimensions = 0;
    private $boundaries = null;

    public function setDimensions($d) {
        if (is_integer($d)) {
            $this-&amp;gt;dimensions = $d;
        } else {
            throw new Exception('setDimensions expects an integer. given: ' . $d);
        }
    }
    public function getDimensions() {
        return $this-&amp;gt;dimensions;
    }
    public function setBoundaries(array $boundaries) {
        $iteration = count($boundaries);
        if ($this-&amp;gt;dimensions &amp;gt; 0 &amp;&amp; $this-&amp;gt;dimensions == count($boundaries)) {
            $this-&amp;gt;boundaries = $boundaries;
            $array = null;
            while ($iteration &amp;gt; 0) {
                $iteration --;
                $array = array_fill(0, $boundaries[$iteration], $array);
            }
            $this-&amp;gt;lattice = $array;
        } else {
            throw new Exception(&quot;Boundary count should match dimension count&quot;);
        }
    }
    public function setNode(array $coordinates, $value) {
        if (count($coordinates) != $this-&amp;gt;dimensions) {
            throw new Exception(&quot;Passed coordinates have dimension mismatch&quot;);
        }
        $iteration = 0;
        $array = &amp;$this-&amp;gt;lattice;
        while ($iteration &amp;lt; count($coordinates) - 1) {
            $coordinate = $coordinates[$iteration];

            if ($coordinate &amp;gt; $this-&amp;gt;boundaries[$iteration] - 1) {
                throw new Exception(&quot;coordinate $iteration is out of bounds&quot;);
            }
            $array = &amp;$array[$coordinate];
            $iteration++;
        }
        $coordinate = $coordinates[$iteration];
        if ($coordinate &amp;gt; $this-&amp;gt;boundaries[$iteration] - 1) {
            throw new Exception(&quot;coordinate $iteration is out of bounds&quot;);
        }
        $array[$coordinate] = $value;
    }
    public function getNode(array $coordinates) {
        if (count($coordinates) != $this-&amp;gt;dimensions) {
            throw new Exception(&quot;Passed coordinates have dimension mismatch&quot;);
        }
        $iteration = 0;
        $array = &amp;$this-&amp;gt;lattice;
        while ($iteration &amp;lt; count($coordinates) - 1) {
            $coordinate = $coordinates[$iteration];

            if ($coordinate &amp;gt; $this-&amp;gt;boundaries[$iteration] - 1) {
                throw new Exception(&quot;coordinate $iteration is out of bounds&quot;);
            }
            $array = &amp;$array[$coordinate];
            $iteration++;
        }
        $coordinate = $coordinates[$iteration];
        if ($coordinate &amp;gt; $this-&amp;gt;boundaries[$iteration] - 1) {
            throw new Exception(&quot;coordinate $iteration is out of bounds&quot;);
        }
        return $array[$coordinate];
    }
    public function toArray() {
        return $this-&amp;gt;lattice;
    }
}

&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Using Shared Strings to Reduce Memory Usage</title>
      <link>http://localhost:8080/articles/using-shared-strings-to-reduce-memory-usage/</link>
      <pubDate>Thu, 26 Sep 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/using-shared-strings-to-reduce-memory-usage/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;As of Excel 2007, files are saved in the Open XML format. This format is comprised of a grouping of XML files and assets, which are then zipped up and given the &lt;code&gt;.xlsx&lt;/code&gt; extension. It&amp;#8217;s a lot more readable from other programs than an old fashioned &lt;code&gt;.xls&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;One means that was used to reduce the file size was setting up a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/office/gg278314.aspx&quot;&gt;shared strings table&lt;/a&gt;. Strings stored in a spreadsheet are given a numeric index and this numeric index is then stored in the xml file. In general, if a string is reused frequently the overhead of the shared string map will be payed off by the saving of only storing string indices. &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For example, consider the following spreadsheet:&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;td&gt;
      reused string
    &lt;/td&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;td&amp;gt;
  reused string
&amp;lt;/td&amp;gt;

&amp;lt;td&amp;gt;
  reused string
&amp;lt;/td&amp;gt;

&amp;lt;td&amp;gt;
  &amp;lt;td&amp;gt;
    reused string
  &amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt; 

  &amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;
      other string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
      reused string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
      reused string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
      other string
    &amp;lt;/td&amp;gt;
  &amp;lt;/tr&amp;gt;

  &amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;
      reused string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
      reused string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
      reused string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
      reused string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
    &amp;lt;/td&amp;gt;
  &amp;lt;/tr&amp;gt;

  &amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;
      reused string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
      reused string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
      reused string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
      reused string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
      other string
    &amp;lt;/td&amp;gt;
  &amp;lt;/tr&amp;gt;

  &amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;
      other string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
      reused string
    &amp;lt;/td&amp;gt;

    &amp;lt;td&amp;gt;
    &amp;lt;/td&amp;gt;
  &amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt; &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This could be shortened to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1 =&amp;gt; reused string
2 =&amp;gt; other string&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
&lt;td&gt;
1
&lt;/td&gt;&lt;/tr&gt; 

&lt;tr&gt;
&lt;td&gt;
2
&lt;/td&gt;

&lt;td&gt;
&lt;/td&gt;

&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
2
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
2
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
2
&lt;/td&gt;

&lt;td&gt;
&lt;/td&gt;

&lt;td&gt;
&lt;/td&gt;

&lt;td&gt;
1
&lt;/td&gt;

&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt; 


&lt;p&gt;The Open XML format has other space savings, like not storing empty cells, but that is not relevant here.&lt;/p&gt;
&lt;p&gt;Even with the clunky HTML table structure above, using shared strings has reduced the number of characters used to store this data from 547 down to 362.&lt;/p&gt;
&lt;p&gt;The same idea can be applied when you have a program that is saving thousands of reused strings. Saving integers is much more efficient. The size of a PHP integer is platform dependent, but generally 32-bits, while a string will use 1 or more bytes per character. If you know you are dealing with something with a lot of string reuse, something like this can be useful.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s an implementation in PHP. You can start by throwing strings into the collection by calling &lt;code&gt;getIndex&lt;/code&gt;. Then, when you are ready to pull the strings back out, call &lt;code&gt;getString&lt;/code&gt;. Note that the class has an insertion mode and an extraction mode, and that when it changes mode a call to &lt;code&gt;array_flip&lt;/code&gt; is made on the internal listing of entries. This is done to speed up the process (by using hashing on both operations rather than doing array searches); the down side is that if you are frequently changing back and forth between reading and writing, it will be slow. It&amp;#8217;s meant to be written to all at once, then read off later.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;SharedString&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $map = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $extraction_mode = &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; count(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;map);
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getIndex&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($string)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;extraction_mode) {
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;map = array_flip(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;map);
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;extraction_mode = &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;;
        }
        $string =  preg_replace(&lt;span class=&quot;string&quot;&gt;'/s/'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;' '&lt;/span&gt;, $string);
        $position = &lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;map[$string]) ? &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;map[$string] : &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;;
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($position === &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;) {
            $position = count(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;map);
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;map[$string] = $position;
        } 
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $position;

    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($index)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;extraction_mode) {
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;map = array_flip(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;map);
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;extraction_mode = &lt;span class=&quot;keyword&quot;&gt;true&lt;/span&gt;;
        }
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;map[$index];
    }
    &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;mapArray&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(SharedString $string, $array)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($array &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $key =&amp;amp;gt; $value) {
            $array[$key] = $string-&amp;amp;gt;getIndex($value);
        }
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $array;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PHP doesn&amp;#8217;t have great control over types, but you can make further memory reductions, as Open XML does, but not saving numerics as strings. These use less memory when stored as their appropriate type. E.g. in Ascii &lt;code&gt;12345&lt;/code&gt; takes 5 bytes, but stored in a signed integer it only takes 16 bits.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>The Knuth-Morris-Pratt algorithm implemented in JavaScript</title>
      <link>http://localhost:8080/articles/the-knuth-morris-pratt-algorithm-implemented-in-javascript/</link>
      <pubDate>Thu, 19 Sep 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/the-knuth-morris-pratt-algorithm-implemented-in-javascript/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm&quot;&gt;Knuth-Morris-Pratt string search algorithm&lt;/a&gt; is an algorithm for finding a substring within another string that uses information calculated about the substring to speed up the search process.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Before looking through the text to be searched, a table of jump lengths is calculated from the search string. Rather than iterating through the whole string, you can determine how many characters to skip over based on the structure of the word being searched for. As you scan through the search text and you find a mismatch, you can start comparing characters again from the last matching substring between the search term and the search text. &lt;/p&gt;
&lt;p&gt;E.g. if you are searching through &lt;a href=&quot;http://www.lyricsfreak.com/n/neil+young/t+bone_20536423.html&quot;&gt;T-Bone by Neil Young&lt;/a&gt; for the words &amp;#8220;Ain&amp;#8217;t got no T-BonenT-Bone&amp;#8221;, every time you find an instance of &amp;#8220;&amp;#8221;Ain&amp;#8217;t got no T-Bonen&amp;#8221; that isn&amp;#8217;t followed by a line-break, you can skip 20 characters of checking the lyrics and restart from the beginning of your words, because you know that they can&amp;#8217;t occur again within that span because you have already checked those and they don&amp;#8217;t match the begging of the search words. Basically you already know that index is the next occurence of Ain&amp;#8217;t, so you can start again from there.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; makeKMPTable = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;word&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;(&lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt;.prototype.toString.call(word) == &lt;span class=&quot;string&quot;&gt;'[object String]'&lt;/span&gt; ) {
        word = word.split(&lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;);
    }
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; results = [];
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; pos = &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; cnd = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;

    results[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] = &lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;;
    results[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; (pos &amp;amp;lt; word.length) {
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (word[pos - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] == word[cnd]) {
            cnd++;
            results[pos] = cnd;
            pos++;
        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (cnd &amp;amp;gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
            cnd = results[cnd];
        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
            results[pos] = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
            pos++;
        }
    }
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; results;
};

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; KMPSearch = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;string, word&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;(&lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt;.prototype.toString.call(string) == &lt;span class=&quot;string&quot;&gt;'[object String]'&lt;/span&gt; ) {
        string = string.split(&lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;);
    }
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;(&lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt;.prototype.toString.call(word) == &lt;span class=&quot;string&quot;&gt;'[object String]'&lt;/span&gt; ) {
        word = word.split(&lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;);
    }

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; index = &lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; m = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; T = makeKMPTable(word);

    &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; (m + i &amp;amp;lt; string.length) {
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (word[i] == string[m + i]) {
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (i == word.length - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;) {
                &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; m;
            }
            i++;
        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
            m = m + i - T[i];
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (T[i] &amp;amp;gt; &lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;) {
                i = T[i];
            } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
                i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
            }
        }
    }
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; index;
};

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; test = &lt;span class=&quot;string&quot;&gt;'potential'&lt;/span&gt;;

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; string = &lt;span class=&quot;string&quot;&gt;&quot;This fact implies that the loop can execute at most 2n times. For, in each iteration, it &quot;&lt;/span&gt; +
    &lt;span class=&quot;string&quot;&gt;&quot;executes one of the two branches in the loop. The first branch invariably increases i and does not &quot;&lt;/span&gt; +
    &lt;span class=&quot;string&quot;&gt;&quot;change m, so that the index m + i of the currently scrutinized character of S is increased. The second &quot;&lt;/span&gt; +
    &lt;span class=&quot;string&quot;&gt;&quot;branch adds i - T[i] to m, and as we have seen, this is always a positive number. Thus the location m &quot;&lt;/span&gt; +
    &lt;span class=&quot;string&quot;&gt;&quot;of the beginning of the current potential match is increased. Now, the loop ends if m + i = n; &quot;&lt;/span&gt; +
    &lt;span class=&quot;string&quot;&gt;&quot;therefore each branch of the loop can be reached at most k times, since they respectively increase &quot;&lt;/span&gt; +
    &lt;span class=&quot;string&quot;&gt;&quot;either m + i or m, and m = m + i: if m = n, then certainly m + i = n, so that since it increases by &quot;&lt;/span&gt; +
    &lt;span class=&quot;string&quot;&gt;&quot;unit increments at most, we must have had m + i = n at some point in the past, and therefore either &quot;&lt;/span&gt; +
    &lt;span class=&quot;string&quot;&gt;&quot;way we would be done.&quot;&lt;/span&gt;;

result = KMPSearch(string, test);&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Replacing Removed Whitespace to Restore Words From a Dictionary</title>
      <link>http://localhost:8080/articles/fixing-strings-with-whitespace-removal/</link>
      <pubDate>Wed, 11 Sep 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/fixing-strings-with-whitespace-removal/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Consider a spell checker program: a user is entering input, and for whatever reason they miss some white space while entering input, so that something like &lt;em&gt;The Sun Also Rises&lt;/em&gt; is entered as &lt;em&gt;The Sun AlsoRises&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;AlsoRises&lt;/em&gt; is not an English word, but obviously both &lt;em&gt;Also&lt;/em&gt; and &lt;em&gt;Rises&lt;/em&gt; are. Finding words within this string can be done using the following algorithm:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Choose a list of words to search for. This could be the whole English dictionary, or anything, really.&lt;/li&gt;
&lt;li&gt;Sort these words in descending order of word length.&lt;/li&gt;
&lt;li&gt;Look for each word and skip to the next unassigned slot when you find a match.&lt;/li&gt;
&lt;li&gt;Any non-matching characters should be kept.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is an implementation of this algorithm. Ideally this would remember the disregarded tokens and wouldn&amp;#8217;t lowercase everything, but as a proof of concept that is not necessary:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Demungler&lt;/span&gt; &lt;/span&gt;{

  &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $parts = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
  &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $shortest_word_length = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;

  &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getDemungledString&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($string, $separator = &lt;span class=&quot;string&quot;&gt;' '&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;{
    $string = strtolower($string);
    $parts = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    $tokens = token_get_all(&lt;span class=&quot;string&quot;&gt;'&amp;amp;lt;?php '&lt;/span&gt; . $string);
    &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($tokens &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $token) {
      &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;($token[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]) &amp;amp;&amp;amp; $token[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;] == &lt;span class=&quot;number&quot;&gt;307&lt;/span&gt;) {
        $parts[] = $token[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;];
      }
    }
    $output = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();


    &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($parts &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $part) {

      $current_partial_word = &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;;
      $limit = strlen($part) ;- &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;shortest_word_length;
      &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt;($i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; $i &amp;amp;lt; $limit; $i++) {
        $add_char = &lt;span class=&quot;keyword&quot;&gt;true&lt;/span&gt;;
        &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;words &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $word) {
          $search_string = substr($part, $i, strlen($word));

          &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($search_string == $word) {

            $i += strlen($word) - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($current_partial_word != &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;) {
              $output[] = $current_partial_word;
              $current_partial_word = &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;;
            }
            $output[] = $word;
            $add_char = &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;;
            &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;;
          }
        }
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($add_char) {
          $current_partial_word .= $part[$i];
        }
      }
      &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!&lt;span class=&quot;keyword&quot;&gt;empty&lt;/span&gt;($current_partial_word)) {
        $output[] = $current_partial_word;
      }

    }

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; implode($separator, $output);
  }

  &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;setDictionary&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($words)&lt;/span&gt; &lt;/span&gt;{
    $words = array_map(&lt;span class=&quot;string&quot;&gt;'strtolower'&lt;/span&gt;, $words);
    usort($words, &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;($a, $b)&lt;/span&gt; &lt;/span&gt;{
      &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; strlen($a) &amp;amp;lt; strlen($b);
    });
    &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;shortest_word_length = strlen($words[count($words) - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]);
    &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;words = $words;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is a test of it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$d = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Demungler();
$d-&amp;gt;setDictionary(
  &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'a'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'are'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'fun'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'of'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'is'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'test'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'tests'&lt;/span&gt;,
  &lt;span class=&quot;string&quot;&gt;'the'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'this'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'tokens'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'too'&lt;/span&gt;)
);
$s = $d-&amp;gt;getDemungledString(&lt;span class=&quot;string&quot;&gt;'thisburgleisatestess ofthedemungler.;tokensarefuntestsarefuntoo'&lt;/span&gt;);
&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;$sn&quot;&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The output of which is&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;this burgle is a test ess of the demungler tokens are fun tests are fun too&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note: It&amp;#8217;s possible that you could find the wrong words using this algorithm. E.g. given the input &amp;#8220;visiteductionalattractions&amp;#8221;, the result would be &amp;#8220;visited u cat ion al attractions&amp;#8221;, instead of the intended &amp;#8220;visit educational attractions&amp;#8221;. The only way to fix this would be to try a variety of different words, when more than one fits, then complete the algorithm for each possibility, and see which result maximizes the average word length and the number of found words. Even so, you&amp;#8217;re left in a best guess situation with many different possibilities.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>A timer class</title>
      <link>http://localhost:8080/articles/a-timer-class/</link>
      <pubDate>Sun, 08 Sep 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/a-timer-class/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;It&amp;#8217;s often useful to time aspects of your applications. In environments without access to profiling tools like xdebug, it is necessary to roll your own. Here&amp;#8217;s one that relies heavily on calls to &lt;code&gt;microtime&lt;/code&gt;. Unfortunately making many thousands of calls to &lt;code&gt;microtime&lt;/code&gt; takes a significant amount of time on its own.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;But a manual timing class like this can still be quite useful in identifying problem blocks of code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Timer&lt;/span&gt; &lt;/span&gt;{

    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $starts = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $calls = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();

    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $times = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($identifier)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!&lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;calls[$identifier])) {
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;calls[$identifier] = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
        }
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;calls[$identifier]++;
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;starts[$identifier] = microtime(&lt;span class=&quot;keyword&quot;&gt;true&lt;/span&gt;);
    }

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;stop&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($identifier)&lt;/span&gt; &lt;/span&gt;{
        $end = microtime(&lt;span class=&quot;keyword&quot;&gt;true&lt;/span&gt;);
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!&lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;times[$identifier])) {
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;times[$identifier] = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
        }
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;times[$identifier] += ($end - &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;starts[$identifier]);
    }

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getTimes&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;times;
    }

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getCallCounts&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;calls;
    }

}&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>A NavigableMap inspired class for PHP</title>
      <link>http://localhost:8080/articles/a-navigablemap-inspired-class-for-php/</link>
      <pubDate>Sun, 25  Aug 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/a-navigablemap-inspired-class-for-php/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Java has a nifty class named &lt;a href=&quot;http://docs.oracle.com/javase/6/docs/api/java/util/NavigableMap.html&quot;&gt;&lt;code&gt;NavigableMap&lt;/code&gt;&lt;/a&gt;. It abstracts away some of the logic for mapping ranges to values. Java is reknowned for it’s ridiculously large library of collections.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a PHP implementation of some of its functionality.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;NavigableMap&lt;/span&gt; &lt;/span&gt;{
  &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $data = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
  &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;checkKeyNumeric&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($key)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_numeric($key)) {
      &lt;span class=&quot;keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;Exception&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;keys must be numeric. Given $key&quot;&lt;/span&gt;);
    }
  }
  &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($key, $value)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;checkKeyNumeric($key);
    &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;data[$key] = $value;
    ksort(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;data);
  }
  &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;firstEntry&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; key(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;data);
  }
  &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;lastEntry&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
    $end = key(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;data);
    reset(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;data);
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $end;
  }
  &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;floorEntry&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($point)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;data[&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;floorKey($point)];
  }
  &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;floorKey&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($point)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;checkKeyNumeric($point);
    $lowest = &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;firstEntry();
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($lowest &amp;amp;gt; $point) {
      &lt;span class=&quot;keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; OutOfBoundsException(&lt;span class=&quot;string&quot;&gt;&quot;no point exists &quot;&lt;/span&gt; .
            &lt;span class=&quot;string&quot;&gt;&quot;below $point. Lowest map entry is $lowest&quot;&lt;/span&gt;);
    }
    &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;data &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $key =&amp;amp;gt; $value) {
      &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($key &amp;amp;gt; $point) {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $previous_key;
      }
      $previous_key = $key;
    }
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $previous_key;
  }
  &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;ceilingEntry&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($point)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;data[&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;ceilingKey($point)];
  }
  &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;ceilingKey&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($point)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;checkKeyNumeric($point);
    $highest = &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;lastEntry();
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($highest &amp;amp;lt; $point) {
      &lt;span class=&quot;keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; OutOfBoundsException(&lt;span class=&quot;string&quot;&gt;&quot;no point exists &quot;&lt;/span&gt; .
            &lt;span class=&quot;string&quot;&gt;&quot;above $point. Highest map entry is $highest&quot;&lt;/span&gt;);
    }
    $keys = array_reverse(array_keys(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;data));
    &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($keys &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $key) {
      &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($key &amp;amp;lt; $point) {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $previous_key;
      }
      $previous_key = $key;
    }
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $previous_key;
  }
}&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>A Bloom Filter in c#</title>
      <link>http://localhost:8080/articles/a-bloom-filter-in-c/</link>
      <pubDate>Thu, 15  Aug 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/a-bloom-filter-in-c/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;A &lt;a href=&quot;http://en.wikipedia.org/wiki/Bloom_filter&quot;&gt;bloom filter&lt;/a&gt; is a probabilistic data structure meant for checking whether a given entry does not occur in a list. It is meant to be quite fast, and is used as a way of not doing costly queries when it can be determined that no results will be returned. E.g., if you could turn this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;costly_lookup(key)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Into this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (!cheap_check_that_key_isnt_there()) {
    costly_lookup()
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then that&amp;#8217;s a win.
&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;
The way that a bloom filter goes about this is by performing a series of &lt;code&gt;k&lt;/code&gt; hashes that return a value between 0 and  &lt;code&gt;n&lt;/code&gt; (in my example code below I use  &lt;code&gt;k=2&lt;/code&gt; and &lt;code&gt;m=32&lt;/code&gt;). When you add a value to your heavy data store, you will also run each of these hashes and store the return values in the bloom filters master list of returned values. Then when you want to see if something is in there, you run it through all of your hashes; if a value is returned that isn&amp;#8217;t in your list of previous hash results you know that the new entry isn&amp;#8217;t in your set. If only previously hashed values are returned the new item &lt;em&gt;may&lt;/em&gt; be in there.&lt;/p&gt;
&lt;p&gt;For a discussion of the rate of false positives, optimizing  &lt;code&gt;k&lt;/code&gt; and &lt;code&gt;m&lt;/code&gt;, and a more in-depth discussion of this issue, I recommend &lt;a href=&quot;http://billmill.org/bloomfilter-tutorial/&quot;&gt;Bloom Filters by Example&lt;/a&gt; by Bill Mill.&lt;/p&gt;
&lt;p&gt;As is usual on my blog, below I will outline the general concept of this data structure. You should note that the values of  &lt;code&gt;m&lt;/code&gt; and  &lt;code&gt;k&lt;/code&gt; are hard-coded here, and that the hashing functions &lt;code&gt;rotate&lt;/code&gt; and &lt;code&gt;rotateMore&lt;/code&gt; aren&amp;#8217;t proper hashing functions, they just illustrate the idea.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; System;
&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; System.Linq;
&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; System.Text;
&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; System.Collections;

&lt;span class=&quot;keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Bloom&lt;/span&gt;
{
    &lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Bloom&lt;/span&gt;
    {
        &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; BitArray bits = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; BitArray(&lt;span class=&quot;number&quot;&gt;32&lt;/span&gt;);

        &lt;span class=&quot;comment&quot;&gt;// two toy hashing functions,&lt;/span&gt;
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; Int16 &lt;span class=&quot;title&quot;&gt;rotateMore&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;String AddString&lt;/span&gt;)&lt;/span&gt;
        {
            Int16 ReturnValue = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
            &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; i &amp;amp;lt; AddString.Length; i++)
            {
                ReturnValue += (Int16)((&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt;)AddString[i] * i);
                ReturnValue = (Int16)(ReturnValue % &lt;span class=&quot;number&quot;&gt;32&lt;/span&gt;);
            }
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; ReturnValue;
        }

        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; Int16 &lt;span class=&quot;title&quot;&gt;rotate&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;String AddString&lt;/span&gt;)&lt;/span&gt;
        {
            Int16 ReturnValue = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
            &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; i &amp;amp;lt; AddString.Length; i++)
            {
                ReturnValue += (Int16) ((&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt;)AddString[i]);
                ReturnValue = (Int16) (ReturnValue % &lt;span class=&quot;number&quot;&gt;32&lt;/span&gt;);
            }
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; ReturnValue;
        }
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;add&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;String AddString&lt;/span&gt;)&lt;/span&gt;
        {
            Console.WriteLine(&lt;span class=&quot;string&quot;&gt;&quot;adding &quot;&lt;/span&gt; + AddString);

            Int16 Point1 = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.rotate(AddString);
            Int16 Point2 = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.rotateMore(AddString);
            &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.bits[Point1] = &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;;
            &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.bits[Point2] = &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;;

        }
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;contains&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;String CheckString&lt;/span&gt;)&lt;/span&gt;
        {
            Int16 Point1 = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.rotate(CheckString);
            Int16 Point2 = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.rotateMore(CheckString);
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.bits[Point1] &amp;amp;&amp;amp; &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.bits[Point2])
            {
                &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;;
            }
            &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;
            {
                &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;false&lt;/span&gt;;
            }
        }
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;checkFor&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;String key&lt;/span&gt;)&lt;/span&gt;
        {
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.contains(key))
            {
                Console.WriteLine(key + &lt;span class=&quot;string&quot;&gt;&quot; may be in there&quot;&lt;/span&gt;);
            }
            &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;
            {
                Console.WriteLine(key + &lt;span class=&quot;string&quot;&gt;&quot; is not there&quot;&lt;/span&gt;);
            }
        }
    }

    &lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Program&lt;/span&gt;
    {
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Main&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;string&lt;/span&gt;[] args&lt;/span&gt;)&lt;/span&gt;
        {
            Bloom bloom = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Bloom();
            bloom.&lt;span class=&quot;keyword&quot;&gt;add&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;string&quot;&lt;/span&gt;);
            bloom.&lt;span class=&quot;keyword&quot;&gt;add&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;fresh&quot;&lt;/span&gt;);
            bloom.&lt;span class=&quot;keyword&quot;&gt;add&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;basketball&quot;&lt;/span&gt;);
            bloom.checkFor(&lt;span class=&quot;string&quot;&gt;&quot;basketball&quot;&lt;/span&gt;);
            bloom.checkFor(&lt;span class=&quot;string&quot;&gt;&quot;soccer&quot;&lt;/span&gt;);
            Console.ReadLine();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The output of this will be:&lt;/p&gt;
&lt;pre&gt;adding string
adding fresh
adding basketball
basketball may be in there
soccer is not there
&lt;/pre&gt;

</description>
    </item>
    <item>
      <title>Skip List Implementation in PHP</title>
      <link>http://localhost:8080/articles/skip-list-implementation-in-php/</link>
      <pubDate>Mon, 12  Aug 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/skip-list-implementation-in-php/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;A skip list is similar to a linked list, but it is always sorted and maintains multiple pointers. The multiple pointers allow fast traversal of the list so that you can quickly look for elements, essentially performing a binary search on the data.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;more&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s an implementation of skip list in PHP:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;meta&quot;&gt;&amp;lt;?php&lt;/span&gt; 
&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;SkipList&lt;/span&gt; &lt;/span&gt;{

    &lt;span class=&quot;comment&quot;&gt;// # implement a skip list with a given depth.&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # this data structure is used to rapidly search&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # through a multiply-linked (sorted) list,&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # mimicking the functionality of a binary&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # sort using references.&lt;/span&gt;

    &lt;span class=&quot;comment&quot;&gt;// # The private properties here are the first&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # node and the depth, which is the number&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # of levels of references to maintain.&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # E.g. a depth of 3 will maintain 3 levels of&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # pointers, so that each subsequent level of&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # reference will allow for more fine-grained&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # access than the one before.&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $_first = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $_depth = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;

    &lt;span class=&quot;comment&quot;&gt;// # We construct with an array. This is then&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # sorted (so use a sortable array) and references&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # are made for the given or predefined depth.&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($list, $depth = null)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_array($list)) {
            &lt;span class=&quot;keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;Exception&lt;/span&gt;(
                &lt;span class=&quot;string&quot;&gt;'SkipList constructor called with invalid list parameter'&lt;/span&gt;
            );
        }
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_numeric($depth)) {
            &lt;span class=&quot;keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;Exception&lt;/span&gt;(
                &lt;span class=&quot;string&quot;&gt;'SkipList constructor called with invalid depth parameter'&lt;/span&gt;
            );
        }
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_depth = $depth;
        sort($list);
        &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($list &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $lkey =&amp;gt; $item) {
            $list[$lkey] = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; SkipListNode($item);
        }
        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; $i &amp;lt; $depth; $i++) {
            &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($j = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; $j &amp;lt; count($list) / pow(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, $i); $j++) {
                $index = $j * pow(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, $i);
                $next_index = ($j + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;) * pow(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, $i);
                $next_node = &lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;($list[$next_index]) ?
                    $list[$next_index] : &lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;;
                $list[$index]-&amp;gt;setNext($next_node, $i);
            }
        }
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_first = $list[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;];
    }

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getFirst&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_first;
    }

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getDepth&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_depth;
    }

    &lt;span class=&quot;comment&quot;&gt;// # for a perfect skip-list implementation you'd&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # reweight the references every so often, so&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # that you don't end up with giant amounts of&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # data between two references and very little&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # between others. This implementation does not&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # do that.&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;insertValue&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($value)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;comment&quot;&gt;// inserts the value at the lowest level.&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;// ideally you'd shuffle everything around&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;// once in a while to ensure it's still efficient.&lt;/span&gt;
        $new_node = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; SkipListNode($value);
        $node = &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_first;
        &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; {
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;) {
                 &lt;span class=&quot;string&quot;&gt;&quot;oops never implemented. lol&quot;&lt;/span&gt;;
            } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
                $node = $node-&amp;gt;getNext(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;);
            }
        } &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; ($node != &lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;);
    }

    &lt;span class=&quot;comment&quot;&gt;// # The whole point of this is to be able to tell quickly&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// # whether or not a list contains a given value.&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($value)&lt;/span&gt; &lt;/span&gt;{
        $found = &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;;
        $node = &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_first;
        $depth = &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_depth - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
        &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; {
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($node-&amp;gt;getValue() == $value) {
                $found = $node;
            } &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($node-&amp;gt;getValue() &amp;gt; $value) {
                &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;;
            } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($node-&amp;gt;getNext($depth) != &lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt; &amp;amp;&amp;amp; $node-&amp;gt;getNext($depth)-&amp;gt;getValue() &amp;gt; $value) {
                $depth--;
                &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;;
            } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
                $node = $node-&amp;gt;getNext($depth);
            }
        } &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; ($depth &amp;gt;= &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; &amp;amp;&amp;amp; $node != &lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;);

        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $found;
    }

}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;SkipListNode&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $_value;
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $_nexts = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($value)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_value = $value;
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getValue&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_value;
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getNext&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($depth)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_nexts[$depth];
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;setNext&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($node, $depth)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_nexts[$depth] = $node;
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($value)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;setValue($value);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example Usage:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$array = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'this'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'is'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'a'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'way'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'to'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'test'&lt;/span&gt;);
$depth = &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;;
$list = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; SkipList($array, $depth);
&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($list-&amp;gt;contains(&lt;span class=&quot;string&quot;&gt;'is'&lt;/span&gt;)) {
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;list contains 'is'.n&quot;&lt;/span&gt;;
}&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Finding near-solutions to Fermat’s Last Theorem in C#</title>
      <link>http://localhost:8080/articles/finding-near-solutions-to-fermats-last-theorem-in-c/</link>
      <pubDate>Thu, 25 Jul 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/finding-near-solutions-to-fermats-last-theorem-in-c/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Fermat%27s_Last_Theorem&quot;&gt;Fermat&amp;#8217;s Last Theorem&lt;/a&gt; States that there are no non-trivial integer solutions solutions to the equation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
x^{n} + y^{n} = z^{n}, n &amp;gt; 2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This theorem went unproven for centuries, and was proven to be true in 1995 by Andrew Wiles. The &lt;a href=&quot;http://en.wikipedia.org/wiki/Treehouse_of_Horror_VI&quot;&gt;Treehouse of Horror VI&lt;/a&gt; episode of the Simpsons aired the same year. People with a keen interest in humourous background gags could have done a freeze frame and seen the following (&lt;a href=&quot;http://www.ohohlfeld.com/simpsonsmath.html&quot;&gt;source&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/finding-near-solutions-to-fermats-last-theorem-in-c/fermat.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;The gag here is that if you punched in  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1782&lt;sup&gt;12&lt;/sup&gt; + 1841&lt;sup&gt;12&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;to a pocket calculator, you would get the same answer as if you punched in:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1922&lt;sup&gt;12&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt; So this equation would seem to be true, but it&amp;#8217;s not. It&amp;#8217;s just really close, and the reason you see the same number is due to floating point rounding. I.e. it&amp;#8217;s not actually true, but it&amp;#8217;s close enough to fool the calculators of the day. Sadly I don&amp;#8217;t know who found this near-solution to give credit. I remember hearing a commentary by David X. Cohen, who is a mathematician and writer for The Simpsons and Futurama, mentioned some details about this.&lt;/p&gt;
&lt;p&gt;Finding near-solutions to FLT is actually quite easy though. You just have to do a brute force search and you can output whatever numbers you find that are close enough to what you are looking for. Just define your ranges of exponents and bases and loop through, looking for solutions that match a certain threshold. Here&amp;#8217;s an example written in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; System;
&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; System.Linq;
&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; System.Text;

&lt;span class=&quot;keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;ConsoleApplication1&lt;/span&gt;
{
    &lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Program&lt;/span&gt;
    {
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Main&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;string&lt;/span&gt;[] args&lt;/span&gt;)&lt;/span&gt;
        {

            &lt;span class=&quot;keyword&quot;&gt;string&lt;/span&gt; lookingFor = &lt;span class=&quot;string&quot;&gt;&quot;.00000000&quot;&lt;/span&gt;;
            &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;double&lt;/span&gt; exponent = &lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;; exponent &amp;amp;lt; &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;; exponent++)
            {

                &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;double&lt;/span&gt; doing = &lt;span class=&quot;number&quot;&gt;701&lt;/span&gt;; doing &amp;amp;lt; &lt;span class=&quot;number&quot;&gt;20002&lt;/span&gt;; doing++)
                {

                    &lt;span class=&quot;keyword&quot;&gt;double&lt;/span&gt; result = Math.Pow(doing, exponent);

                    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;double&lt;/span&gt; x = Math.Floor(doing * &lt;span class=&quot;number&quot;&gt;0.5&lt;/span&gt;); x &amp;amp;lt; Math.Floor(doing * &lt;span class=&quot;number&quot;&gt;.95&lt;/span&gt;); x++)
                    {
                        &lt;span class=&quot;keyword&quot;&gt;double&lt;/span&gt; y1 = Math.Ceiling(Math.Pow(result - Math.Pow(x, exponent), &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; / exponent));
                        &lt;span class=&quot;keyword&quot;&gt;double&lt;/span&gt; y2 = Math.Floor(Math.Pow(result - Math.Pow(x, exponent), &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; / exponent));

                        &lt;span class=&quot;comment&quot;&gt;// check the high number&lt;/span&gt;
                        &lt;span class=&quot;keyword&quot;&gt;double&lt;/span&gt; sum = Math.Pow(Math.Pow(y1, exponent) + Math.Pow(x, exponent), &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; / exponent);
                        &lt;span class=&quot;keyword&quot;&gt;string&lt;/span&gt; sumstring = sum.ToString();
                        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (sumstring.IndexOf(lookingFor) &amp;amp;gt; &lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;)
                        {
                            Console.WriteLine(doing + &lt;span class=&quot;string&quot;&gt;&quot;^&quot;&lt;/span&gt; + exponent + &lt;span class=&quot;string&quot;&gt;&quot; = &quot;&lt;/span&gt; + x + &lt;span class=&quot;string&quot;&gt;&quot;^&quot;&lt;/span&gt; + exponent + &lt;span class=&quot;string&quot;&gt;&quot; + &quot;&lt;/span&gt; + y1 + &lt;span class=&quot;string&quot;&gt;&quot;^&quot;&lt;/span&gt; + exponent + &lt;span class=&quot;string&quot;&gt;&quot;, actually: &quot;&lt;/span&gt; + sumstring);
                        }

                        &lt;span class=&quot;comment&quot;&gt;// then the low.&lt;/span&gt;
                        sum = Math.Pow(Math.Pow(y2, exponent) + Math.Pow(x, exponent), &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; / exponent);
                        sumstring = sum.ToString();
                        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (sumstring.IndexOf(lookingFor) &amp;amp;gt; &lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;)
                        {
                            Console.WriteLine(doing + &lt;span class=&quot;string&quot;&gt;&quot;^&quot;&lt;/span&gt; + exponent + &lt;span class=&quot;string&quot;&gt;&quot; = &quot;&lt;/span&gt; + x + &lt;span class=&quot;string&quot;&gt;&quot;^&quot;&lt;/span&gt; + exponent + &lt;span class=&quot;string&quot;&gt;&quot; + &quot;&lt;/span&gt; + y2 + &lt;span class=&quot;string&quot;&gt;&quot;^&quot;&lt;/span&gt; + exponent + &lt;span class=&quot;string&quot;&gt;&quot;, actually: &quot;&lt;/span&gt; + sumstring);
                        }
                    }
                }
            }

            Console.ReadLine();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And doing this you can find some interesting near-solutions like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[

19639^{11} = 15797^{11} + 19469^{11}, actually: 19639.0000000074

]

[

4472^{12} = 3987^{12} + 4365^{12}, actually: 4472.00000000706

]

[

14051^{13} = 11184^{13} + 13994^{13}, actually: 14051.0000000076

]
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>A demonstration of the usefulness of Memoization in Lua</title>
      <link>http://localhost:8080/articles/a-demonstration-of-the-usefulness-of-memoization-in-lua/</link>
      <pubDate>Tue, 23 Jul 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/a-demonstration-of-the-usefulness-of-memoization-in-lua/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Memoization&quot;&gt;Memoization&lt;/a&gt; is a programming technique where you save expensive 
computations in memory to speed up function execution time. E.g. If 
you were writing a CMS and you wanted a &lt;code&gt;getSignedInUserName()&lt;/code&gt; 
method, you wouldn’t want to make two database calls to show 
the user name at the top and bottom of the page, so you’d save 
it in memory for use later.&lt;/p&gt;
&lt;p&gt;My canonical example of the speed increase you can get from this technique is with a Fibonacci calculator. Here is a non-optimized version:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lua&quot;&gt;fib = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(n)&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; n==&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;or&lt;/span&gt; n==&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; fib(n&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;)+fib(n&lt;span class=&quot;number&quot;&gt;-2&lt;/span&gt;)
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;built_in&quot;&gt;print&lt;/span&gt;(fib(&lt;span class=&quot;number&quot;&gt;40&lt;/span&gt;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This takes about 22 seconds to run on my development machine. Here’s a rewritten calculator that uses memoization:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lua&quot;&gt;results = {}
fib = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(n)&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; results[n] &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; results[n]
    &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; n==&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;or&lt;/span&gt; n==&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt;
            result = &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;
            result = fib(n&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;)+fib(n&lt;span class=&quot;number&quot;&gt;-2&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        results[n] = result
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; result
    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;built_in&quot;&gt;print&lt;/span&gt;(fib(&lt;span class=&quot;number&quot;&gt;40&lt;/span&gt;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This finishes in well under one second. In fact, calling the memoized function with fib(100) finishes in under a second too. The real benefit here is that you aren’t clogging up your call stack with hundreds of thousands of calls, each waiting on other calls. By having previous results on hand, the function can easily move on to the next step.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Parsing mathematical expressions and calculating the result</title>
      <link>http://localhost:8080/articles/parsing-mathematical-expressions-and-calculating-the-result/</link>
      <pubDate>Thu, 18 Jul 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/parsing-mathematical-expressions-and-calculating-the-result/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Given a string like &lt;code&gt;2 * 2 + 2&lt;/code&gt;, how would you calculate the value? It&amp;#8217;s necessary to tokenize the string, parse those tokens, and apply the order of operations to the parsed data.&lt;/p&gt;
&lt;p&gt;Here is the function to throw a string at.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php

function calculate($input) {
    $tokens = tokenize($input);
    $parsed = parse_tokens($tokens);
    $result = calculate_from_parsed($parsed);
    return $result;
}
&amp;lt;/pre&amp;gt;

And I just rely on PHP&amp;amp;#8217;s built in tokenizer, which I throw a wrapper around.

&amp;lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&amp;gt;function tokenize($input) {

    $tokens = token_get_all(&quot;&amp;lt;?php $input&quot;);
    return $tokens;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So here is the first function that really does anything. Note that only pedmas rules are followed. The parser doesn&amp;#8217;t deal with anything like exponentiation, trig functions, etc.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;parse_tokens&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($tokens)&lt;/span&gt; &lt;/span&gt;{

    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_array($tokens)) {
        &lt;span class=&quot;comment&quot;&gt;// invalid input.&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;;
    }

    $expecting = &lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;;

    $parsed_tokens = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    $skip_to = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;

    &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($tokens &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $token_number =&amp;gt; $token) {
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($token_number &amp;lt; $skip_to) &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;;
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (is_array($token) &amp;amp;&amp;amp; &lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;($token[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;])) {
            &lt;span class=&quot;keyword&quot;&gt;switch&lt;/span&gt;($token[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]) {
                &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;305&lt;/span&gt; :
                &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;306&lt;/span&gt; :
                    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_null($expecting) &amp;amp;&amp;amp; $expecting != &lt;span class=&quot;string&quot;&gt;'number'&lt;/span&gt;) {
                        &lt;span class=&quot;keyword&quot;&gt;exit&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'error 1: unexpected token '&lt;/span&gt; . print_r($token, &lt;span class=&quot;keyword&quot;&gt;true&lt;/span&gt;) . &lt;span class=&quot;string&quot;&gt;&quot;nn&quot;&lt;/span&gt;);
                    }
                    $expecting = &lt;span class=&quot;string&quot;&gt;'operator'&lt;/span&gt;;
                    $parsed_tokens[] = $token[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;];
                &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;372&lt;/span&gt;:
                &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;375&lt;/span&gt;:
                    &lt;span class=&quot;comment&quot;&gt;// whitespace&lt;/span&gt;
                    &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;;

                &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt; :
                    &lt;span class=&quot;keyword&quot;&gt;exit&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'error: unhandled token '&lt;/span&gt; . print_r($token, &lt;span class=&quot;keyword&quot;&gt;true&lt;/span&gt;) . &lt;span class=&quot;string&quot;&gt;&quot;nn&quot;&lt;/span&gt;);
            }
        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {

            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_null($expecting) &amp;amp;&amp;amp; $expecting != &lt;span class=&quot;string&quot;&gt;'operator'&lt;/span&gt; &amp;amp;&amp;amp; $token != &lt;span class=&quot;string&quot;&gt;'('&lt;/span&gt; &amp;amp;&amp;amp; $token != &lt;span class=&quot;string&quot;&gt;')'&lt;/span&gt;) {
                &lt;span class=&quot;keyword&quot;&gt;exit&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'error 2: unexpected token '&lt;/span&gt; . print_r($token, &lt;span class=&quot;keyword&quot;&gt;true&lt;/span&gt;) . &lt;span class=&quot;string&quot;&gt;&quot;nn&quot;&lt;/span&gt;);
            }
            &lt;span class=&quot;keyword&quot;&gt;switch&lt;/span&gt;($token) {
                &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'('&lt;/span&gt; : 

                    $new_tokens = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
                    $parentheses_count = &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
                    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($i = $token_number + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;; $i &amp;lt; count($tokens); $i++) {
                        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($tokens[$i] == &lt;span class=&quot;string&quot;&gt;'('&lt;/span&gt;) {
                            $parentheses_count ++;

                        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($tokens[$i] == &lt;span class=&quot;string&quot;&gt;')'&lt;/span&gt;) {
                            $parentheses_count --;
                        }

                        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($parentheses_count != &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
                            $new_tokens[] = $tokens[$i];
                        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
                            $skip_to = $i;
                            $expecting = &lt;span class=&quot;string&quot;&gt;'operator'&lt;/span&gt;;
                            &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;;
                        }
                    }

                    $parsed_tokens[] = parse_tokens($new_tokens);
                    $expecting = &lt;span class=&quot;string&quot;&gt;'operator'&lt;/span&gt;;
                    &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;;
                &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'+'&lt;/span&gt; :
                &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'-'&lt;/span&gt; :
                &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'*'&lt;/span&gt; :
                &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'/'&lt;/span&gt; :
                    $parsed_tokens[] = $token;
                    $expecting = &lt;span class=&quot;string&quot;&gt;'number'&lt;/span&gt;;
                    &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;;
            }
        }

    }
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $parsed_tokens;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now run through the parsed tokens, apply the order of operations, and run until there is a result.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;calculate_from_parsed&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($parsed_tokens)&lt;/span&gt; &lt;/span&gt;{

    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (count($parsed_tokens) == &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; &amp;amp;&amp;amp; !is_array($parsed_tokens[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;])) {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $parsed_tokens[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;];
    } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (count($parsed_tokens) == &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; &amp;amp;&amp;amp; is_array($parsed_tokens[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;])) {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; calculate_from_parsed($parsed_tokens[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;]);
    } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
        &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($parsed_tokens &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $token_number =&amp;gt; $parsed_token) {
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (is_array($parsed_token)) {
                $parsed_tokens[$token_number] = calculate_from_parsed($parsed_token);
            }
        }

        &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; (count($parsed_tokens) &amp;gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;) {
            $continue = &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;;
            &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($parsed_tokens &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $token_number =&amp;gt; $parsed_token) {
                $previous_token_pair = get_previous_token_pair($parsed_tokens, $token_number);
                $previous_token = $previous_token_pair[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;];
                $previous_token_index = $previous_token_pair[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;];
                &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($parsed_token == &lt;span class=&quot;string&quot;&gt;'*'&lt;/span&gt; || $parsed_token == &lt;span class=&quot;string&quot;&gt;'/'&lt;/span&gt;) {
                    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($parsed_token == &lt;span class=&quot;string&quot;&gt;'*'&lt;/span&gt;) {
                        $parsed_tokens[$token_number] = $previous_token * $parsed_tokens[$token_number + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;];
                        &lt;span class=&quot;keyword&quot;&gt;unset&lt;/span&gt;($parsed_tokens[$previous_token_index], $parsed_tokens[$token_number + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]);
                        $continue = &lt;span class=&quot;keyword&quot;&gt;true&lt;/span&gt;;
                        &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;;
                    } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($parsed_token == &lt;span class=&quot;string&quot;&gt;'/'&lt;/span&gt;) {
                        $parsed_tokens[$token_number] = $previous_token / $parsed_tokens[$token_number + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;];
                        &lt;span class=&quot;keyword&quot;&gt;unset&lt;/span&gt;($parsed_tokens[$previous_token_index], $parsed_tokens[$token_number + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]);
                        $continue = &lt;span class=&quot;keyword&quot;&gt;true&lt;/span&gt;;
                        &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;;
                    }
                }
            }
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($continue) &lt;span class=&quot;keyword&quot;&gt;continue&lt;/span&gt;;

            $parsed_tokens = array_values($parsed_tokens);

            &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($parsed_tokens &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $token_number =&amp;gt; $parsed_token) {
                $previous_token_pair = get_previous_token_pair($parsed_tokens, $token_number);
                $previous_token = $previous_token_pair[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;];
                $previous_token_index = $previous_token_pair[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;];
                &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($parsed_token == &lt;span class=&quot;string&quot;&gt;'+'&lt;/span&gt; || $parsed_token == &lt;span class=&quot;string&quot;&gt;'-'&lt;/span&gt;) {
                    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($parsed_token == &lt;span class=&quot;string&quot;&gt;'+'&lt;/span&gt;) {
                        $parsed_tokens[$token_number] = $previous_token + $parsed_tokens[$token_number + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;];
                        &lt;span class=&quot;keyword&quot;&gt;unset&lt;/span&gt;($parsed_tokens[$previous_token_index], $parsed_tokens[$token_number + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]);
                        &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;;
                    } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($parsed_token == &lt;span class=&quot;string&quot;&gt;'-'&lt;/span&gt;) {
                        $parsed_tokens[$token_number] = $previous_token - $parsed_tokens[$token_number + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;];
                        &lt;span class=&quot;keyword&quot;&gt;unset&lt;/span&gt;($parsed_tokens[$previous_token_index], $parsed_tokens[$token_number + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]);
                        &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;;
                    }
                }
            }

            $parsed_tokens = array_values($parsed_tokens);
        }
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (count($parsed_tokens) == &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;) {
            $parsed_tokens = array_values($parsed_tokens);
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $parsed_tokens[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;];
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And since we pop results out of the array as we go we need a helper function for retrieving the previous populated element in an array.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_previous_token_pair&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($tokens, $token_number)&lt;/span&gt; &lt;/span&gt;{
    $return = &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($i = $token_number - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;; $i &amp;gt; &lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;; $i--) {
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;($tokens[$i])) {
            $return = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;($tokens[$i], $i);
            &lt;span class=&quot;keyword&quot;&gt;break&lt;/span&gt;;
        }
    }
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $return;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is a little test suite, all of which pass:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$tests = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'(1.1 + ((1)))'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;2.1&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'2 + 2'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'1 + 1 + 1 + 1 + 1    + 1 + 1 + 1 + 1 + 1      + 1 +1 + 1 + 1 + 1'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'2*(1 + 1 + 1 + 1 + 1)    + 3*(1 + 1 + 1 + 1 + 1)      + 4*(1 +1 + 1 + 1 + 1)'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;45&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'(1 + 1 + 1 + 1 + 1)*2 + (1 + 4)*3 + (1 +1 + .5+.5 + 1 + 1)*5'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;50&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'2 * 2'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'2 * (1-1)'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'2 * 2 + 2'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;6&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'2+ 2 * 2'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;6&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'(2+ 2) * 2 + 2'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'(2+ 3 + 1) / 3 + 7'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;9&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'2+ 2 * 2 + 2'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'729 / 3 / 3 / 3 / 3'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;9&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'729 / 3 / (3 / 3) / 3'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;81&lt;/span&gt;),
    &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'2 + 1'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;)
);

&lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($tests &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $test) {
    $input = $test[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;];
    &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;$input = &quot;&lt;/span&gt;;
    $result = $test[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;];
    $generated_result = calculate($input);
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($generated_result == $result) {
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;$generated_result passedn&quot;&lt;/span&gt;;
    } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;$generated_result &amp;lt;-- FAILEDn&quot;&lt;/span&gt;;
    }
}
&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Viable promises in PHP using pthreads</title>
      <link>http://localhost:8080/articles/viable-promises-in-php-using-pthreads/</link>
      <pubDate>Tue, 09 Jul 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/viable-promises-in-php-using-pthreads/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I&amp;#8217;ve looked at making promises in PHP before, &lt;a href=&quot;http://benwendt.ca/blog/?p=85&quot;&gt;but it was a bit pointless due to PHP&amp;#8217;s synchronous nature&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But PHP isn’t necessarily synchronous. You can add threading capabilities by installing &lt;a href=&quot;https://github.com/krakjoe/pthreads/&quot;&gt;pthreads&lt;/a&gt;. Using this library it is possible to set up functioning promises (with a few limitations) in PHP.&lt;/p&gt;
&lt;p&gt;Pthreads supports stacking threads, which is essentially a promise. As such, this blog post is essentially a rehash of any of the &lt;a href=&quot;https://github.com/krakjoe/pthreads/blob/master/examples/Stacking.php&quot;&gt;pthreads examples of &lt;code&gt;Stackable&lt;/code&gt;&lt;/a&gt;. The basic idea is to set up a class that inherits from &lt;code&gt;Worker&lt;/code&gt;, initialize an instance, start it going, then stack on an instance of a class inheriting from &lt;code&gt;Stackable&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;My implementation of this pattern will allow the passing of arbitrary functions to these classes, which is what the promise pattern is all about. It works, but there is a limitation. You can pass function names in (e.g. &lt;code&gt;count_to_a_million&lt;/code&gt;), but not closures (e.g &lt;code&gt;function() {echo &amp;quot;foo&amp;quot;;}&lt;/code&gt;). [Aside: for some reason PHP calls anonymous functions closures even though they are only related concepts.] It appears that pthreads has some hidden serialization of parameters going on under the hood, and PHP does not support serialization of closures. Because of this, my implementation only supports the passing of function names (although it could be modified to accept parameters as well, as those could be serializable).&lt;/p&gt;
&lt;p&gt;Here are the classes:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;meta&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;PromiseClass&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Worker&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $_promise = &lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        $func = &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_promise;
        $func();
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($promise)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_promise = $promise;
    }
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;ThenClass&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Stackable&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $_promise = &lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($promise)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_promise = $promise;
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        $func = &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_promise;
        $func();
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see &lt;code&gt;PromiseClass&lt;/code&gt; and &lt;code&gt;ThenClass&lt;/code&gt; have the same extended properties and methods, but are based on different classes.&lt;/p&gt;
&lt;p&gt;Here is how to use these classes to implement Promises in PHP:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;then_function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;and then...n&quot;&lt;/span&gt;;
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;promise_function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;promise function called...n&quot;&lt;/span&gt;;
}

$promiser = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; PromiseClass(&lt;span class=&quot;string&quot;&gt;'promise_function'&lt;/span&gt;);

$then = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; ThenClass(&lt;span class=&quot;string&quot;&gt;'then_function'&lt;/span&gt;);

$promiser-&amp;gt;start();
$promiser-&amp;gt;stack($then);

&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; $i &amp;lt; &lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;; $i++) {
    &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;testn&quot;&lt;/span&gt;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The output for the above example should be something like the following (the outputs of &amp;#8220;test&amp;#8221; are there to show that this work is asynchronous):&lt;/p&gt;
&lt;pre&gt;promise function called...
test
test
...
test
and then...
test
test
...
&lt;/pre&gt;

&lt;p&gt;Promises are most useful as a means of waiting for data before performing an action with it. In that regard this is not an ideal solution as it would require some form of kludge. If PHP had proper closures it would be reasonable but in this form it would likely need to require use of the &lt;code&gt;global&lt;/code&gt; operator which is never nice.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Non-functional Sleep Sort Implemented in PHP using pthreads</title>
      <link>http://localhost:8080/articles/non-functional-sleep-sort-implemented-in-php-using-pthreads/</link>
      <pubDate>Sun, 07 Jul 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/non-functional-sleep-sort-implemented-in-php-using-pthreads/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;I&amp;#8217;ve looked at &lt;a href=&quot;http://benwendt.ca/blog/?p=124&quot;&gt;Sleep Sorting&lt;/a&gt; before. The basic idea is that each scalar in your collection to be sorted will be used as it&amp;#8217;s own weight, which is then used as the delay before outputting it as output.&lt;/p&gt;
&lt;p&gt;In a perfect world, all elements are sent to this time-based output buffer at the same instant, in which case the results will be accurate.&lt;/p&gt;
&lt;p&gt;When I did this before in javascript, the results were accurate because javascript is an asynchronous language. When you call &lt;code&gt;setInterval&lt;/code&gt;, other things can happen before that interval is complete.&lt;/p&gt;
&lt;p&gt;PHP is not asynchronous. You could imagine looping through a collection and calling &lt;code&gt;sleep&lt;/code&gt; before each &lt;code&gt;echo&lt;/code&gt; and that this would be a basic sleep sort implementation. This doesn&amp;#8217;t work because in PHP sleep is blocking. The result will be a script that waits the sum of the array seconds in total, and outputs the order unchanged.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;sleepcount&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($sleepnum)&lt;/span&gt; &lt;/span&gt;{
    sleep($sleepnum);
    &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;$sleepnumn&quot;&lt;/span&gt;;
}
&lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($nums &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $num){
    sleepcount($num);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are several methods of implementing threading in PHP. A beta PHP extension called &lt;a href=&quot;https://github.com/krakjoe/pthreads&quot;&gt;pthreads&lt;/a&gt; is one way to do this. Here&amp;#8217;s an implementation based on the &lt;a href=&quot;https://github.com/krakjoe/pthreads/blob/master/examples/CallAnyFunction.php&quot;&gt;pthreads Async example&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;sleepcount&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($sleepnum)&lt;/span&gt; &lt;/span&gt;{
    sleep($sleepnum);
    &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;$sleepnumn&quot;&lt;/span&gt;;
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Async&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Thread&lt;/span&gt; &lt;/span&gt;{

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($method, $params)&lt;/span&gt;&lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;method = $method;
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;params = $params;
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;result = &lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;;
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;joined = &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;;
    }

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;&lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ((&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;result=call_user_func_array(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;method, &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;params))) {
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;true&lt;/span&gt;;
        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;;
    }

    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($method, $params)&lt;/span&gt;&lt;/span&gt;{
        $thread = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Async($method, $params);
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;($thread-&amp;gt;start()){
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $thread;
        }
    }

}


$nums = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;( &lt;span class=&quot;number&quot;&gt;6&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;);

&lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;($nums &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $num){
    $future = Async::call(&lt;span class=&quot;string&quot;&gt;&quot;sleepcount&quot;&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;($num));
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On my development machine this does not product the correct results. It only sorts elements pairwise, so my result is&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;2, 6, 1, 4&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is likely because my development machine has a dual core processor. That&amp;#8217;s just part of the fun of concurrent programming I suppose. &lt;/p&gt;
&lt;p&gt;There may be a better way of implementing this in pthreads. I wouldn&amp;#8217;t know. I&amp;#8217;m only currently getting my feet wet with it.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Sleep Sort in Javascript</title>
      <link>http://localhost:8080/articles/sleep-sort-in-javascript/</link>
      <pubDate>Sun, 07 Jul 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/sleep-sort-in-javascript/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;&lt;a href=&quot;http://archives.cazzaserver.com/SleepSortWiki/SleepSort.html&quot;&gt;Sleep Sort&lt;/a&gt; is a humourous algorithm for sorting. The idea is to output the numeric array elements after a time interval proportional to the value of the array element. So if you had an array [3, 2, 1], 3 could be output three seconds after the sort, 2 two seconds after and 1 one second after. The result is that you’d see 1, 2, 3 three seconds later.&lt;/p&gt;
&lt;p&gt;Of course this is a terrible idea, but it’s also a heck of a lot of fun!&lt;/p&gt;
&lt;p&gt;Here’s an implementation of the idea in javascript:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;opnode&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;a&lt;/span&gt;) &lt;/span&gt;{
    el = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createElement(&lt;span class=&quot;string&quot;&gt;'div'&lt;/span&gt;);
    el.innerHTML = a;
    &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.body.appendChild(el);
}

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; temporalSort = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;ar&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; i &amp;lt; ar.length; i++) {
        (
            &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;a&lt;/span&gt;)&lt;/span&gt;{
                &lt;span class=&quot;built_in&quot;&gt;window&lt;/span&gt;.setTimeout(
                    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
                        opnode(a);
                    },
                &lt;span class=&quot;number&quot;&gt;100&lt;/span&gt; * a);
            }
        )(ar[i]);
    }
};

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; i, array = [&lt;span class=&quot;number&quot;&gt;6&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;14&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;9&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;15&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;13&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;];

temporalSort(array);&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Simple Observer Pattern in PHP</title>
      <link>http://localhost:8080/articles/simple-observer-pattern-in-php/</link>
      <pubDate>Tue, 02 Jul 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/simple-observer-pattern-in-php/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;The observer pattern is a nifty way to decouple objects from one another. Rather than having methods explicitly rely on, create, and access other objects, the other objects can subscribe to an object and enact their own changes as necessary.&lt;/p&gt;
&lt;p&gt;Our implementation will have two general groups of objects, subscribers and observers. A subscriber class will hook in to an observer class and make actions when the observer publishes certain messages. The observer class will give objects methods to subscribe and unsubscribe from its messages.&lt;/p&gt;
&lt;p&gt;We’ll begin by setting up an interface for our subscribers. Our subscribers could really be anything, so we want to specify some general behaviour that they will have. We don’t want to be restrictive and have an abstract class that they will inherit from because that would restrict functionality of all subscribers and limit the usefulness of this pattern.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Subscriber&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;EventCall&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($str)&lt;/span&gt;&lt;/span&gt;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we&amp;#8217;ll set up an abstract class for Observables. This may be more useful as a trait but we actually do have to implement some functionality here.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Observable&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $_subscribers = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Subscribe&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($o)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;comment&quot;&gt;// give objects an ability to add themselves to the subscribers list.&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!in_array($o, &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_subscribers)) {
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_subscribers[] = $o;
        }
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Unsubscribe&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($o)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;comment&quot;&gt;// give objects an ability to remove themselves from the subscribers list.&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (in_array($o, &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_subscribers)) {
            &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_subscribers &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $key =&amp;gt; $value) {
                &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($o == $value) {
                    &lt;span class=&quot;keyword&quot;&gt;unset&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_subscribers[$key]);
                }
            }
        }    
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($event)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;comment&quot;&gt;// when the event occurs, call the corresponding method on the clients.&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;_subscribers &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $subscriber) {
            $subscriber-&amp;gt;EventCall($event);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that the abstract class and interface are ready, we can make some concrete classes based on these.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Observer&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Observable&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Talk&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;I am an observern&quot;&lt;/span&gt;;
    }
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Subscriber1&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Subscriber&lt;/span&gt;&lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;EventCall&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($str)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;Subscriber1 event occured $strn&quot;&lt;/span&gt;;
    }
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Subscriber2&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Subscriber&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $data;
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($data)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;data = $data;
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;EventCall&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($str)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;Subscriber2 event occured $str data is &quot;&lt;/span&gt; . &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;data . &lt;span class=&quot;string&quot;&gt;&quot;n&quot;&lt;/span&gt;;
    }
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Subscriber3&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Subscriber&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;EventCall&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($str)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;Subscriber3 event occured $strn&quot;&lt;/span&gt;;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now let’s make some instances of these:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$observer = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Observer();
$subscriber1 = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Subscriber1();
$subscriber2 = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Subscriber2(&lt;span class=&quot;string&quot;&gt;'one'&lt;/span&gt;);
$subscriber2too = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Subscriber2(&lt;span class=&quot;string&quot;&gt;'two'&lt;/span&gt;);
$subscriber3 = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Subscriber3();

$observer-&amp;gt;Subscribe($subscriber1);
$observer-&amp;gt;Subscribe($subscriber2);
$observer-&amp;gt;Subscribe($subscriber2);
$observer-&amp;gt;Subscribe($subscriber2too);
$observer-&amp;gt;Subscribe($subscriber3);

$observer-&amp;gt;Event(&lt;span class=&quot;string&quot;&gt;'wow check out this awesome message that is being passed, bro.'&lt;/span&gt;);
$observer-&amp;gt;Talk();

$observer-&amp;gt;Unsubscribe($subscriber2);

$observer-&amp;gt;Event(&lt;span class=&quot;string&quot;&gt;'what unheard of madness will happen next?'&lt;/span&gt;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And of course the output is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Subscriber1 event occured wow check out this awesome message that is being passed, bro.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Subscriber2 event occured wow check out this awesome message that is being passed, bro. data is one&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Subscriber2 event occured wow check out this awesome message that is being passed, bro. data is two&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Subscriber3 event occured wow check out this awesome message that is being passed, bro.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I am an observer&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Subscriber1 event occured what unheard of madness will happen next?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Subscriber2 event occured what unheard of madness will happen next? data is two&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Subscriber3 event occured what unheard of madness will happen next?&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    <item>
      <title>Using Interfaces to reduce coupling</title>
      <link>http://localhost:8080/articles/using-interfaces-to-reduce-coupling/</link>
      <pubDate>Thu, 27 Jun 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/using-interfaces-to-reduce-coupling/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Consider the following three scenarios:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;  &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Dog&lt;/span&gt; &lt;/span&gt;{
...
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Bark&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($str)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $str;
    }
...
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;AnimalCommunication&lt;/span&gt; &lt;/span&gt;{
...
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;DogBark&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(Dog $dog, $str)&lt;/span&gt; &lt;/span&gt;{
        $dog-&amp;gt;Bark($str);
    }
...
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;  &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Dog&lt;/span&gt; &lt;/span&gt;{
...
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Bark&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($str)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $str;
    }
...
}


&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;AnimalCommunication&lt;/span&gt; &lt;/span&gt;{
...
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;AnimalCommunicate&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($str)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $str;
    }
...
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;Interface&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;IAnimal&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Speak&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($str)&lt;/span&gt;&lt;/span&gt;;
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;Class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Dog&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;IAnimal&lt;/span&gt; &lt;/span&gt;{
...
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Speak&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($str)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;gt;Bark($str);
    }
....
}
&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;AnimalCommunication&lt;/span&gt; &lt;/span&gt;{
...
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;AnimalCommunicate&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(IAnimal $animal, $str)&lt;/span&gt; &lt;/span&gt;{
        $animal-&amp;gt;speak($str);
    }
...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the following about these examples:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The first is tightly coupled to the dog class, and hence is not very extensible.&lt;/li&gt;
&lt;li&gt;The second is coupled to echo. It does not allow different &amp;#8220;animals&amp;#8221; to output their text differently. What if we later added a &lt;code&gt;TelepathicGecko&lt;/code&gt; class, which didn&amp;#8217;t echo out to speak, but rather published to some ESP API somewhere? Clearly the coupling here is not ideal either.&lt;/li&gt;
&lt;li&gt;The third is best. By programming to an interface, we reduce coupling to the minimum necessary amount.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    <item>
      <title>Pointless Promises in PHP</title>
      <link>http://localhost:8080/articles/pointless-promises-in-php/</link>
      <pubDate>Tue, 18 Jun 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/pointless-promises-in-php/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;A &lt;a href=&quot;http://en.wikipedia.org/wiki/Futures_and_promises&quot;&gt;promise&lt;/a&gt; is a way to defer the execution of a given routine 
until the data it needs to run is ready. This is a very useful 
pattern in asynchronous languages, so using promises in a language 
like javascript is a great idea.&lt;/p&gt;
&lt;p&gt;Of course PHP is (without forking) totally synchronous so there is 
really no reason to implement the promise pattern in PHP.&lt;/p&gt;
&lt;p&gt;But the motto of every programmer is &amp;#8220;if it’s a bad 
idea, I will do it!&amp;#8221; (no, it isn’t), so here’s an 
implementation of promises in PHP:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;PromiseClass&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $callbacks = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $last_return;
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;promise&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($promise)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (get_class($promise) == &lt;span class=&quot;string&quot;&gt;'Promise'&lt;/span&gt;) {
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $promise;
        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (is_callable($promise)) {
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;then($promise);
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;;
        }
    }
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;(callable $callback)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;callbacks[] = $callback;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;;
    }
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;resolve&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        $callback = array_shift(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;callbacks);
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (is_callable($callback)) {
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;last_return = $callback(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;last_return);
        }
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (count(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;callbacks) &amp;amp;gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;resolve();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A few things to note here: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First you will have to make an instance of the class.&lt;/li&gt;
&lt;li&gt;You start by passing a function to the &lt;code&gt;promise&lt;/code&gt; method. You could use &lt;code&gt;then&lt;/code&gt; but the code wouldn&amp;#8217;t look as descriptive or read as well.&lt;/li&gt;
&lt;li&gt;You can then add any functions that would be run after with successive calls to &lt;code&gt;then&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;None of the functions that have been set up will be run until you call the &lt;code&gt;resolve&lt;/code&gt; method on the object.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here&amp;#8217;s an example of usage of this useless and pointless class:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$promiser = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; PromiseClass();

$promiser-&amp;gt;promise(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;sleepingn&quot;&lt;/span&gt;;
        sleep(&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;);
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;;
    })
    -&amp;amp;gt;then(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($args)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;that farn$argsn&quot;&lt;/span&gt;;
        sleep(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;);
    })
    -&amp;amp;gt;then(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;even farthernn&quot;&lt;/span&gt;;
    });

$promiser-&amp;gt;resolve();    &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note: I’ve added some &lt;code&gt;sleep&lt;/code&gt; statements here so it almost seems 
like something asynchronous is happening. Really &lt;code&gt;sleep&lt;/code&gt; is just 
blocking. The output will be something like:&lt;/p&gt;
&lt;pre&gt;sleeping
that far
3
even farther
&lt;/pre&gt;

</description>
    </item>
    <item>
      <title>Longest Common Substring in PHP</title>
      <link>http://localhost:8080/articles/longest-common-substring-in-php/</link>
      <pubDate>Mon, 10 Jun 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/longest-common-substring-in-php/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Longest common substring is a function that can be useful once in a while. Here&amp;#8217;s a PHP implementation. Be forewarned, this runs in &lt;code&gt;O(mn)&lt;/code&gt; time.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;longest_common_substring&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($string1, $string2)&lt;/span&gt; &lt;/span&gt;{
    $L = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    $length = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
    $pos = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
    $array1 =str_split($string1);
    $array2 =str_split($string2);
    &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt; ($array1 &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $i =&amp;amp;gt; $c1) { 
        $L[$i] = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
        &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt; ($array2 &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $j =&amp;amp;gt; $c2) { 
            $L[$i][$j] = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($c1 == $c2) {
                &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($i == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; || $j == &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
                    &lt;span class=&quot;comment&quot;&gt;// initialize that this character position exists.&lt;/span&gt;
                    $L[$i][$j] = &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
                } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
                    &lt;span class=&quot;comment&quot;&gt;// increment previous or reset.&lt;/span&gt;
                    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;($L[$i&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;][$j&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;])) {
                        $L[$i][$j] = $L[$i&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;][$j&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;] + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
                    } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
                        $L[$i][$j] = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
                    }
                }
                &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($L[$i][$j] &amp;amp;gt; $length) {
                    $length = $L[$i][$j];
                }
                &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ((&lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;($L[$i][$j]))&amp;amp;&amp;amp;($L[$i][$j] == $length)) {
                    $pos = $i;
                }
            }
        }
    }
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($length &amp;amp;gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;) {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; substr($string1, $pos - $length + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, $length);
    } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Usage:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;
$string1 = &lt;span class=&quot;string&quot;&gt;'sadjjasdf this is the string  sdlkjhaskl'&lt;/span&gt;;
$string2 = &lt;span class=&quot;string&quot;&gt;'eriuhysdfnbasi this is the stringbhdjubsdi'&lt;/span&gt;;

&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; longest_common_substring($string1, $string2);&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Finding the main content element on a page in javascript</title>
      <link>http://localhost:8080/articles/finding-the-main-content-element-on-a-page-in-javascript/</link>
      <pubDate>Sun, 09 Jun 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/finding-the-main-content-element-on-a-page-in-javascript/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Short of going to something more complex like measuring information
or doing some natural language processing, you can estimate which 
element on a page contains the content by determining which element 
has the highest ratio of contained content to contained markup. 
Here’s a javascript snippet that does just that:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// not perfect obviously. Not terrible neither.&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; id, tag;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; all = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.querySelectorAll(&lt;span class=&quot;string&quot;&gt;'body *'&lt;/span&gt;), max = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, el, i, L;

&lt;span class=&quot;comment&quot;&gt;// list some commons ids that denote the outermost element on a page.&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; badIds = {
    &lt;span class=&quot;string&quot;&gt;&quot;wrapper&quot;&lt;/span&gt; : &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,
    &lt;span class=&quot;string&quot;&gt;&quot;container&quot;&lt;/span&gt; : &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,
    &lt;span class=&quot;string&quot;&gt;&quot;wrapper-content&quot;&lt;/span&gt; : &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
};

&lt;span class=&quot;comment&quot;&gt;// we don't want to include content from certain tags.&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; badTags = {
    &lt;span class=&quot;string&quot;&gt;&quot;SCRIPT&quot;&lt;/span&gt; : &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,
    &lt;span class=&quot;string&quot;&gt;&quot;STYLE&quot;&lt;/span&gt; : &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,
    &lt;span class=&quot;string&quot;&gt;&quot;HEADER&quot;&lt;/span&gt; : &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
}

&lt;span class=&quot;comment&quot;&gt;// the goal rate of markup per content&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; contentPercent = &lt;span class=&quot;number&quot;&gt;0.45&lt;/span&gt;;

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; contentRatio = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;el&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; i, L, totalScript = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, scripts = el.getElementsByTagName(&lt;span class=&quot;string&quot;&gt;&quot;script&quot;&lt;/span&gt;);
    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i =&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, L= scripts.length; i &amp;amp;lt; L; i++) {
        totalScript += scripts[i].length;
    }
    totalScript = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (el.textContent.length - totalScript) / el.innerHTML.length;
};

&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, L =all.length; i &amp;amp;lt; L; i++) {
    id = all[i].getAttribute(&lt;span class=&quot;string&quot;&gt;'id'&lt;/span&gt;);
    tag = all[i].tagName;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (all[i].textContent &amp;amp;&amp;amp; all[i].textContent.length &amp;amp;gt; max &amp;amp;&amp;amp; (contentRatio(all[i]) &amp;amp;gt; contentPercent) &amp;amp;&amp;amp; !badIds[id] &amp;amp;&amp;amp; !badTags[tag]) {
        max = all[i].textContent.length;
        el = all[i];
    }
}

&lt;span class=&quot;comment&quot;&gt;// show the results.&lt;/span&gt;
&lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(el)
&lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(el.textContent.length / el.innerHTML.length)
&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>Simple Markov Chain in PHP</title>
      <link>http://localhost:8080/articles/simple-markov-chain-in-php/</link>
      <pubDate>Wed, 29 May 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/simple-markov-chain-in-php/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Here&amp;#8217;s a simple Markov chain implementation in PHP, loosely 
adapted from this excellent write up about &lt;a href=&quot;http://blog.javascriptroom.com/2013/01/21/markov-chains/&quot;&gt;implementing Markov 
chains in javascript&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Link&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $nexts = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;addNextWord&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($word)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_string($word)) {
            &lt;span class=&quot;keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;Exception&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'addNextWord method in Link class is run with an string parameter'&lt;/span&gt;);
        }
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!&lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;nexts[$word])) {
            &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;nexts[$word] = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
        }
        &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;nexts[$word]++;
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getNextWord&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{
        $total = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
        &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;nexts &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $word =&amp;amp;gt; $count) {
            $total += $count;
        }
        $randomIndex = rand(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, $total);
        $total = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;
        &lt;span class=&quot;keyword&quot;&gt;foreach&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;nexts &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; $word =&amp;amp;gt; $count) {
            $total += $count;
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; ($total &amp;amp;gt;= $randomIndex) {
                &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $word;
            }
        }
    }
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Chain&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt; $words = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;();
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($words)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_array($words)) {
            &lt;span class=&quot;keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;Exception&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'Chain class is instantiated with an array'&lt;/span&gt;);
        }

        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt;($i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; $i &amp;amp;lt; count($words); $i++) {
            $word = (string) $words[$i];
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!&lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;words[$word])) {
                &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;words[$word] = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Link();
            }
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;($words[$i + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;])) {
                &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;words[$word]-&amp;amp;gt;addNextWord($words[$i + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]);
            }
        }
    }
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;getChainOfLength&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($word, $i)&lt;/span&gt; &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_string($word)) {
            &lt;span class=&quot;keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;Exception&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'getChainOfLength method in Chain class is run with an string parameter'&lt;/span&gt;);
        }
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_integer($i)) {
            &lt;span class=&quot;keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;Exception&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'getChainOfLength method should be called with an integer'&lt;/span&gt;);
        }
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!&lt;span class=&quot;keyword&quot;&gt;isset&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;words[$word])) {
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;;
        } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
            $chain = &lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;($word);
            &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; ($j = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; $j &amp;amp;lt; $i; $j++) {
                $word = &lt;span class=&quot;keyword&quot;&gt;$this&lt;/span&gt;-&amp;amp;gt;words[$word]-&amp;amp;gt;getNextWord();
                $chain[] = $word;
            }
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; implode(&lt;span class=&quot;string&quot;&gt;' '&lt;/span&gt;, $chain);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is an example of usage:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_all_words_in_file&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($file)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; preg_split(&lt;span class=&quot;string&quot;&gt;'/s+/ '&lt;/span&gt;, file_get_contents($file));
}

$file = &lt;span class=&quot;string&quot;&gt;'testtext2.txt'&lt;/span&gt;;

$words = get_all_words_in_file($file);
$chain = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Chain($words);
$newSentence = $chain-&amp;amp;gt;getChainOfLength(&lt;span class=&quot;string&quot;&gt;'The'&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;200&lt;/span&gt;);
&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; wordwrap($newSentence, &lt;span class=&quot;number&quot;&gt;80&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;n&quot;&lt;/span&gt;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Conceptually, a Markov chain captures the idea of likelihood of 
traversing from state to state. You can populate this data for a 
block of text by passing through a block of text and counting the 
number of occurrences of words that follow a given word. You can 
then use this data to generate new blocks of text.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>A Mandelbrot Set Viewer via Javascript and Canvas</title>
      <link>http://localhost:8080/articles/a-mandelbrot-set-viewer-via-javascript-and-canvas/</link>
      <pubDate>Thu, 23 May 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/a-mandelbrot-set-viewer-via-javascript-and-canvas/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;In mathematics, a &lt;a href=&quot;http://en.wikipedia.org/wiki/Fixed_Point&quot;&gt;fixed point&lt;/a&gt; is an input  &lt;code&gt;x&lt;/code&gt; for a function &lt;code&gt;f&lt;/code&gt; such that&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f(x) = x&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The Mandelbrot Set is a visualization of which points near &lt;code&gt;0&lt;/code&gt; in the complex plane are fixed points for the function &lt;img src=&quot;http://benwendt.ca/blog/wp-content/ql-cache/quicklatex.com-fbbf2a4c724249d1ef2f4dc756849d05_l3.png&quot; class=&quot;ql-img-inline-formula quicklatex-auto-format&quot; alt=&quot;&amp;#102;&amp;#40;&amp;#122;&amp;#41;&amp;#32;&amp;#61;&amp;#32;&amp;#122;&amp;#94;&amp;#123;&amp;#50;&amp;#125;&amp;#32;&amp;#45;&amp;#32;&amp;#49;&quot; title=&quot;Rendered by QuickLaTeX.com&quot; height=&quot;19&quot; width=&quot;103&quot; style=&quot;vertical-align: -4px;&quot; /&gt;, where &lt;img src=&quot;http://benwendt.ca/blog/wp-content/ql-cache/quicklatex.com-b85edc5050d852426cfbfae352fd2550_l3.png&quot; class=&quot;ql-img-inline-formula quicklatex-auto-format&quot; alt=&quot;&amp;#122;&amp;#105;&amp;#110;&amp;#109;&amp;#97;&amp;#116;&amp;#104;&amp;#98;&amp;#98;&amp;#123;&amp;#67;&amp;#125;&quot; title=&quot;Rendered by QuickLaTeX.com&quot; height=&quot;13&quot; width=&quot;97&quot; style=&quot;vertical-align: 0px;&quot; /&gt;. Points that are fixed are rendered in black, while all other points are colour-coded based on how quickly repeated application of the function to a point diverges.&lt;/p&gt;
&lt;p&gt;Images of the Mandelbrot set should be familiar to most everyone. It&amp;#8217;s an infinitely detailed, self-similar set of rainbows surrounding bubbles.&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;http://benwendt.ca/blog/wp-content/uploads/2013/05/canvas6-300x171.png&quot; alt=&quot;canvas6&quot; width=&quot;300&quot; height=&quot;171&quot; class=&quot;alignnone size-medium wp-image-30&quot; /&gt;&lt;img src=&quot;http://benwendt.ca/blog/wp-content/uploads/2013/05/canvas-300x171.png&quot; alt=&quot;canvas&quot; width=&quot;300&quot; height=&quot;171&quot; class=&quot;alignnone size-medium wp-image-31&quot; /&gt;&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;http://benwendt.ca/blog/wp-content/uploads/2013/05/canvas2-300x171.png&quot; alt=&quot;canvas2&quot; width=&quot;300&quot; height=&quot;171&quot; class=&quot;alignnone size-medium wp-image-32&quot; /&gt;&lt;img src=&quot;http://benwendt.ca/blog/wp-content/uploads/2013/05/canvas3-300x171.png&quot; alt=&quot;canvas3&quot; width=&quot;300&quot; height=&quot;171&quot; class=&quot;alignnone size-medium wp-image-33&quot; /&gt;&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;http://benwendt.ca/blog/wp-content/uploads/2013/05/canvas4-300x171.png&quot; alt=&quot;canvas4&quot; width=&quot;300&quot; height=&quot;171&quot; class=&quot;alignnone size-medium wp-image-34&quot; /&gt;&lt;img src=&quot;http://benwendt.ca/blog/wp-content/uploads/2013/05/canvas5-300x171.png&quot; alt=&quot;canvas5&quot; width=&quot;300&quot; height=&quot;171&quot; class=&quot;alignnone size-medium wp-image-35&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So here&amp;#8217;s my javascript and canvas based Mandlebrot viewer:&lt;/p&gt;
&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;var xScale, xOffext, yScale, yOffset, xVal, yVal;
var canvas, h, w;
updateScalesAndOffsets = function() {
    xScale = parseFloat(document.getElementById('xScale').value);
    xOffset = parseFloat(document.getElementById('xOffset').value);
    yScale = parseFloat(document.getElementById('yScale').value);
    yOffset = parseFloat(document.getElementById('yOffset').value);
};
updateCanvasAndDimensions = function() {
    canvas = document.getElementById('m');
    h = canvas.getAttribute('height');
    w = canvas.getAttribute('width');
};
doMandelbrot = function() {
    var iteration, max_iteration = 1000, l, x, y, x0, y0, xtemp;
    updateCanvasAndDimensions();
    var ctx = canvas.getContext('2d');
    updateScalesAndOffsets();

    for (var i=0; i &amp;lt; w; i++) {
        for (var j=0;j &amp;lt; h; j++) {
            // for each point in the image, generate the color value.
            x0 = xScale * (i / w) + xOffset;
            y0 = yScale * (j / h) + yOffset;

            x = 0;
            y = 0;

            iteration = 0;

            while (x*x + y*y &amp;lt; 4 &amp;&amp; iteration &amp;lt; max_iteration) {
                // this is parametrically performing the complex function f(z) = z^2 -1.
                xtemp = x*x - y*y + x0;
                y = 2*x*y + y0;
                x = xtemp;
                iteration++;
            }

            if (x*x + y*y &amp;lt; 4) {
                ctx.fillStyle='rgb(0,0,0)';
            } else {
                l = iteration &amp;lt; 50? iteration : 50;
                // set colors using hsl so that the number of iterations to diverge maps to the hue.
                ctx.fillStyle='hsl('+Math.floor((iteration/max_iteration)*256)+',100%,' + l + '%)';
            }

            ctx.fillRect(i,j,i+1,j+1);
        }
    }
};
mouseMove = function(e) {


    xVal = xScale * (e.clientX / w) + xOffset;
    yVal = yScale * (e.clientY / h) + yOffset;
    var xCoordinateElement = document.getElementById('xCoordinate'), yCoordinateElement = document.getElementById('yCoordinate');
    xCoordinateElement.innerHTML = xVal;
    yCoordinateElement.innerHTML = yVal;
};

zoomIn = function() {
    document.getElementById('xScale').value = parseFloat(document.getElementById('xScale').value) / 2;
    document.getElementById('xOffset').value = xVal - parseFloat(document.getElementById('xScale').value) / 2;
    document.getElementById('yScale').value = parseFloat(document.getElementById('yScale').value) / 2;
    document.getElementById('yOffset').value = yVal - parseFloat(document.getElementById('yScale').value) / 2;
    doMandelbrot();

}
zoomOut = function() {
    document.getElementById('xScale').value = parseFloat(document.getElementById('xScale').value) * 2;
    document.getElementById('yScale').value = parseFloat(document.getElementById('yScale').value) * 2;
    doMandelbrot();

}
moveDir = function(dir) {
    switch (dir) {
        case 'up' : document.getElementById('yOffset').value = yOffset - yScale / 10; break;
        case 'down' : document.getElementById('yOffset').value = yOffset + yScale / 10; break;
        case 'right' : document.getElementById('xOffset').value = xOffset + xScale / 10; break;
        case 'left' : document.getElementById('xOffset').value = xOffset - xScale / 10; break;
    }
    updateScalesAndOffsets();
    doMandelbrot();
}


&lt;/pre&gt;

</description>
    </item>
    <item>
      <title>Reactive Programming in PHP</title>
      <link>http://localhost:8080/articles/reactive-programming-in-php/</link>
      <pubDate>Wed, 22 May 2013 20:00:00 -0400</pubDate>
      <guid isPermaLink="true">http://localhost:8080/articles/reactive-programming-in-php/</guid>
      <author>Ben Wendt</author>
      <description>&lt;p&gt;Wikipedia has this to say about &lt;a href=&quot;http://en.wikipedia.org/wiki/Reactive_programming&quot;&gt;reactive programming&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In &lt;a href=&quot;http://en.wikipedia.org/wiki/Computing&quot; title=&quot;Computing&quot;&gt;computing&lt;/a&gt;, &lt;strong&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Reactive_programming&quot;&gt;reactive programming&lt;/a&gt;&lt;/strong&gt; is a &lt;a href=&quot;http://en.wikipedia.org/wiki/Programming_paradigm&quot; title=&quot;Programming paradigm&quot;&gt;programming paradigm&lt;/a&gt; oriented around &lt;a href=&quot;http://en.wikipedia.org/wiki/Dataflow_programming&quot; title=&quot;Dataflow programming&quot;&gt;data flows&lt;/a&gt; and the propagation of change. This means that it should be possible to express static or dynamic data flows with ease in the programming languages used, and that the underlying execution model will automatically propagate changes through the data flow.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Inspired by projects like &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;knockout.js&lt;/a&gt; and &lt;a href=&quot;https://github.com/fynyky/reactor.js&quot;&gt;reactor.js&lt;/a&gt;, I thought I’d give it a shot in PHP. Here is an example implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$Signal = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($v)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (is_callable($v)) {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;($v)&lt;/span&gt; &lt;/span&gt;{
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $v();
        };
    } &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;($a = null)&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;($v)&lt;/span&gt; &lt;/span&gt;{
            &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; $return;
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (is_null($return)) {
                $return = $v;
            }
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (!is_null($a)) {
                $return = $a;
            }
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $return;
        };
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is an example of usage:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;
&lt;span class=&quot;keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'Reactor.php'&lt;/span&gt;;

$foo = $Signal(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;);

$bar = $Signal(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;($foo)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $foo() + &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
});
$bar2 = $Signal(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;params&quot;&gt;($foo, $bar)&lt;/span&gt; &lt;/span&gt;{
    $val = $foo();
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; $val * $val + $bar();
});

&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $foo() . &lt;span class=&quot;string&quot;&gt;&quot;n&quot;&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $bar() . &lt;span class=&quot;string&quot;&gt;&quot;n&quot;&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $bar2() . &lt;span class=&quot;string&quot;&gt;&quot;nn&quot;&lt;/span&gt;;

$foo(&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;);

&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $foo() . &lt;span class=&quot;string&quot;&gt;&quot;n&quot;&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $bar() . &lt;span class=&quot;string&quot;&gt;&quot;n&quot;&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $bar2() . &lt;span class=&quot;string&quot;&gt;&quot;nn&quot;&lt;/span&gt;;

$foo(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;);

&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $foo() . &lt;span class=&quot;string&quot;&gt;&quot;n&quot;&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;echo&lt;/span&gt; $bar2() . &lt;span class=&quot;string&quot;&gt;&quot;nn&quot;&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
  </channel>
</rss>