this, and the module pattern) was really straightforward, but I found the day's project (in collaboration with Irene Ngyuen) on client-side MVC quite challenging at times; I fear that we were only the second-best Irene–Zach team today. I'm sleeping over at the office again tonight, which seems like a good thing to do twice a week maybe?—when I stay, I can fit in some quality solo hacking time until sleep or distraction takes me, whereas I am not inclined to do so after a train and bike ride home. Case in point: I got a crude form of authentication working in Wires today! So many feels!
Wednesday 30 October 2013— Our focus this week is Backbone.js, a library for doing client-side stuff. I hadn't been sure what to do for my capstone project, but now (perhaps inspired by remembering how I really ought to use feeds instead of manually navigating to my favorite blogs for all the world as if it were 2003) I'm thinking of making an RSS reader and calling it Event Listener. In the evening, I made a small improvement to the Wires template engine, and I started working on an improvement to how objects inherit from the ORM base class, but it's getting late and I'm not done debugging and I wasn't planning on sleeping over tonight, so rather than pushing egregiously broken code to GitHub, I backed up my work as an online paste of a diff obtained by redirecting
git stash show -p.
Thursday 24 October 2013 (well, 0106 Friday)— Yesterday ("yesterday") I worked with Tommy Nast on a crude Asteroids clone using HTML canvas, and today ("today") I worked with Irene Zhou on a towers of Hanoi UI and started a Snake game using jQuery and DOM manipulation. I'm sleeping over at the office tonight, having spent the evening working on Wires.
Monday 14 October 2013— I'll confess that I didn't have a productive weekend at all. No excuses; I just got distracted. You could argue (I won't, but you can) that it's perfectly healthy and fine to take some well-earned relaxation on one's days off, but even relaxation is something that can be done better or worse: hours of the latest ephemeral internet amusements are probably much less rejuvenating than hours of ... I don't know, some sort of activity that doesn't involve sitting in front of a monitor?—I presume such things still exist even if I can't remember them anymore.
Still no deal in the BART contract talks; I took an evening train and slept at the office last night because we didn't know whether there would be trains in the morning. As it turns out, there were, but there likely won't be tomorrow. A moment of amusement is provided by imagining what kind of vicious and histrionic things a frustrated commuter might say if they were angry ("Curse the unions! Curse anyone who won't curse the unions! Curse anyone who won't put a light in their window and sit up all night cursing the unions! Let management fire them and hire scabs! Let hackers insert their names into the public sex-offender registry!" &c.), but in truth, I ain't even mad. (This is in accordance with policy; even if we were to suppose that I somehow knew how the labor dispute should ("should") be resolved, it would still be a waste of cognition to think about it unless we were also to suppose that people care what I think—and that's ridiculous.)
Today we did solo work on an application to keep track of musical artists and their associated albums and tracks, in the process gaining some more practice with authentication and learning about ActionMailer.
Tomorrow there's an assessment scheduled, and I really ought to have taken the time on the weekend to go through the posted practice-assessment, because I looked at it this evening, and somehow getting the specs to pass is much more difficult than I would have imagined. I may have a slight attitude problem: I tend to hold the entire idea of "studying for a test" in contempt (for surely we should study exactly the things that are worth knowing, tests merely being a instrumentally useful device for measuring what we have retained), but this is probably an error of modeling myself as having more agency than I actually have. All principles and rhetoric aside, we can predict that if I had studied for the test last week, then I wouldn't have forgotten the HAVING clause, but I didn't, so I did.
And that's terrible.
Monday 7 October 2013— The main part of SedentaryRecord went pretty smoothly. I like my one-liner implementation of the
has_many_through association better than the instructions' suggestion of writing a whole new query template; the TA Patrick pointed out that my version is inefficient (firing off two queries rather than one), but instead of writing the query-saving long version right away, I decided to try implementing validations first (one of the suggested extension ideas). That didn't go well at all; I spent a lot of time ineffectually hacking away at the problem but didn't even come up with anything worth committing!
Wednesday 9 October 2013— I did poorly on the assessment yesterday. There were eight SQL queries to write; the first five were trivial, but I bombed the last three because I'm a moron and didn't remember that the keyword for filtering aggregations was HAVING. I worked with William Ott on an ice-cream finder (which uses Google Maps APIs to print out directions to nearby ice-cream) and a Twitter client. Of course, it simply wouldn't do to write an ice-cream finder without using it to find ice-cream, so after class we took one of our program's suggestions and bought ice-cream at the Häagen-Dazs in the mall on Market and Fifth. Today I worked with David A.; we learned about routers and controllers.
Monday 30 September 2013— Today's assessment was implementing Crazy Eights in accordance with the given RSpec tests. In the afternoon, I worked with Dan Quan on exercises from the SQL Zoo, which varied wildly in difficulty.
Tuesday 1 October 2013— Today I worked with A. J. Gregory again, this time on a cute Ruby program for interacting with a database. A few remarks follow. The first remark: I much prefer the
%Q syntax for multiline strings over heredocs. The second remark: it turns out that using string interpolation to compose database queries is very bad, because it leaves you vulnerable to SQL-injection attacks. The third, and final, remark: you shouldn't name any of your Ruby classes "Data," because apparently this name is already used by a regrettably exposed implementation detail of the interpreter itself.
Monday 23 September 2013— I rewrote most of the tic-tac-toe game yesterday; information-theoretically speaking, the board state is only 9 lg 3 ≈ 14.26 bits, but for better or for worse, I resisted the temptation to represent it as a two-character string. Still (still!) didn't get the AI working, though. Today was our first assessment: way too easy, I thought; we were given about an hour, and I finished in under half that. Then we had a lecture/Q&A period which I thought was too long, which covered the solutions to the assessment and default hash values. Why does anyone think lectures are a good idea? I'll confess to hanging out in the back and reading a little bit from A Farewell to Alms, which I bought on a whim on Saturday at Half-Price Books (which is a nice store, although you have to wonder whose idea it was to stock so many copies of Elliptic Partial Differential Equations and Quasiconformal Mappings in the Plane). At lunch I bought coffee and food at Starbucks and spent a little more time trying to debug the tic-tac-toe AI—still to no avail, but I'll get there eventually! (Tic-tac-toe itself is dross, but it's really important to get minimax right, because it should generalize to other games without too much trouble, and we're doing chess later this week.) Speaking of games on grids, today's project was to clone Minesweeper. I worked with Jeff Fiddler, who is the Jeff from Nevada (and not the other Jeff who tried to teach math in high schools but was frustrated with the overemphasis on standardized tests). It went really well; we used pretty Unicode symbols and even got around to implementing a cursor interface (which is way better than making the user enter coordinates)!
Monday 16 September 2013— For the next couple months, I'm going to be engrossed in an intensive web development course offered by App Academy; it's pretty great! Part of the routine is to write end-of-day blogposts describing what we've learned; I guess we were "supposed" to start a Tumblr specifically for these, but that's dumb because I already have a blog, so I think I'll just put my updates here (updating the post throughout the week). Today was the first day! App Academy puts a lot of focus on pair programming: you have two people at a workstation; only the "driver" types, while the "navigator" offers direction (and then you switch roles). Today I was paired with Chris Evans, who is a nice guy who knows way more math than me! Today our task was a bunch of fairly straightfoward Ruby exercises: monkeypatch the Array class to do this-and-such, make a playable Tower of Hanoi game, that sort of thing. The most challenging one was part 15 of Test First Ruby: write a method that accepts integers and returns a string describing the number in words (so e.g. 259123 becomes "two hundred fifty nine thousand one hundred twenty three"). Chris and I finished the most important stuff on time and started working on the bonus project about solving mazes, but we didn't get too far with that in the time remaining.
Dear reader, Ruby is a pretty okay programming language, but I have to say I feel ambivalent about the use of
end as block delimiters. (Contrast to braces in C/Java/&c. or indentation in Python.) Three keystrokes just to close a block?! Scandalous!
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
end. For example, pasting the following code into one's Emacs init file assigns
M-]) to insert the text
end), much as one would type
Shift-]) for an open- (respectively close-) brace, except with Alt ("Meta" in Emacs parlance) instead of Shift—
(global-set-key (kbd "M-[") 'block-do)
(global-set-key (kbd "M-]") 'block-end)
I guess this would also be useful for like, Lua.
Dear reader, have you ever dreamed of solving instances of the maximum flow problem? Sure you have! Suppose we have a weighted directed graph, which we might imagine as a network of pipes (represented by the edges) between locations (represented by the nodes), pipes through which some sort of fluid might thereby be transported across the network. One node is designated the source, another is called the sink, and the weight of the edge (i, j) represents the maximum capacity of the pipe which transports fluid from the location i to location j. The maximum-flow problem is precisely the question of how to transport the maximum possible amount of fluid from the source to the sink (without any fluid leaking or magically appearing at any of the intermediate nodes). That is, we want to assign an amount of fluid flow to each edge, not to exceed that edge's capacity, such that inflow equals outflow for all the intermediate (i.e., non-source, non-sink) nodes, and such that the total flow reaching the sink is maximized.
Dear reader, I have got to tell you, fandom is intense. One day last October Equestria Daily (internet clearinghouse for fans of the animated series My Little Pony: Friendship Is Magic) posts a joke proposal for a programming language (FIM++) based on the show, and within the week there's a working interpreter for it. What does it mean to model a programming language after a cartoon, you ask? Well, in the show, episodes typically end with our heroine Twilight Sparkle (or after Season Two, Episode Three "Lesson Zero", one of her friends) writing a letter about what she's learned about the magic of friendship to her mentor (and God-Empress of the sun) Princess Celestia. So, then, why not have an esoteric programming langauge where the source code reads like a letter to Princess Celestia? Adorable, right?
So, this gift having been provided to us courtesy of Karol S. 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—
Dear reader, you know what's way more fun than feeling sad about the nature of the cosmos? Data compression, that's what! Suppose you want to send a message to your friends in a nearby alternate universe, but interuniversal communication bandwidth is very expensive (different universes can't physically interact, so we and our alternate-universe analogues can only communicate by mutually inferring what the other party must be saying, which takes monstrous amounts of computing power and is not cheap), so you need to make your message as brief as possible. Note that 'brief' doesn't just have to do with how long your message is in natural language, it also has to do with how that message is represented over the transuniveral communication channel: indeed, the more efficient the encoding, the more you can afford to say on a fixed budget.
The classic ASCII encoding scheme uses seven bits to represent each character. (Seven?—you ask perplexedly, surely you mean eight? Apparently it was seven in the original version.) Can we do better? Well ... ASCII has a lot of stuff that arguably you don't need that badly. Really, upper and lower case letters? Ampersands, asterisks, backslashes? And don't get me started about those unprintable control characters! If we restrict our message to just the uncased alphabet A through Z plus space and a few punctuation marks, then we can encode our message using only a 32 (= 25) character set, at five bits per character.
Can we do better? Seemingly not—24 = 16 isn't a big enough character set to cover the alphabet. Unless ...
Jurij Kovič's paper "The Arithmetic Derivative and Antiderivative" contains a curious remark in Section 1.2. Having just stated the definition of the logarithmic arithmetic derivative (L(n) = n′/n = Σj aj/pj where the prime mark indicates the arithmetic derivative, and Πipiai is the prime factorization of n), Kovič writes:
The logarithmic derivative is an additive function L(xy) = L(x) + L(y) for any x, y ∈ ℚ. Consequently, using a table of values L(p) = 1/p (computed to sufficient decimal places!) and the formula D(x) = L(x)·x, it is easy to find D(n) for n ∈ ℕ having all its prime factors in the table.
... a table of values? Did I read that correctly? Surely there must be some mistake; surely a paper published in 2012 can't expect us to rely on a printed table, for all the world as if we were John Napier in the seventeenth century! But never fear, dear reader, for the situation is easily rectified—with just a few lines of Python, you can take all the arithmetic derivatives you like on your own personal computing device.
Sometimes I think it's sad that the most popular programming languages use "=" for assignment rather than ":=" (like Pascal). Equality is a symmetrical relationship: "a equals b" means that a and b are the same thing or have the same value, and this is clearly the same as saying that "b equals a". Assignment isn't like that: putting the value b in a box named a isn't the same as putting the value a in a box named b!—surely an asymmetrical operation deserves an asymmetrical notation? Okay, so it is an extra character, but any decent editor can be configured to save you the keystroke.
I'd like to see the colon-equals assignment symbol more often in math, too. For example, shouldn't we be writing lower indices of summation like this?—
—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:
sum = 0;
for (int j=0; j<=n; j++)
sum += f(j);
What the utter novice finds brilliant and fascinating, the slightly-more-experienced novice finds obvious and boring.
When you're trying to think of cool things to do with a system, one of the obvious things to try is to abuse self-reference for all the world as if you were Douglas fucking Hofstadter—but it's not cool, precisely because it is so obvious, and you're not Douglas Hofstadter.
Once I made a Git repository and a Mercurial repository living in the same directory, tracking each other endlessly, one going out of date the moment you committed to the other ...
But that's not interesting.
You can run Emacs inside a terminal, and you can run a terminal inside Emacs—in fact, you can run two (M-x term, M-x ansi-term). Therefore you can run two instances of Emacs within Emacs. Each of those Emacsen could run some natural number of other nested Emacsen, and therefore (to a certain perverse sort of mind) could be said to represent that natural number, which I presume could be determined programmatically (via recursion). Two-counter machines are Turing-complete. So, in principle, if you didn't run out of memory, you could build a computer out of instances of Emacs running on your computer ...
But that's boring.
Dear reader, I don't think I've ever told you how much I love the Python standard library, but I do. When they say "Batteries included," they may not mean it in the sense of "a device that produces electricity by a chemical reaction between two substances," but they do mean it in the sense of "an array of similar things," where the similar things are great libraries. If you need a CSV reader, it's there. If you need fixed-point decimal arithmetic, it's there. But although perhaps it should not have surprised me, never has my joy and appreciation been greater than the fateful moment when I learned that the standard library itself contains a module for