From 05d481d6f977385032266ba9361814c278ef410c Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Tue, 14 Jul 2026 13:56:43 -0700 Subject: [PATCH] classify fenced pre/code blocks Someone probably worked really hard on Pygments's guess-lexer, but now it's just garbage in the eyes of Claude --- content/2012/colon-equals.md | 2 +- .../computing-the-arithmetic-derivative.md | 4 +-- .../training-your-very-own-turtle-to-draw.md | 12 ++++----- content/2013/computing-the-powerset.md | 2 +- content/2013/doend-macros-for-emacs.md | 2 +- content/2013/ford-fulkerson.md | 16 ++++++------ content/2013/huffman.md | 16 ++++++------ content/2013/quicksort-in-fim.md | 6 ++--- ...ode-i-havent-found-an-excuse-to-use-yet.md | 2 +- content/2014/clarity-of-intent.md | 2 +- content/2014/consistent-hashing.md | 10 +++---- content/2014/convention.md | 2 +- ...kdown-to-html-within-emacs-using-pandoc.md | 2 +- content/2014/debugging-techniques-i.md | 2 +- content/2014/growl.md | 2 +- content/2014/last-friday-night.md | 6 ++--- .../my-favorite-error-message-this-year.md | 2 +- content/2015/attentional-shunt.md | 2 +- content/2015/back-from-running.md | 2 +- content/2015/dollar.md | 4 +-- content/2015/epistolary.md | 2 +- .../2015/monthly-favorites-september-2015.md | 4 +-- .../2015/the-foundations-of-erasure-codes.md | 26 +++++++++---------- content/2015/xxx-i.md | 2 +- content/2015/xxx-ii.md | 2 +- content/2015/xxx-iii.md | 2 +- content/2016/0x1f431-cat-face.md | 2 +- content/2016/missing-refutations.md | 2 +- content/2016/subzero.md | 8 +++--- content/2016/todo-i.md | 2 +- content/2018/binge-purge.md | 2 +- pelicanconf.py | 2 +- 32 files changed, 77 insertions(+), 77 deletions(-) diff --git a/content/2012/colon-equals.md b/content/2012/colon-equals.md index a46aed1..ec61bcc 100644 --- a/content/2012/colon-equals.md +++ b/content/2012/colon-equals.md @@ -13,7 +13,7 @@ $$\sum\_{j:=0}^n f(j)$$ —the rationale being that the text under the sigma _isn't_ asserting that _j_ _equals_ zero, but rather that _j_ is _assigned_ zero as the initial index value of what is, in fact, a for loop: -``` +```c sum = 0; for (int j=0; j<=n; j++) { diff --git a/content/2012/computing-the-arithmetic-derivative.md b/content/2012/computing-the-arithmetic-derivative.md index 2cf4b89..078c82e 100644 --- a/content/2012/computing-the-arithmetic-derivative.md +++ b/content/2012/computing-the-arithmetic-derivative.md @@ -13,7 +13,7 @@ Jurij Kovič's paper "[The Arithmetic Derivative and Antiderivative](https://cs. Although first, we will need a function to find the prime factorization of a natural number. You can write your own, copy-paste [someone else's](http://glowingpython.blogspot.com/2011/07/prime-factor-decomposition-of-number.html), or (my personal favorite) use the subprocess module to call the system's _/usr/bin/factor_: -``` +```python from subprocess import check_output def factorize(n): @@ -27,7 +27,7 @@ def factorize(n): But then coding the definition of the arithmetic derivative itself is easy: -``` +```python def D(n): result = 0 factorization = factorize(n) diff --git a/content/2012/training-your-very-own-turtle-to-draw.md b/content/2012/training-your-very-own-turtle-to-draw.md index 3cc4393..d19fc6d 100644 --- a/content/2012/training-your-very-own-turtle-to-draw.md +++ b/content/2012/training-your-very-own-turtle-to-draw.md @@ -11,13 +11,13 @@ ___TURTLE GRAPHICS___ Yes, turtle graphics! In case you had a deprived childhood, I should explain: the idea is that you have a cursor on the screen (the turtle), and you can type, say, -``` +```text FORWARD 10 ``` and then the turtle will move forward ten units, drawing a line as it goes. And then you can say, like, -``` +```text RIGHT 60 ``` @@ -45,14 +45,14 @@ That is, we pick a number _c_ in ℂ, iterate _z__n_+1 = _z__n_2 + _c_ starting Let's start writing instructions for our turtle. First, we'll summon the turtle. Also, let's tell her to look up instructions on how to compute the argument of a complex number—don't ask me how, but I have a feeling we're going to need that later: -``` +```python import turtle from cmath import phase ``` Now, it turns out (claims _Wikipedia_, and I believe it), that if the absolute value of one of our _z__n_s ever exceeds two, then that sequence will diverge. This seems like a useful fact, so let's tell our turtle how to calculate how many iterations it will take for the sequence associated with a particular _c_ to exceed two, and if it doesn't do so within some given number of iterations, then to tell us that: -``` +```python def z_n_escape_time(c, n): z = 0 for i in range(n): @@ -64,7 +64,7 @@ def z_n_escape_time(c, n): To approximate the boundary of the Mandelbrot set, we'll tell the turtle to consider a grid of reasonably-finely-spaced points, and to consider a point to be on the boundary if the number of iterations it takes for the sequence for that point to exceed two is in some given range. We'll also tell her to sort those points by their argument, because that seems like a somewhat-reasonable order to visit them in: -``` +```python def mandelbrot_edge(resolution, iterations, edge): points = [] x_coordinates = [-2+i*(3/resolution) for i in range(int(resolution*1.5))] @@ -79,7 +79,7 @@ def mandelbrot_edge(resolution, iterations, edge): Then (choosing some reasonable-looking numbers as specific parameters for our earlier instructions) we tell our turtle to visit all those points, drawing along the way: -``` +```python def draw_boundary(protagonist, boundary_points, speed): protagonist.speed(speed) protagonist.penup() diff --git a/content/2013/computing-the-powerset.md b/content/2013/computing-the-powerset.md index 968568d..68bb7cd 100644 --- a/content/2013/computing-the-powerset.md +++ b/content/2013/computing-the-powerset.md @@ -15,7 +15,7 @@ $$\mathcal{P}(S\cup\{e\})=\mathcal{P}(S)\cup\{t\cup\{e\}\}\_{t\in\mathcal{P}(S)} So in Clojure we might say -``` +```clojure (require 'clojure.set) (defn include-element [collection element] diff --git a/content/2013/doend-macros-for-emacs.md b/content/2013/doend-macros-for-emacs.md index 6584d55..6621a78 100644 --- a/content/2013/doend-macros-for-emacs.md +++ b/content/2013/doend-macros-for-emacs.md @@ -9,7 +9,7 @@ Dear reader, Ruby is a pretty okay programming language, but I have to say I fee Or _maybe_ ... _not_-so-scandalous. For two or three _characters_ need not imply two or three _keystrokes_; one need only configure one's editor with convenient bindings for the insertion of `do` and `end`. For example, pasting the following code into one's Emacs init file assigns `M-[` (respectively `M-]`) to insert the text `do` (respectively `end`), much as one would type `Shift-[` (respectively `Shift-]`) for an open- (respectively close-) brace, except with Alt ("Meta" in Emacs parlance) instead of Shift— -``` +```elisp (fset 'block-do "do") (global-set-key (kbd "M-[") 'block-do) diff --git a/content/2013/ford-fulkerson.md b/content/2013/ford-fulkerson.md index 7875445..497af10 100644 --- a/content/2013/ford-fulkerson.md +++ b/content/2013/ford-fulkerson.md @@ -9,7 +9,7 @@ Dear reader, have you ever dreamed of solving instances of the maximum flow prob It turns out that there's a conceptually straightforward algorithm for solving the maximum flow problem, known as the Ford-Fulkerson method, which we'll implement in Ruby. But first, we'll want to pin down exactly how the flow network will be represented. Let's define an `Edge` class, each instance of which will be initialized with the names of the nodes at its head and tail, and the edge's maximum capacity: -``` +```ruby class Edge attr_accessor :tail attr_accessor :head @@ -25,7 +25,7 @@ end And let's also make a `FlowNetwork` class, defined by the names of its source and sink nodes, and a hash which maps `Edge`s to the amount of flow currently assigned to that `Edge`: -``` +```ruby class FlowNetwork attr_accessor :source attr_accessor :sink @@ -45,7 +45,7 @@ class FlowNetwork So how _do_ we solve the maximum-flow problem? It's pretty simple! We start with the "zero flow." (In our code above, this is already done when we initialize an instance of `FlowNetwork`.) We then find an _augmenting path_ from the source to the sink (possibly including edges traversed backwards) such that all the forward-traversed edges along the path have not been assigned their maximum capacity, and all the backward-traversed edges have a nonzero amount of flow. This is path along which we can _push_ more flow from the source to the sink, by increasing the amount of flow along the forward-traversed edges, and decreasing the amount of flow along the backward-traversed edges. (Convince yourself that pushing flow through an edge _backwards_ amounts to decreasing the amount of flow along that edge.) Once we've found such an augmenting path, we push as much flow as we can along it. Then we look for another augmenting path and do the same, until no more augmenting paths can be found. It turns out that the resulting flow assignment solves our problem. So that's the Ford-Fulkerson method: -``` +```ruby def ford_fulkerson path = augmenting_path while path @@ -57,7 +57,7 @@ So how _do_ we solve the maximum-flow problem? It's pretty simple! We start with Of course, we need to specify exactly how to _find_ these augmenting paths. This is a little bit more involved. It amounts to doing walking through the graph starting at the source, "labeling" nodes that could be part of an augmenting path, and scanning neighbors of labeled nodes looking for more labelable nodes, until we reach the sink (in which case we have found a path) or until we run out of nodes to scan (in which case there are no augmenting paths left). Sort of like this: -``` +```ruby def augmenting_path labeled = {@source=>nil} # keys are labeled nodes; values, parents thereof scanned = {} @@ -100,7 +100,7 @@ Of course, we need to specify exactly how to _find_ these augmenting paths. This And of course, we also need code to actually augment the flow along the path found— -``` +```ruby def flow_augmentation(path) flow = +1.0/0 # positive infinity edges = [] @@ -134,7 +134,7 @@ And of course, we also need code to actually augment the flow along the path fou Then throw in a reporting method so we have some way of actually inspecting our network and its completed flow assignment, close the `FlowNetwork` class definition (at long last) ... -``` +```ruby def report print "Source: ", @source, "\n" print "Sink: ", @sink, "\n" @@ -153,7 +153,7 @@ end We can then (admittedly with some typing) call for a solution like so: -``` +```ruby my_edges = [Edge.new('A', 'B', 12), Edge.new('A', 'E', 15), Edge.new('A', 'G', 13), Edge.new('B', 'C', 9), Edge.new('E', 'C', 11), Edge.new('G', 'E', 7), Edge.new('C', 'D', 18), Edge.new('C', 'F', 10), @@ -167,7 +167,7 @@ my_network.report And receive it like so: -``` +```text Source: A Sink: I A -> B; capacity: 12, flow: 9 diff --git a/content/2013/huffman.md b/content/2013/huffman.md index c6bc30d..0626b5f 100644 --- a/content/2013/huffman.md +++ b/content/2013/huffman.md @@ -19,7 +19,7 @@ Consider the process of decoding a prefix-free code: we read bits from the start First, we'll need a data structure to represent the nodes of the tree. Actually, we'll use a structure that represents a node _and_ all of its children, which we'll call `Subtree`. Each instance of `Subtree` will have fields for a _character_ and _frequency_ associated with a node, and the node's left and right children if any (which are also instances of `Subtree`). -``` +```python class Subtree: def __init__(self, char, freq, left, right): self.char = char @@ -32,14 +32,14 @@ The leaf nodes of our tree will have the character field set to a character in o We'll also want nodes to be comparable by their frequencies: -``` +```python def __gt__(self, othernode): return self.freq > othernode.freq ``` When all is said and done, Huffman's algorithm will give us an instance of `Subtree` representing our tree, but it would really be more convenient to have the decoding information embodied by the tree in the form of Python dictionary mapping bitstrings to the characters they encode. We can get this by doing a standard recursive tree walk: -``` +```python def codebook(self): codes = {} def traversal(item, code): @@ -54,7 +54,7 @@ When all is said and done, Huffman's algorithm will give us an instance of `Subt We're also going to need a _min-priority queue_, a dynamic set from which we can insert items and retrieve the "smallest": -``` +```python class MinPriorityQueue: def __init__(self): self.queue = [] @@ -69,7 +69,7 @@ class MinPriorityQueue: Now that we have the appropriate data structures, we're ready for Huffman's algorithm. Suppose our character/frequency data are given to us in a Python dictionary `C`. For each character, we create an instance of `Subtree` to be the corresponding leaf node in our tree, and put them all in a min-priority queue. Then we build our tree from the bottom up by selecting the two lowest-frequency nodes in the queue, making them the children of a new node whose frequency is the sum of their frequencies, putting the new node back in the priority queue, and again until we've built the entire tree: -``` +```python def Huffman(C): Q = MinPriorityQueue() leaves = {Subtree(k, C[k], None, None) for k in C} @@ -85,7 +85,7 @@ def Huffman(C): And that's Huffman's algorithm. Of course, we'll also want functions for encoding and decoding a message: -``` +```python def code(plaintext, codebook): return ''.join(codebook[c] for c in plaintext) @@ -103,7 +103,7 @@ def decode(ciphertext, codebook): So, suppose you want to send your friends in a nearby alternate universe the eighty-two character message, "I USED TO WONDER WHAT FRIENDSHIP COULD BE, UNTIL YOU ALL SHARED ITS MAGIC WITH ME." If you used seven-bit ASCII, you'd have to pay the cost of transmitting 82\*7 = 574 bits. But if you use a Huffman code informed by knowledge of [English letter frequencies](http://en.wikipedia.org/wiki/Letter_frequency#Relative_frequencies_of_letters_in_the_English_language) ... -``` +```python eng_freqs = {'A' : 8167, 'B' : 1492, 'C' : 2782, 'D' : 4253, 'E' : 12702, 'F' : 2228, 'G' : 2015, 'H' : 6094, 'I' : 6966, 'J' : 153, 'K' : 772, 'L' : 4025, 'M' : 2406, 'N' : 6749, 'O' : 7507, 'P' : 1929, 'Q' : 95, @@ -116,7 +116,7 @@ cipher = code(plain, eng_codebook) You can send _this_ instead: -``` +```text 0111010111100000100111001010110110010101110101001011011001001111110101110100 0001010110101011100111111011100101101100100010000011110000101011110110011111 0010110110010101000000011100001011110001101101011110110010100010100111110001 diff --git a/content/2013/quicksort-in-fim.md b/content/2013/quicksort-in-fim.md index c6b0588..779cffa 100644 --- a/content/2013/quicksort-in-fim.md +++ b/content/2013/quicksort-in-fim.md @@ -9,7 +9,7 @@ Dear reader, I have got to tell you, fandom is _intense_. One day last October _ So, this gift having been provided to us courtesy of [Karol S.](https://github.com/KarolS) and the brony community, let's _do_ something with it! More specifically, how about we implement quicksort?—that is a _classic_. What's quicksort? Well, we want to sort a list, right? So—bear with me—we define this partitioning procedure that, given indices into an array, partitions the subarray between those indices into a subsubarray of elements less-than-or-equal-to a given element dubbed the _pivot_, then the pivot itself, then a subsubarray of elements greater than the pivot. How do we do that? Well, let's designate the last element in our subarray as the pivot. Then we're going to scan through all the other elements, and if any of them are less-than-or-equal-to the pivot, we swap it into our first subsubarray and increment a variable keeping track of where the first subsubarray ends. Then, we swap the pivot into place and return its index. In Ruby— -``` +```ruby def partition(array, p, r) i = p-1 for j in p..(r-1) do @@ -25,7 +25,7 @@ end Then we can sort an entire array with a bunch of recursive calls to our partitioning procedure: -``` +```ruby def quicksort(array, p, r) if p < r q = partition(array, p, r) @@ -42,7 +42,7 @@ print my_array # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] So that's quicksort. With a little more effort, we can do the same thing in FIM++: -``` +```text Dear Princess Celestia: Letter about Quicksort: I learned about exchange with Applejack, Rainbow Dash, and Rarity. diff --git a/content/2014/a-line-of-code-i-havent-found-an-excuse-to-use-yet.md b/content/2014/a-line-of-code-i-havent-found-an-excuse-to-use-yet.md index f4df3ec..f0bb58c 100644 --- a/content/2014/a-line-of-code-i-havent-found-an-excuse-to-use-yet.md +++ b/content/2014/a-line-of-code-i-havent-found-an-excuse-to-use-yet.md @@ -5,6 +5,6 @@ Category: Uncategorized Tags: Clojure Slug: a-line-of-code-i-havent-found-an-excuse-to-use-yet -``` +```clojure (defn intentional-mispelling? [sic] ``` diff --git a/content/2014/clarity-of-intent.md b/content/2014/clarity-of-intent.md index db0f0fd..f4e088d 100644 --- a/content/2014/clarity-of-intent.md +++ b/content/2014/clarity-of-intent.md @@ -5,7 +5,7 @@ Category: computing Tags: Python Slug: clarity-of-intent -``` +```irc and here on line 79--- else: return None diff --git a/content/2014/consistent-hashing.md b/content/2014/consistent-hashing.md index c2ff7b6..b8e9ef4 100644 --- a/content/2014/consistent-hashing.md +++ b/content/2014/consistent-hashing.md @@ -17,7 +17,7 @@ One day, after a particularly painful rearrangement of files, you decide enough Anyway, consistent hashing. The essential nature of your problem is that you need a way to split the space of possible filenames into _n_ [partitions](http://en.wikipedia.org/wiki/Partition_of_a_set) in a way that minimizes the number of files that have to change partitions when _n_ changes. So imagine mapping the 128-bit output space of MD5 around a ring. Now pseudorandomly designate _m_ spots on the ring (_m_ being some prudently-chosen natural number) for each of your _n_ storage devices: say, by hashing the device name suffixed with the number _j_ for each _j_ between 0 and _m_–1 inclusive. Internally, you might represent the ring as just an array of hash/device pairs. Like this (in Clojure; here the array and the pairs it contains are actually "vectors")— -``` +```clojure (import 'java.security.MessageDigest) (defn md5 [string] @@ -47,7 +47,7 @@ Anyway, consistent hashing. The essential nature of your problem is that you nee Then when your patrons ask you to store a file, you're still going to hash its name, but instead of taking the residue mod _n_ of the hash to decide where the file should live, you're going to locate the hash in your ring, and find the next designated spot on the ring associated with one of your storage devices, and the file will live on that device. In terms of your internal representation of the ring as an array of hash/device pairs, you'll find the first pair whose first item (the hash of the suffixed device name) is greater than the hash of the name of the file to be stored, and the second item of that pair will tell you which storage device to use. (And if the filename hash is greater than all those stored in the (first items of the pairs stored in the) array, then you just use the first pair in the array. It is supposed to represent a _ring_, after all.) Like this— -``` +```clojure (defn ring-search [ring key] (or (some (fn [pair] (if (> (compare (first pair) key) 0) @@ -61,7 +61,7 @@ Then when your patrons ask you to store a file, you're still going to hash its n And now—why, _now_ when you gain (respectively lose) a storage device, you can decide the allocation question simply by adding (respectively removing) the appropriate designated spots to (respectively from) your ring— -``` +```clojure (defn ring-add [ring device spots] (sort (vec (concat ring (ring-kv-pairs device spots))))) @@ -76,7 +76,7 @@ And now—why, _now_ when you gain (respectively lose) a storage device, you can You decide to run a quick simulation to see if you've gotten this right before saving the edits to your soul. Suppose you had storage devices `device0` through `device5` and your patrons wanted you to store `file0` through `file5999`; how would the files end up distributed across your devices? You choose a prudent-seeming integer for the number of designated spots per device—say, 450?—and write the simulation like this— -``` +```clojure (defn filemap [ring files] (into {} (for [file files @@ -98,7 +98,7 @@ You decide to run a quick simulation to see if you've gotten this right before s And the results seem reasonable enough: -``` +```text $ clojure consistent_hashing.clj [device0 1020] [device1 993] diff --git a/content/2014/convention.md b/content/2014/convention.md index f453852..7ad6407 100644 --- a/content/2014/convention.md +++ b/content/2014/convention.md @@ -5,7 +5,7 @@ Category: computing Tags: Clojure Slug: convention -``` +```console $ lein new 3lg2048 Project names must be valid Clojure symbols. $ lein new Thirty-Three diff --git a/content/2014/convert-markdown-to-html-within-emacs-using-pandoc.md b/content/2014/convert-markdown-to-html-within-emacs-using-pandoc.md index 1007139..fc82baa 100644 --- a/content/2014/convert-markdown-to-html-within-emacs-using-pandoc.md +++ b/content/2014/convert-markdown-to-html-within-emacs-using-pandoc.md @@ -7,7 +7,7 @@ Slug: convert-markdown-to-html-within-emacs-using-pandoc Okay, so there actually is a [pandoc-mode](http://joostkremers.github.io/pandoc-mode/), but I couldn't figure out how to configure and use it, so it was easier to just write the one command that I wanted— -``` +```elisp (defun markdown-to-html () (interactive) (let* ((basename (file-name-sans-extension (buffer-file-name))) diff --git a/content/2014/debugging-techniques-i.md b/content/2014/debugging-techniques-i.md index e26e484..4ef4944 100644 --- a/content/2014/debugging-techniques-i.md +++ b/content/2014/debugging-techniques-i.md @@ -5,7 +5,7 @@ Category: computing Tags: Python Slug: debugging-techniques-i -``` +```python #def my_problematic_function(x): def my_problematic_function(x, call_count=[]): call_count.append(1) diff --git a/content/2014/growl.md b/content/2014/growl.md index 454b2b3..d2c7e26 100644 --- a/content/2014/growl.md +++ b/content/2014/growl.md @@ -11,7 +11,7 @@ _Or you could design a script to make desktop notifications about how much more Well, I already made it for you (unless your Linux distribution doesn't use `notify-send` or you're on a Mac or something). -``` +```python #!/usr/bin/env python3 import argparse diff --git a/content/2014/last-friday-night.md b/content/2014/last-friday-night.md index 2596e81..3428d34 100644 --- a/content/2014/last-friday-night.md +++ b/content/2014/last-friday-night.md @@ -9,7 +9,7 @@ _[it's a blacked-out blur](http://www.youtube.com/watch?v=KlyXNRrsk4A&t=1m19s), \* \* \* -``` +```console $ heroku create Creating howling-nightmare-4505... done, stack is cedar http://howling-nightmare-4505.herokuapp.com/ | git@heroku.com:howling-nightmare-4505.git @@ -20,7 +20,7 @@ Git remote heroku added \* \* \* -``` +```text -----> Python app detected -----> Installing runtime (python-2.7.8) ``` @@ -29,7 +29,7 @@ Git remote heroku added \* \* \* -``` +```console $ echo "python-3.4.1" > runtime.txt $ g a . $ gco -m "the month of July 2010 called and wants their programming language back" diff --git a/content/2014/my-favorite-error-message-this-year.md b/content/2014/my-favorite-error-message-this-year.md index 2819f84..1278722 100644 --- a/content/2014/my-favorite-error-message-this-year.md +++ b/content/2014/my-favorite-error-message-this-year.md @@ -5,7 +5,7 @@ Category: computing Tags: Git, Python Slug: my-favorite-error-message-this-year -``` +```text zmd@SuddenHeap:~/Code/Finetooth$ git commit --amend Traceback (most recent call last): File "./manage.py", line 8, in diff --git a/content/2015/attentional-shunt.md b/content/2015/attentional-shunt.md index c4397f3..d87803f 100644 --- a/content/2015/attentional-shunt.md +++ b/content/2015/attentional-shunt.md @@ -5,7 +5,7 @@ Category: computing Tags: akrasia, Python Slug: attentional-shunt -``` +```python #!/usr/bin/env python3 # Copyright © 2015 Zack M. Davis diff --git a/content/2015/back-from-running.md b/content/2015/back-from-running.md index 88bcfce..34c7f64 100644 --- a/content/2015/back-from-running.md +++ b/content/2015/back-from-running.md @@ -5,7 +5,7 @@ Category: Uncategorized Tags: akrasia Slug: back-from-running -``` +```irc [16:03:37] I'm back from literally running, metaphorically from figurative demons [16:03:50] including the celebrity demon-prince Rateirs-Blak diff --git a/content/2015/dollar.md b/content/2015/dollar.md index 171b29e..65ddcf9 100644 --- a/content/2015/dollar.md +++ b/content/2015/dollar.md @@ -11,7 +11,7 @@ I used to think of `$` in regular expressions as matching the end of the string. Note! The end of the string, _or just before the newline at the end of the string_. -``` +```text In [2]: my_regex = re.compile("foo$") In [3]: my_regex.match("foo") @@ -31,7 +31,7 @@ All this that I have said about `$` in regexes concerns the Python world. Appare > [b]y default, the regular expressions `^` and `$` ignore line terminators and only match at the beginning and the end, respectively, of the entire input sequence. -``` +```text user=> (re-matches #"foo$" "foo") "foo" user=> (re-matches #"foo$" "foo\n") diff --git a/content/2015/epistolary.md b/content/2015/epistolary.md index 3997a3e..8ab0b5c 100644 --- a/content/2015/epistolary.md +++ b/content/2015/epistolary.md @@ -6,7 +6,7 @@ Slug: epistolary [(Previously.)](http://zackmdavis.net/blog/2014/05/a-short-story/) -``` +```irc [19:26:50] alice: you still around? [19:27:08] bob, sort of [19:27:20] alice: ok. never mind. diff --git a/content/2015/monthly-favorites-september-2015.md b/content/2015/monthly-favorites-september-2015.md index 7bc468f..c5d747b 100644 --- a/content/2015/monthly-favorites-september-2015.md +++ b/content/2015/monthly-favorites-september-2015.md @@ -9,14 +9,14 @@ __Favorite commit message fragment:__ "it turns out that it's `\d` that matches __Favorite line of code:__ a tie, between -``` +```rust let mut time_radios: Vec<(Commit, mpsc::Receiver<(Option, f32)>)> = Vec::new(); ``` and -``` +```python for (previous, new), expected in zip( itertools.product(('foo', None), ('bar', None)), ("from foo to bar", "from foo", "to bar", "")): diff --git a/content/2015/the-foundations-of-erasure-codes.md b/content/2015/the-foundations-of-erasure-codes.md index eef7c87..100b97a 100644 --- a/content/2015/the-foundations-of-erasure-codes.md +++ b/content/2015/the-foundations-of-erasure-codes.md @@ -39,7 +39,7 @@ But don't take _my_ word for it! Mere verbal arguments can be deceptive, but [co So suppose we want to save some textual data; say, the string, "THE FUNDAMENTAL PROBLEM OF COMMUNICATION IS THAT OF REPRODUCING AT ONE POINT EITHER EXACTLY OR APPROXIMATELY A MESSAGE SELECTED AT ANOTHER POINT". Now, this data is made out of letters and spaces, not polynomials, but we can process it into a form that will make it easier to make-believe that it is. Say, we split the text into chunks of a fixed size (padding the end with extra spaces if necessary so that our chunk size evenly divides it), and convert the characters into integers from 0 to 26 (space is 0, _A_ is 1, _B_ is 2, _&c._). Here are some functions to help with that— -``` +```python from string import ascii_uppercase ALPHABET = " "+ascii_uppercase @@ -61,7 +61,7 @@ After turning our text into converted chunks (lists of integers), we can interpr (It's actually better if you use polynomials over the _finite field_ 𝔽_q_ of the integers modulo _q_ for some _q_ which is a prime raised to the power of something, but let's not worry about that.) -``` +```python def evaluate_polynomial(coefficients, x): return sum(c * x**i for i, c in enumerate(coefficients)) @@ -77,7 +77,7 @@ def erasure_code(text, chunk_size, encoded_chunk_size): Then, with a choice for the original chunk size (which you'll recall will also be the number of terms each in the polynomials used to encode each chunk) and the size of the resulting encoded chunk (that is, the number of points we'll sample from the polynomials), we can encode our text. -``` +```text $ python3 >>> from reed_solomon import * >>> text = "THE FUNDAMENTAL PROBLEM OF COMMUNICATION IS THAT OF @@ -96,7 +96,7 @@ At this point, our text has been transformed into a Python list, whose elements Let's simulate distributing that encoded information across several storage nodes by writing points with different _x_-values to different files. We'll make-believe that each file is a different storage node. We'll write another function for that. -``` +```python import json def disperse(encoded_chunks): @@ -108,7 +108,7 @@ def disperse(encoded_chunks): And try it out— -``` +```text >>> disperse(encoded) >>> $ ls @@ -125,7 +125,7 @@ In conclusion, that's how you use Reed–Solomon coding to turn comprehensible E What's that you say, dear reader? Demonstrating how to encode something is useless unless you also demonstrate how to decode it? Well, I suppose you may have a point. Never fear—we can do that, too! But first, we'll need some functions for manipulating polynomials (in the "list of coefficients in order of ascending power" form that we've been using). -``` +```python def get_coefficient(P, i): if 0 <= i < len(P): return P[i] @@ -170,7 +170,7 @@ _y_1 ((_x_1 – _x_2)(_x_1 – _x_3)(_x_1 – _x_4)) / ((_x_1 – _x_2)(_x_1 – So by design, our interpolated polynomial takes value _y_1 at _x_1, _y_2 at _x_2, and so forth. In Python, the whole process looks like this— -``` +```python def lagrange_basis_denominator(xs, i): denominator = 1 for j, x in enumerate(xs): @@ -203,7 +203,7 @@ def interpolate(points): With this technique, we now have all the tools we need to recover our text from a subset of the data we wrote to our various "nodes" earlier. What we need to do is this: for each chunk, arbitrarily select a number of stored points equal to our chunk size, _interpolate_ the polynomial from them, _deconvert_ the numbers which are the coefficients of that polynomial back into their character equivalents, _unchunkify_ the chunks into a unified whole, and _unpad_ any whitespace we added to the end when we began. -``` +```python def deconvert(sequence): return ''.join(INT_TO_CHAR[i] for i in sequence) @@ -221,14 +221,14 @@ def erasure_decode(encoded_chunks, chunk_size, encoded_chunk_size): But _about_ that data that we wrote out earlier. -``` +```console $ ls node0 node1 node2 node3 node4 node5 node6 node7 ``` It would hardly be a compelling test of our erasure-coding skills if there were any suspicion that we actually needed _all_ of those files—we really only need as many as our chunk size. So let's suppose that three of our nodes die in a fire— -``` +```console $ rm node1 node3 node6 $ ls node0 node2 node4 node5 node7 @@ -236,7 +236,7 @@ node0 node2 node4 node5 node7 Could this the end of our data? With a full three-eighths of our encoding having been utterly destroyed, is it delusional to hold out hope that our text might yet be faithfully recovered? No! No, it is not! We only need one more function to retrieve the encoded chunks— -``` +```python def retrieve(*nodes): responses = [] for node in nodes: @@ -248,7 +248,7 @@ def retrieve(*nodes): —and then— -``` +```text $ python3 >>> from reed_solomon import * >>> node_data = retrieve("node0", "node2", "node4", "node5", "node7") @@ -256,7 +256,7 @@ $ python3 —successfully decode them! -``` +```pycon >>> erasure_decode(node_data, 5, 8) 'THE FUNDAMENTAL PROBLEM OF COMMUNICATION IS THAT OF REPRODUCING AT ONE POINT EITHER EXACTLY OR APPROXIMATELY A MESSAGE SELECTED AT AN diff --git a/content/2015/xxx-i.md b/content/2015/xxx-i.md index eddc1bd..c32ce75 100644 --- a/content/2015/xxx-i.md +++ b/content/2015/xxx-i.md @@ -5,7 +5,7 @@ Category: computing Tags: Clojure Slug: xxx-i -``` +```clojure ;; XXX: adorable (defmacro λ [& code] `(fn ~@code)) diff --git a/content/2015/xxx-ii.md b/content/2015/xxx-ii.md index 3338349..c2afbb6 100644 --- a/content/2015/xxx-ii.md +++ b/content/2015/xxx-ii.md @@ -5,7 +5,7 @@ Category: Uncategorized Tags: Rust Slug: xxx-ii -``` +```rust // XXX: old_io is probably facing deprecation if names mean anything #![feature(old_io)] use std::old_io; diff --git a/content/2015/xxx-iii.md b/content/2015/xxx-iii.md index bdecee1..7b83584 100644 --- a/content/2015/xxx-iii.md +++ b/content/2015/xxx-iii.md @@ -5,7 +5,7 @@ Category: computing Tags: Rust Slug: xxx-iii -``` +```rust const PSEUDO_DIGITS: [char; 7] = ['M', 'D', 'C', 'L', 'X', 'V', 'I']; const PSEUDO_PLACE_VALUES: [usize; 7] = [1000, 500, 100, 50, 10, 5, 1]; diff --git a/content/2016/0x1f431-cat-face.md b/content/2016/0x1f431-cat-face.md index b66c831..b336531 100644 --- a/content/2016/0x1f431-cat-face.md +++ b/content/2016/0x1f431-cat-face.md @@ -5,7 +5,7 @@ Category: computing Tags: Git, Unicode Slug: 0x1f431-cat-face -``` +```diff diff --git a/.bash_aliases b/.bash_aliases index 648287f..e00dbc9 100644 --- a/.bash_aliases diff --git a/content/2016/missing-refutations.md b/content/2016/missing-refutations.md index f0178ea..4ce8c1d 100644 --- a/content/2016/missing-refutations.md +++ b/content/2016/missing-refutations.md @@ -9,7 +9,7 @@ It [looks like](https://github.com/swiftstack/Chesswork/commit/681085b3) the opp Real chess aficionados (chessters? chessies?) will laugh at me, but it actually took me a while to understand why Ng3 was in that principal variation (I might even have invoked the engine again to help). The position after Ng3 looks like -``` +```text a b c d e f g h 8 ♜ ♜ ♚ 7 ♟ ♟ ♟ ♟ ♟ ♟ diff --git a/content/2016/subzero.md b/content/2016/subzero.md index c095f1b..70d2336 100644 --- a/content/2016/subzero.md +++ b/content/2016/subzero.md @@ -7,7 +7,7 @@ Slug: subzero Python has this elegant destructuring-assignment iterable-unpacking syntax that every serious Pythonista and her dog tends to use whereëver possible. So where a novice might write -``` +```python split_address = address.split(':') host = split_address[0] port = split_address[1] @@ -15,7 +15,7 @@ port = split_address[1] a serious Pythonista (_and_ her dog) would instead say -``` +```python host, port = address.split(':') ``` @@ -23,14 +23,14 @@ which is clearly superior on grounds of succinctness and beauty; we don't want o Consider, however, the somewhat-uncommon case where we have an iterable that, for whatever reason, we happen to _know_ contains only one element, and we want to assign that one element to a variable. Here, I've seen people who ought to know better fall back to indexing: -``` +```python if len(jobs) == 1: job = jobs[0] ``` But there's _no reason_ to violate the æsthetic principle of "use a length-_n_ ([or smaller](https://www.python.org/dev/peps/pep-3132/)) tuple of identifiers on the left side of a destructuring assignment in order to name the elements of a length-_n_ iterable" just because _n_ happens to be one: -``` +```python if len(jobs) == 1: job, = jobs ``` diff --git a/content/2016/todo-i.md b/content/2016/todo-i.md index 7a24892..06b96e1 100644 --- a/content/2016/todo-i.md +++ b/content/2016/todo-i.md @@ -5,7 +5,7 @@ Category: Uncategorized Tags: Rust Slug: todo-i -``` +```rust let path = Path::new("/proc/meminfo"); let proc_meminfo = match File::open(path) { Ok(f) => f, diff --git a/content/2018/binge-purge.md b/content/2018/binge-purge.md index 45e4b74..4ba8d5d 100644 --- a/content/2018/binge-purge.md +++ b/content/2018/binge-purge.md @@ -5,7 +5,7 @@ Category: psychology Tags: akrasia Slug: binge-purge -``` +```console $ history | grep freeciv 605 freeciv 606 sudo apt-get install freeciv diff --git a/pelicanconf.py b/pelicanconf.py index bc4f557..f795fc2 100644 --- a/pelicanconf.py +++ b/pelicanconf.py @@ -74,7 +74,7 @@ PAGINATION_PATTERNS = ( # Markdown extensions MARKDOWN = { 'extension_configs': { - 'markdown.extensions.codehilite': {'css_class': 'highlight'}, + 'markdown.extensions.codehilite': {'css_class': 'highlight', 'guess_lang': False}, 'markdown.extensions.extra': {}, 'markdown.extensions.meta': {}, 'markdown.extensions.toc': { -- 2.53.0