I used to think of
$ in regular expressions as matching the end of the string. I was wrong! It actually might do something more subtle than that, depending on what regex engine you're using. In my native Python's
[m]atches the end of the string or just before the newline at the end of the string, and in MULTILINE mode also matches before a newline.
Note! The end of the string, or just before the newline at the end of the string.
In : my_regex = re.compile("foo$")
In : my_regex.match("foo")
Out: <_sre.SRE_Match object; span=(0, 3), match='foo'>
In : my_regex.match("foo\n")
Out: <_sre.SRE_Match object; span=(0, 3), match='foo'>
I guess I can see the motivation—we often want to use the newline character as a terminator of lines (by definition) or files (by sacred tradition), without wanting to think of
\n as really part of the content of interest—but the disjunctive behavior of
$ can be a source of treacherous bugs in the fingers of misinformed programmers!
Thursday 7 Novembmer 2013— I guess Superscription is going okay. Here's how it works. You can sign up and sign in and stuff. (I used Devise for this rather than rolling my own.) There are forms for adding a category or a subscription URL. When you add a URL, stuff happens which depends on stuff. More specifically, if you enter a URL which the system has never seen before, then a new
Subscription model (which
accepts_nested_attributes_for an associated
UserSubscription join model) is created, and it requests the feed from the URL you supplied and tries to parse the XML using Nokogiri. If that doesn't work, it suggests that maybe you got the URL wrong, but if it does work, then it makes a bunch of Entry objects for all the stories in the feed, saves everything, and redirects you to your subscription index page. But if the system has already seen your URL before (presumably from another user with similar reading tastes), then it doesn't wastefully fetch all that data again: it just makes a new
UserSubscription that points to you and your
Category and the
Subscription that it already has. It's efficient! Then when you click the "Read!" button (which is non-hideously positioned thanks to nearly an hour of fighting the CSS), all your news is organized by category under Bootstrap tabs. And on the subscription index page, when you click the little trash can next to a subscription, then it does the cool jQuery fade-out thing and sends an Ajax request telling the server to destroy that
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.
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—