Fixed up Tamari a bit and also moved it to use supplementary content.

This commit is contained in:
Shoofle Munroe 2013-09-03 11:39:11 -04:00
parent 7f2bb9df55
commit 6768f1f1e6
19 changed files with 92 additions and 69 deletions

View File

@ -6,7 +6,7 @@ to the `bloop` object. It's a blueprint which describes how to route requests fo
`render_article`; Go team!""" `render_article`; Go team!"""
import os import os
from flask import Blueprint, render_template, abort from flask import Blueprint, render_template, send_from_directory, abort
folder = "articles" folder = "articles"
article_base_template = os.path.join(folder, "article.template.html") article_base_template = os.path.join(folder, "article.template.html")
@ -78,17 +78,22 @@ def supplementary(article_name, file_path):
necessary to make a blueprint for it. Then, it's necessary to include the blueprint in this file. Oh well. necessary to make a blueprint for it. Then, it's necessary to include the blueprint in this file. Oh well.
""" """
# Put the article name into the standard form, and concatenate them together. # Put the article name into the standard form, and concatenate them together.
article_name = page_name.replace("-", "_").lower() article_name = article_name.replace("-", "_").lower()
# You could make a strong argument that this is unnecessary, and we could just shove in a static file handler. # You could make a strong argument that this is unnecessary, and we could just shove in a static file handler.
# But I like this solution more. It better separates out the supplementary content from the article itself. # But I like this solution more. It better separates out the supplementary content from the article itself.
# Things that don't fit into this framework might not belong as articles, anyway! # Things that don't fit into this framework might not belong as articles, anyway!
path = os.path.join(article_name, file_path)
print("trying to render supplementary stuff at /{an}/{p}/".format(article_name, file_path)) # Important! This didn't work right for a long time until I finally made it join `folder` to the beginning.
# Without that, it tries to load the file relative to wherever the server's running - which is /not/ the
# right thing. The server's running somewhere, but this needs to be in the articles folder, yadda yadda,
# you can figure it out.
path = os.path.join(folder, article_name, file_path)
# If the path exists and is a file, then we should send it. # If the path exists and is a file, then we should send it.
if os.path.isfile(path): if os.path.isfile(path):
directory, file_name = os.path.split(path) directory, file_name = os.path.split(path)
abort(420) print("sending %(fn)s from directory %(d)s" % {"fn": file_name, "d": directory})
return send_from_directory(directory, file_name) return send_from_directory(directory, file_name)
# If that file wasn't found, then, well, whoops. # If that file wasn't found, then, well, whoops.

View File

@ -0,0 +1,15 @@
{% extends "articles/article.template.html" %}
{% block title -%}
Features for a game-focused programming language or library
{%- endblock %}
{% block body -%}
<p>I like making games but sometimes I spend a lot of time doing stuff that is just annoying. What if a language or environment were designed to make those things easy?</p>
<hr>
{%- include "articles/snorlax_evaluation.article.html" -%}
<hr>
{%- include "articles/time_integration.article.html" -%}
<hr>
{%- include "articles/easy_peasy_state_machinesy.article.html" -%}
{%- endblock %}

View File

@ -1,19 +1,7 @@
<article> <article>
<script type="text/javascript" src="/static/flot/jquery.flot.js"></script> <script type="text/javascript" src="/static/flot/jquery.flot.js"></script>
<script type="text/javascript" src="/static/flot/jquery.flot.resize.js"></script> <script type="text/javascript" src="/static/flot/jquery.flot.resize.js"></script>
<script type="text/javascript"> <script type="text/javascript" src="/something-or-other/soo.js"></script>
var data, config;
$(document).ready(function() {
data = [];
for (var i=0; i<10; i++) {
data.push([i, i*i/10]);
}
config = {};
config.yaxis = {max: 10};
config.xaxis = {min: 0, max: 10};
$.plot($('#the_graph'), [data], config);
});
</script>
<p>Oh look a graph</p> <p>Oh look a graph</p>
<div id="the_graph" style="width:100%;height:200px"></div> <div id="the_graph" style="width:100%;height:200px"></div>
<p>That's the graph</p> <p>That's the graph</p>

View File

@ -0,0 +1,11 @@
var data, config;
$(document).ready(function() {
data = [];
for (var i=0; i<10; i++) {
data.push([i, i*i/10]);
}
config = {};
config.yaxis = {max: 10};
config.xaxis = {min: 0, max: 10};
$.plot($('#the_graph'), [data], config);
});

View File

@ -1,66 +1,70 @@
<article class="project"> <article class="project">
<h1>Tamari Lattices!</h1> <h1>Tamari Lattices!</h1>
<p>Tamari lattices are graphs (in the mathematical sense - a set of nodes with connections between them) describing a particular set of operations. I like them because they're pretty!</p> <p>Tamari lattices are graphs (in the mathematical sense - a set of nodes with connections between them) describing a particular set of operations. I like them because they're pretty!</p>
<figure> <figure>
<img src="/static/tamari/tamari_3.png" alt="The (trivial) Tamari lattice for a three-element tree."> <img src="/tamari/tamari_3.png" alt="The (trivial) Tamari lattice for a three-element tree.">
<figcaption>A (trivial) Tamari lattice, generated by the associations of three elements. <a class="source" href="/static/tamari/tamari_3.dot">Source file.</a></figcaption> <figcaption>A (trivial) Tamari lattice, generated by the associations of three elements. <a class="source" href="/tamari/tamari_3.dot">Source file.</a></figcaption>
</figure> </figure>
<p>Oh - oh dear. How'd that get there? Okay, that's not a very good example.</p> <p>Oh - oh dear. How'd that get there? Okay, that's not a very good example.</p>
<p>There are many ways to generate and think of a Tamari lattice. The way I prefer to think of it is this: Consider some binary operation - you take two elements to produce a new one. You want to combine several of these elements. So long as you have three or more elements, there are multiple ways to combine them.</p> <p>There are many ways to generate and think of <code>a</code> Tamari lattice. The way I prefer to think of it is this: Consider some binary operation - <code>a</code> way to use two things to make <code>a</code> new one. You want to combine <code>a</code> bunch. So long as you have three or more elements, there's more than one way to combine them - if you've got <code>a</code>, <code>b</code>, and <code>c</code>, you could combine <code>b</code> and <code>c</code>, and then combine the product of that with <code>a</code>, <em>or</em> you could combine <code>a</code> and <code>b</code>, and then combine that with <code>c</code>. We're going to pretend you can't combine <code>a</code> and <code>c</code> (although maybe that would produce more pictures...). The way we write combining two elements is like this: <code>(a, b)</code>. So that means that the first way of combing <code>a</code>, <code>b</code>, and <code>c</code> is written like so: <code>(a, (b, c))</code>. The second way would be <code>((a, b), c)</code>.</p>
<p>The game we play is this: You're allowed to step from one way of combining the elements to another, but only by <i class="keyword">left-association</i>: turning <code>(a, (b, c))</code> into <code>((a, b), c)</code>.</p> <p>Okay, got it? Good.</p>
<p>The only remaining rule is that if you can step from one combination to another, the second one has to appear below the first one when you draw it.</p> <p>The game we play is this: You're allowed to step from one way of combining the elements to another, but only by <i class="keyword">left-association</i>: turning <code>(a, (b, c))</code> into <code>((a, b), c)</code>.</p>
<figure> <p>The only other rule is that if you can step from one combination to another, the second one has to be drawn below the first one when you list them all out.</p>
<img src="/static/tamari/tamari_4.png" alt="A Tamari lattice for a four-element tree."> <figure>
<figcaption>As above, but generated by a four-element tree. <a class="source" href="/static/tamari/tamari_4.dot">Source file.</a></figcaption> <img src="/tamari/tamari_4.png" alt="A Tamari lattice for a four-element tree.">
</figure> <figcaption>As above, but generated by a four-element tree. <a class="source" href="/tamari/tamari_4.dot">Source file.</a></figcaption>
<p>You can also think about it in terms of <a href="http://wikipedia.org/wiki/Tree_rotation">tree rotations</a> - but remember that that's a different tree than the one we're building as the Tamari lattice. Tree rotations are just another way to think of left-association and right-association.</p> </figure>
<p>If you look at <a href="http://wikipedia.org/wiki/Tamari_lattice">the wikipedia article on Tamari lattices</a>, you'll see a very pretty image:</p> <span class="sidenote span4">You can also think about it in terms of <a href="http://wikipedia.org/wiki/Tree_rotation">tree rotations</a> - but remember that that's a different tree than the one we're building as the Tamari lattice. Tree rotations are just another way to think of left-association and right-association.</span>
<p>If you look at <a href="http://wikipedia.org/wiki/Tamari_lattice">the wikipedia article on Tamari lattices</a>, you'll see a very pretty image:</p>
<figure>
<img src="http://upload.wikimedia.org/wikipedia/commons/4/46/Tamari_lattice.svg"> <img src="http://upload.wikimedia.org/wikipedia/commons/4/46/Tamari_lattice.svg">
<p>There are a lot of ways to reorganize a Tamari lattice, and it takes some artistic work to make one that really looks good. You can even visualize the same graph as <a href="http://en.wikipedia.org/wiki/Associahedron">a 3D shape called an "associahedron"</a>, but I like it in the simple gridded lattice form above. It reminds me how much beauty there can be in regularity - you can see the grid, but it doesn't look constrained by it. I might get a tattoo of the five-element Tamari lattice someday.</p> <figcaption><a href="http://en.wikipedia.org/wiki/File:Tamari_lattice.svg">http://en.wikipedia.org/wiki/File:Tamari_lattice.svg</a></figcaption>
<figure> </figure>
<img src="/static/tamari/tamari_5.png" alt="Tamari lattice for a five-element tree."> <p>There are a lot of ways to reorganize a Tamari lattice, and it takes some artistic work to make one that really looks good. You can even visualize the same graph as <a href="http://en.wikipedia.org/wiki/Associahedron">a 3D shape called an "associahedron"</a>, but I like it in the simple gridded lattice form above. It reminds me how much beauty there can be in regularity - you can see the grid, but it doesn't look constrained by it. I might get a tattoo of the five-element Tamari lattice someday.</p>
<figcaption>Also the five-element lattice! Compare to the <a href="http://wikipedia.org/wiki/Tamari_lattice">example above, on wikipedia.</a>. <a class="source" href="/static/tamari/tamari_5.dot">Source file.</a></figcaption> <figure>
</figure> <img src="/tamari/tamari_5.png" alt="Tamari lattice for a five-element tree.">
<p>All these graphs with the ovals and the curvy lines were generated by yours truly! I made some python that would take a string representation of an association of a number of elements and convert it into an easily-manipulated memory representation. Then, a few tree rotations spit out all the possible results of left-associating on it, and it was relatively simple to print out a <code>.dot</code> file, parseable by <a href="http://www.graphviz.org/">graphviz</a>, that described the graph. It even labeled the nodes!</p> <figcaption>Also the five-element lattice! Compare to the <a href="http://wikipedia.org/wiki/Tamari_lattice">example above, on wikipedia.</a>. <a class="source" href="/tamari/tamari_5.dot">Source file.</a></figcaption>
<p><code>dot</code> happily converted them into the <code>png</code> files you're looking at. Of course, they don't have the human touch, so they're not organized into beautiful grid lines and 45° angles - but it can be fun to try to mentally reorganize them into a nicer shape. If you want, you can download the <code>.dot</code> source files for any of these, and play around with them in a graph-editing program (such as <a href="https://github.com/jrfonseca/xdot.py">XDot</a>)</p> </figure>
<figure> <p>All these graphs with the ovals and the curvy lines were generated by yours truly! I made some python that would take a string representation of an association of a number of elements and convert it into an easily-manipulated memory representation. Then, a few tree rotations spit out all the possible results of left-associating on it, and it was relatively simple to print out a <code>.dot</code> file, parseable by <a href="http://www.graphviz.org/">graphviz</a>, that described the graph. It even labeled the nodes!</p>
<img src="/static/tamari/tamari_6.png" alt="Tamari lattice for a six-element tree."> <p><code>dot</code> happily converted them into the <code>png</code> files you're looking at. Of course, they don't have the human touch, so they're not organized into beautiful grid lines and 45° angles - but it can be fun to try to mentally reorganize them into a nicer shape. If you want, you can download the <code>.dot</code> source files for any of these, and play around with them in a graph-editing program (such as <a href="https://github.com/jrfonseca/xdot.py">XDot</a>)</p>
<figcaption>It's starting to get out of hand, I think.<a class="source" href="/static/tamari/tamari_6.dot">Source file.</a></figcaption> <figure>
</figure> <img src="/tamari/tamari_6.png" alt="Tamari lattice for a six-element tree.">
<p>Unfortunately, at a certain point I think it's going to get difficult to make these pretty. It turns out there are a lot of ways to associate a larger number of elements! Starting with a six-element tree or string, there are 42 elements (above). With seven, there are 132! Wowie!</p> <figcaption>It's starting to get out of hand, I think. <a class="source" href="/tamari/tamari_6.dot">Source file.</a></figcaption>
<figure> </figure>
<img src="/static/tamari/tamari_7.png" alt="Tamari lattice for a seven-element tree."> <p>Unfortunately, at a certain point I think it's going to get difficult to make these pretty. It turns out there are a lot of ways to associate a larger number of elements! Starting with a six-element tree or string, there are 42 elements (above). With seven, there are 132! Wowie!</p>
<figcaption>Oh dear. <a class="source" href="/static/tamari/tamari_7.dot">Source file.</a></figcaption> <figure>
</figure> <img src="/tamari/tamari_7.png" alt="Tamari lattice for a seven-element tree.">
<p>My server was chugging along trying to generate <code>tamari_8.dot</code> but I started getting messages from linode about going over my CPU quotas, so I canceled it - after it ran for an hour or so, without finishing. I think the seven-element one is messy-looking enough!</p> <figcaption>Oh dear. <a class="source" href="/tamari/tamari_7.dot">Source file.</a></figcaption>
<p>You can look at the <a class="source" href="/static/tamari/tamari.py">python script</a> I used to make this, but it's not particularly pretty - I was bored one day and decided I was going to figure out how to generate these... It's not exactly meant to be extensible. It's got a basic binary tree node class I threw together for working the association rules and a handful of (really ugly) helper functions. I just went through and rewrote it a bit to be nicer - the final output loop may please you if you enjoy <code>set</code>s and list comprehensions:</p> </figure>
<pre> <p>My server was chugging along trying to generate <code>tamari_8.dot</code> but I started getting messages from linode about going over my CPU quotas, so I canceled it - after it ran for an hour or so, without finishing. I think the seven-element one is messy-looking enough!</p>
<p>You can look at the <a class="source" href="/tamari/tamari.py">python script</a> I used to make this, but it's not particularly pretty - I was bored one day and decided I was going to figure out how to generate these... It's not exactly meant to be extensible. It's got a basic binary tree node class I threw together for working the association rules and a handful of (really ugly) helper functions. I just went through and rewrote it a bit to be nicer - the final output loop may please you if you enjoy <code>set</code>s and list comprehensions:</p>
<pre>
<code class="language-python">current_generation = set() <code class="language-python">current_generation = set()
next_generation = {RootOfAllEvil} next_generation = {RootOfAllEvil}
edges = set() edges = set()
labels = set() labels = set()
while next_generation: # While there are trees to examine. while next_generation: # While there are trees to examine.
# Move to look at the next generation. # Move to look at the next generation.
current_generation = next_generation current_generation = next_generation
# Clear out the next gen to fill it with the children of this generation. # Clear out the next gen to fill it with the children of this generation.
next_generation = set() next_generation = set()
# Ensure there are labels for this generation. # Ensure there are labels for this generation.
labels = labels | set(label_from_node(parent) for parent in current_generation) labels = labels | set(label_from_node(parent) for parent in current_generation)
for parent in current_generation: for parent in current_generation:
children = generate_children(parent) children = generate_children(parent)
labels = labels | set(label_from_node(child) for child in children) labels = labels | set(label_from_node(child) for child in children)
edges = edges | set(str(parent) + " -> " + str(child) + ";" for child in children) edges = edges | set(str(parent) + " -> " + str(child) + ";" for child in children)
next_generation = next_generation | children next_generation = next_generation | children
# Output a dot-formatted stream! # Output a dot-formatted stream!
args.output.write(u"digraph tamari {\n") args.output.write(u"digraph tamari {\n")
args.output.write(u"\n".join(labels) + "\n") args.output.write(u"\n".join(labels) + "\n")
args.output.write(u"\n".join(edges)) args.output.write(u"\n".join(edges))
args.output.write(u"\n}\n")</code></pre> args.output.write(u"\n}\n")</code></pre>
<p>The full script can be used by running <code class="language-bash">python tamari.py --length 4 | dot -Tpng > output.png</code> to produce a graph. <code>tamari.py</code> will print out to a specified file if you also include a filename: <code class="language-bash">python tamari.py --length 5 output.dot</code></p> <p>The full script can be used by running <code class="language-bash">python tamari.py --length 4 | dot -Tpng > output.png</code> to produce a graph. <code>tamari.py</code> will print out to a specified file if you also include a filename: <code class="language-bash">python tamari.py --length 5 output.dot</code></p>
</article> </article>

View File

Before

Width:  |  Height:  |  Size: 84 B

After

Width:  |  Height:  |  Size: 84 B

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

View File

Before

Width:  |  Height:  |  Size: 317 KiB

After

Width:  |  Height:  |  Size: 317 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB