Cuttlepress

Blogging about Hacker School?

Day 21

More webapp stuff today: I got Twilio working with Flask/Heroku, with ample help from Moshe and not a lot of help from Flask/Heroku. I can now automatically reply to SMS messages sent to my Twilio number! Very exciting, but still not particularly screencap-able. The next task was to figure out some persistent state-keeping, because Heroku’s file system is ephemeral. Moshe’s advice was to try using a MongoDB, so we tried to set one up. Theoretically everything is in place, but authentication is giving us trouble. Hopefully that will get resolved tomorrow.

I also attended Jessica McKellar’s talk on making and breaking Python sandboxes, and Julia’s practice practice talk on iPython Notebook, pandas, and data.

Day 20b

Somewhat in response to yesterday’s fiasco, but more because I’m enjoying making a habit of doing my Friday work in Python, I decided to work on today’s optional-jobs-prep “make a bit.ly clone” assignment with Flask. Progress was slow and very frustrating at first, even with Amy’s help at installing various dependencies, but Alan saved the day by getting me up to speed with the basics: learning about how both browsers and curl handle/send GET and POST requests, how to access form information from Flask, Jinja templating, and a brush-up on HTML forms. The URL-shortening is boring and poorly-implemented (I’m not obfuscating the links or anything, nor am I providing for multiple instances of the same or even similar links); the successes are that it’s a working web app with input, output, and persistent state. I even managed to get it up on Heroku, after a bit of a struggle with two unrelated bugs. One was that I had failed to install gunicorn in my virtualenv and thus didn’t have it in my requirements.text, and the other was that I was misunderstanding the proper use of Flask’s “url-to” function. I wish the Heroku error message had been a bit clearer about how exactly to “check your logs,” which was simple in retrospect but nonobvious at the time; it took me a while to even realize it was a thing I could google for. Here’s the bare-bones thing; hopefully improvements will occur in the future. (Particularly improvements involving appearance! I’m sick of not having pretty pictures to post. Time for some Sass, I think.)

Day 20

I sorted the Metaphone rules into a more aesthetically pleasing order, basing some decisions on the commentary at http://aspell.net/metaphone/metaphone-kuhn.txt. I read up some on approximate string matching, but was overwhelmed by the quantity of last names in the Wikipedia category on string matching algorithms and so decided to come back to it another time. Clearly what I needed to do instead was learn about servers and web apps! I got some basic information from Kat and then she helped me install Node.js on my Dreamhost server… which is not allowed by their ToS and I was promptly booted from the network. This coincided with the server going down for scheduled[?] maintenance, so it was unclear for some time how much of my inability to connect and the site’s inability to load were my fault. Anyway, that’s why this blog has not been updated in a bit.

Day 19

Regex time! Today I implemented the simplified Metaphone rules given on the Wikipedia page It definitely has some ordering issues (why would we check for “gg” after we’ve removed all duplicate letters except “cc”?), but it was a good way to learn about regexes. Code’s on github.

I present some poetry:

t b or nt t b 0t is 0 ksksn w0r ts nblr in 0 mnt t sfr 0 slnks ant arws of otrjs frtn or t tk arms aknst a s of trbls ant b opsnk ent 0m t t t slp n mr ant b a slp t s w ent 0 hrt aksh ant 0 0snt ntrl shkks 0t flksh is hr t ts a knsmksn tftl t b wksht t t t slp t slp prkshns t trm a 0rs 0 rb fr in 0t slp of t0 wt trms m km wn w hf shflt of 0s mrtl kl mst jf us ps 0rs 0 rspkt 0t mks klmt of s lnk lf fr w wlt br 0 wps ant skrns of tm 0 oprsrs rnk 0 prt mns kntml 0 pnks of tspst lf 0 lws tl 0 inslns of ofs ant 0 sprns 0t ptnt mrt of 0 unwr0 tks wn h hmslf mt hs kts mk w0 a br btkn w wlt frtls br t krnt ant swt untr a wr lf bt 0t 0 trt of sm0nk aftr t0 0 untskfrt kntr frm ws brn n trflr rtrns psls 0 wl ant mks us r0r br 0s ils w hf 0n fl t o0rs 0t w nw nt of 0s knssns ts mk kwrts of us al ant 0s 0 ntf h of rslksn is skklt or w0 0 pl kst of 0t ant entrprss of krt p0 ant mmnt w0 0s rkrt 0r krnts trn awr ant ls 0 nm of akksn sft y nw 0 fr ofl nmf in 0 orsns b al m sns rmmbrt

(Note that “0” approximates a theta.)

Also, in the morning, I finished and shipped my entry for Ectocomp.

Day 18

Scattered and frustrating day. I variously worked on planning a high school workshop, the Tic Tac Toe game, Sass, and a Metaphone implementation in JS and was variously thwarted by poor communication, apathy, the hackiness of CSS with respect to equal-height columns, and file I/O, respectively. This is pretty much what I’ve got for today:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var fs = require('fs');
var filename = "speech.txt";


var ampersand = function(lines){
  console.log(lines.split(RegExp("[^A-z]{1,}")).join("&"));

}

var main = function() {
  var lines = fs.readFileSync(filename,'utf8');
  ampersand(lines);
}

main();

Day 17

On Friday, Rebecca and I decided to take on the job prep prompt to “write a recursive function that calculates the minimax value of a board in Tic-Tac-Toe.” From there, we decided to implement player interaction for the more satisfying result of a playable Tic Tac Toe game; we’ll tidy and memoize the code in a future session.

For our Sass work today, Moshe and I learned about how to use media queries for a basic responsive layout. In JavaScript, I did some tidying of my dishwashing game code, including rearranging the canvases to a more sensible ordering and fixing a few bugs. Then Smita and I started work on a back-to-basics platformer in JS/canvas.

Day 16

Other than the daily Sass session (grids! #{} interpolation!), today I was trying to get together a demo-able version of the dishwashing game by hooking together the stacking and washing components. There are several known bugs, but it worked well enough to show at the end-of-week presentations.

Four canvases of fun.

Day 15

Today’s Sass with Moshe was implementing some beautiful swanky buttons. In Javascript, I decided to take a break from unmitigated JS/Canvas to try my hand at writing a Twine macro. After doing a bunch of reading and examining existing code (from the Porpentine’s resource list), I made this slightly silly attempt at a macro that poorly imitates a built-in Twine markup feature: making an external link.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try {
  version.extensions['exlink'] = {
    major:1, minor:0, revision:0
  };
  macros['exlink'] = {
    handler: function(place, macroName, params, parser) {
      l = Wikifier.createExternalLink(place, "http://"+params[0]);
      insertElement(l,"span",null,null,params[1]||params[0]);
      // http://www.gimcrackd.com/etc/api/files/functions-js.html#insertElement
    },
    init: function() { },
  };
} catch(e) {
  throwError(place,"exlink Setup Error: "+e.message);
}

Obviously not useful on its own, but enough to convince me I’ve started to get the hang of the thing.

Day 14

I attended Yaron Minsky’s brief session on OCaml in the morning, but then worked on my dishwashing game. It is now possible to be graded on the cleanliness of the dish, on a scale of gold star to no star:

Gold star!

In the evening, I worked on an Ectocomp entry in Inform 7, with lots of fun breaks to help Lyndsey get up and running on her own Inform 7 game.

Day 13

On Friday, we had some more of the “optional job-getting content” and I wrote some recursive functions in Python alongside Rebecca.

Today, I wrote a further piece of my exciting dishwashing sim game: the part in which you scrub the dishes. Instead of holding the background (clean plate) pixels in a buffer and examining them by hand, I went with a solution involving three stacked canvases. The bottommost canvas holds an image of the clean plate, and is only drawn to once, on load. The uppermost canvas draws the sponge cursor (tied to the mousemove event). The middle canvas holds the dirty dish image, and the magic is that the canvas composition modes include one in which the overlayed image is subtracted from the destination image, so all I have to do is draw a sponge-out image to the dirt layer while in “destination-out” compositing mode:

1
2
middlectx.globalCompositeOperation = "destination-out";
middlectx.drawImage(eraser, mouseX-eraser.width/2, mouseY-eraser.width/2);

So satisfying.

Code’s on Github.

Additionally, I had some theoretically-regularly-scheduled Sass time with Moshe. In the evening I enjoyed the talk by Yaron Minsky at Jane Street on concurrent programming, which was surprisingly accessible if necessarily constrained by the time.