16 Apr 2012

How to load your Mustache templates on the client side?

Mustache.js is really awesome. It's fast, the syntax is succint (and pretty), and all but the most basic logic is hidden from you to lead you away from the path of Satan. It's been ported to umpteen platforms, so unlike things like Jinja, ERB, HAML, Smarty, etc., you can actually reuse the same templates from different languages -- importantly, javascript and whatever else. Client-side template rendering makes for a way faster experience for the user, what with the general snappiness of javascript these days. 

That said, there is still the problem of how to get the templates to your client-side code. There are a few schools of thought on this.

One school is the one taught by backbone.js's canonical todo example: embed the template in a <script> tag and use jQuery (or whatever) to extract the text for rendering.

I think this is popular mostly because it's in the canonical todo list example from backbone.js. It certainly is convenient, and I go this route when I'm not using Mustache (underscore's templates come with backbone, so you may as well use them).

Problem is, I like Mustache on the server-side too, and if not that than Jinja or Django's templates -- all of which share the {{}} syntax, and so will render parts they ought not if they see your Mustache bits just sitting there in your files.

As a developer, when you come across this, your first thought is probably to serve the template via ajax so that the js can fetch and render it on demand. You will only have this thought for a second, because it reveals itself as a stupid one pretty fast. Why send an uncompiled template from server to client this way? It defeats the point of moving application code to the client side to begin with.

Finally, you might settle on serving a js file with the templates stringified and ready to render. In my opinion, this is the correct answer; once loaded, templates are available immediately to the client-side scripts with little overhead.

Of course, if you have a very large application with a non-trivial line count of templates to serve up, you might do well do break them into chunks. Otherwise, you can do what I came up with to mash all your templates together.

Genius, I know. Actually, what would be really nice is to include some sort of watch function, so that you can reload a la coffeescript. Perhaps using http://packages.python.org/fs/watch.html?

13 Apr 2012

From Python to Clojure: What I miss.

Part of an ongoing serious about my delving into Clojure. I've returned to a Python project for a bit, only to find that a language I characterized as "the ideal general-purpose language" only last month seems... well, constraining. After 30 minutes of Python coding, here's what I've run up against:

The anonymous function syntax is incomplete. I never minded before, but coming back with a few new tricks, I find myself running into it more often. No statements means nothing so much as a conditional within a lambda. Of course, as the wikipedia article points out, I could just as well create a named function. But of course it's not just about what I could do, but about convenience. Other languages do this better; I'm a particular fan of coffeescript's (x) -> x * x, which is also incidentally a language with whitespace-defined blocks.

The functools library is a touch sparse. I went in looking for a compose, and came out empty-handed. If course, one can write one's own, but one comes to expect such things should be common enough to be present in functools to begin with. At least partial was where I expected it.

Did I mention macros? Faced with the limitations of lambda above, I immediately started writing an "if" function analogous to clojure's if form -- only to of course realize that without compile-time macros there was no way to do it without evaluating the arguments, or otherwise doing something not allowed in lambda. It's been just a month since I first tried clojure, and already I take macros for granted.

And finally, the REPL, and integration with Vim thereof, was sorely missed. This is still perhaps the greatest selling point for any lisp.

Of course, I'm not suggesting that richer lambdas and more functional tools be bolted on to python; it has its place, and it's still very very good at what it does. And after all, as Mr. Turing observed all those years ago, you really can write about any program in any (sufficient) language. It just feels good to have risen above Blub by just a little bit. If I can, you can.

30 Mar 2012

Using Java from Clojure in plain !@#%^%ing language, with some simple goddamn examples.

This is something I found a bit lacking in the official docs, or maybe I just didn't look hard enough.

Basically, I'm not that smart, and after 2 weeks, I have more experience in Clojure than I ever did in Java (first-year CS courses don't count). Whether by lack of resources, or general dumbness, I had an unreasonably difficult time coming across the knowledge that I am about to impart. I hope it helps any of my peers in the same position.

Basics

Using Externals (with lein)

Java doesn't have quite everything built in, although it sure does its best. Here is the process I took to get pegdown, a very nice Markdown renderer (it does a bunch of other stuff too), working.

1. Add the scalatools repository to project.clj

I was actually doing this a different (stupid) way before, which you can still read about for posterity below. This way is better.

First, you need to inform lein, via project.clj, of the maven repository containing the tool you want.

:repositories {"scalatools" "http://scala-tools.org/repo-releases/"}

2. Add the dependency, formatted correctly

The formatting was a pain to get right because I couldn't find it explained anywhere. Here is the bit of knowledge that I couldn't find:

<group-id>/<name> "<version>"

So, for pegdown, it was:

[org.pegdown/pegdown "1.1.0"]

If you don't write it just right, maven will not find it. What a pain.

3. Use the dependencies

The dumb way

I left this in for transparency. All below might be useful still, but the way above is better -- it resolves dependencies and all that.

----------------

1. Track down dependencies

Don't skip this, no matter how dearly you believe in your heart that you can. Read the docs for pegdown, and it lists a dependency on parboiled. Go to parboiled, and you'll find that it has a dependency on asm. Asm, blessedly, has no dependencies.

2. Round up jars

I needed 4:

  • pegdown-1.1.0
  • parboiled-core-1.0.2
  • parboiled-java-1.0.2
  • asm-all-3.3.1

3. Install jars, with help from lein and maven2

You need maven2. Install it somehow.

Lein can't install jars for you, or if I can, I don't know how. But, if you give it something that it can't find, it'll spit out the mvn command that you need to install it! Since I don't know anything about maven, this is what we will use.

First, add those as dependencies in your project.clj. The format goes like so:

[pegdown "1.1.0"]
    [parboiled-core "1.0.2"]
    [parboiled-java "1.0.2"]
    [asm-all "3.3.1"]

Once you do that, run

> lein deps

This will result in an error, during which the mvn command you need will be suggested it to you. Copy/paste it, fill out the file= arg with the path to the appropriate jar, and run the command. Do it for all 4, and voila! The jars are now part of your project, and you can use them with impugnity.

Easy! Also, if anyone has a guide to maven, preferably a way to use it without adding 20 command-line arguments, I'd love to hear about it.

27 Mar 2012

Utility scripting with Clojure, as a Newbie

Disclaimer: I have been using clojure for like 2 weeks, I'm no expert. I write this in hopes that there is benefit from this perspective.

In this post, I will outline the development of a small utility script in Clojure, in the hopes that, I don't know, it's helpful to you.

Why write your little utility scripts in Clojure? The REPL, stupid! Or more to the point, the integration between your editor (vim, for me) and the Clojure REPL served via Swank.

Setting Up

Lein is a great tool, but it's also picky. It wants you to have a project directory, complete with project.clj, before you can use "lein swank". So, if you want to use Clojure to write little scripts that don't really deserve their own project, I recommend you just create a single project that you'll subsequently use to provide the environment for all your scripts. Easy.

> lein new scratch

This will set up a project called "scratch" in wherever you happen to be. Then, start swank and we can get scripting.

> lein swank

Writing the script

I am not one to spend a lot of time planning -- I prefer to dive in and get a proper feel for the problem. That may be the reason for my newfound enthusiasm.

When you -- when I -- write scripts using Clojure, I write it in little bits, usually from the inside out. In this case, I created a utility script to

  1. Crawl a directory structure given a root, and find the paths to all files ending in ".m"
  2. Filter out duplicates based on filename alone
  3. Return a sorted list of duplicate pathnames, with duplicated files together

How to start? Easy: each of those represents a function. Write a bit of code, evaluate it using swank, see how the result turns out. Do that for a while, and you have a program.

In contravention of custom, I use Vim, not Emacs, to edit my Clojure code. Using Slimv, ",c" connects to swank, ",e" evaluates the current form. There's not much else to know.

The Final Code

 


The code may look more complex than, say, python, but it wasn't written all at once. Lisp programs, as you may have heard and as I will verify, tend to grow almost organically, with many forms written and tested indepently before being assembled into something working.

Another difference from Python: In python, there's about 1 way to do this, with minor variations. In Lisp (clojure, that is), there are probably 1000.

Also, if you have a way to write the "dupes" function without the non-tail recursion there, tell me it. I'm still new at this.

 

19 Mar 2012

Quickstart: Getting Started with Clojure via Vim, Lein, Slimv (Windows + Linux)

You'll need a command line for this. Here's the quick view:

  1. Install leiningen
  2. Install Slimv
  3. Install swank-clojure
  4. Create a project and get started

Install leiningen

Leiningen is a combination buildout/package management script for clojure. In Windows, you'll need lein.bat; on *nix, just lein will do.

Get that here

Get the one you need from the link, and make sure it's in your PATH. You have a user-space bin/ area where you keep your command-line executables, right? That's outside the scope of this article, but if you don't have one, get one.

I also had to get wget.exe and put it in the path; I got mine from http://users.ugent.be/~bpuype/wget/wget.exe.

Once you have lein, you can run the self-install to finish the job:

   > lein self-install   

Install Slimv

I assume you found this article looking for something like "vim clojure", so I assume you have pathogen. If not, get it. After that, it's as easy as downloading slimv and putting its contents in the bundle/ directory. We'll see if it worked later.

Install Clojure-swank

Leiningen makes this as easy as

   > lein plugin install swank-clojure 1.4.0   

I'm not actually sure this is necessary, but hey, it worked for me.

Usage

Lein really prefers that you do your development in a well-defined project directory. You can make one with:

   > lein new test-app   

This will create a new clojure project "test-app" in a new directory from where you ran the command. Then, cd into that directory and run:

   > lein swank   

Slimv claims to have the ability to run this for you, but it didn't work for me on windows. Besides, this way you're running it from your proper project. Now, you can open the src/test-app/core.clj file in vim (this might be called something else for you). It will have a namespace at the top already; I added the rest in so that you had something to test on:

Basic commands:

1) Turn off paredit using ",(". It will be annoying for you until you get used to it.

2) Open up the swank connection using ",c", outside of insert mode of course.

3) Go within the (defn...) and type ",d". This is a shortcut to evaluating the defn that your cursor is in.

4) Highlight the opening paren of the (fact 5) statement and type ",e". This will evaluate the current form.

That's about it! You should see the results in the swank window in vim as you do all that.

13 Mar 2012

Installing Fabric under Windows 7 64-bit, with virtualenv.

It's a bit of a pain to do, but I managed to get Fabric working on my Windows 7 64-bit machine. You'll need pip in advance, I shouldn't need to tell you how to get it.

I did this in Python 2.7, but these steps will probably work for others.

The basic steps are:

  • Create a virtual environment
  • Get/install Mingw
  • Install PyCrypto
  • Install pywin32
  • Install fabric

Init a virtualenv

If you want to do this in a virtualenv, you'll need to do this in the normal way:

> virtualenv --no-site-packages .env
> .env\Scripts\activate.bat

If you choose to use virtualenv, all hacking will take place in your .env\Lib folder unless otherwise specified. If not, you'll be looking in C:\Python27\Lib

Install MinGW

The mingw website has instructions on this matter.

Remember to add the \bin folder to your path. You'll need it.

Install PyCrypto

PyCrypto is a Fabric dependency, and it needs to be compiled via MinGW. To do this, you'll need to edit the file `Lib\distutils\distutils.cfg`. Add the following lines:

[build]
compiler=mingw32

You'll also need to mess with your C:\Python27\distutils\cygwincompiler.py. This is in C:\Python27 even for you virtualenv types.

Remove all "-mno-cygwin" flags from lines 322-327 (or wherever the call to set_executables is), so that they look like this:

self.set_executables(compiler='gcc -O -Wall',
                              compiler_so='gcc -mdll -O -Wall',
                              compiler_cxx='g++ -O -Wall',
                              linker_exe='gcc',
                              linker_so='%s %s %s'
                                         % (self.linker_dll, shared_option,
                                            entry_point))

Then, you should be able to install it using pip.

Install pywin32

The gotcha here is to NOT install the 64-bit version, or at least it was for me. Go to http://sourceforge.net/projects/pywin32/ and find the latest 32-bit file for your python from the latest build. My installer was called "pywin32-217.win32-py2.7.exe"

If you're using a virtualenv, you have two options:

  1. Run the installer as usual and copy the files from C:\Python27\Lib\site-packages
  2. Run the installer from an activated virtualenv using easy_install:
> easy_install C:\Path\To\installer.exe

Install Fabric

Finally, you can install fabric just how you expected to in the first place: "pip install fabric"

Now, on to actually try out this Fabric business.

3 Mar 2012

Installing CyanogenMod on an HTC Legend

These are the steps I took this morning to unlock my HTC Legend and install CyanogenMod. My Legend is on Virgin Mobile Canada/Bell Mobility.

You will need

Run the installers for the first two. 

Unlocking the bootloader

Visit  HTC's Developer Site, register, and follow the instructions to unlock your phone's bootloader.

Flash ClockworkMod Recovery

  1. Power on your phone holding Volume Down + Power.
  2. Select "Fastboot" and press the power button.
  3. Connect the phone to the computer. The red text on the phone's boot screens should change from "Fastboot" to "Fastboot USB"
  4. Put the ClockworkMod .img file in the C:\Android folder you created following HTC's directions
  5. Open a Windows command window
  6. cd to the C:\Android (or whatever) folder
  7. Run the following command:
fastboot flash recovery recovery-clockwork-5.0.2.0-legend.img

Install CyanogenMod

The last bit is directly from the CM wiki:

 

  1. Download the latest version of CyanogenMod.
    Optional: Download the Google Apps for the device.
  2. Place the CyanogenMod update.zip file on the root of the SD card.
    Optional: Place the Google Apps .zip on the root of the SD card also.
  3. Boot into the ClockworkMod Recovery.
  4. Once the device boots into the ClockworkMod Recovery, use the side volume buttons to move around, and either the power button or the trackball to select.
    Optional: Select backup and restore to create a backup of current installation on the HTC Legend.
  5. Select the option to Wipe data/factory reset.
  6. Then select the option to Wipe cache partition.
  7. Select Install zip from sdcard.
  8. Select Choose zip from sdcard.
  9. Select the CyanogenMod update.zip.
    Optional: Install the Google Apps by performing steps 7 - 9 again and choosing the Google Apps update.zip.
  10. Once the installation has finished, select +++++Go Back+++++ to get back to the main menu, and select the Reboot system now option. The HTC Legend should now boot into CyanogenMod

 

 

With any luck, this process will work as perfectly for you as it did for me.

 

23 Nov 2011

Python+Heroku: Minecraft Enchant Calculator

Github: https://github.com/adambard/minecraft-enchant

Yesterday, someone on the minecraft subreddit posted their .NET/Windows-based enchantment calculator. I don't run Windows at home, so I couldn't check it out, but I thought it sounded like a lot of overhead for such a simple tool, and something that could function well as a small web application.

It was also a good excuse to try out Flask on Heroku. I've been meaning to start with the former on something non-database-backed, and as for the latter, they're free and good and have newly-minted python support, so what's not to like?

What I learned

  • Flask is a very nice replacement for making low-overhead experiments that I might otherwise be tempted to do in PHP for simplicity of deployment.
  • Heroku is awesome.
  • Don't skip over the easy-sounding bits of the Heroku documentation.

I got my Heroku instructions from their devcenter, and followed them closely. They even provided almost enough Flask example to get going. If you want to do something similar, I recommend going there.

I could put code docs in here, but I think the docstrings and comments do a good job. Check out the code!

30 Aug 2011

An important lesson about PHP APC RFC 1867

If you don't know -- although I don't know how you found this if you do -- APC stands for Alternate PHP Cache, and RFC 1867 is a sort of stopgap way of fetching the progress of a file upload.

Here's something I learned after a few hours of frustration, trying to put an upload progress bar into the Contact Enhanced module for Joomla for a client:

The APC_FILE_UPLOAD field MUST come sooner in your form than the file field.

Try it yourself!

22 Aug 2011

Diamond Dash Bot: 1,000,000 points!

Update: My current high score is about 1.1 million, much more than the 480,000 reported earlier.

My wife is a hardcore casual gamer. Her Bejeweled Blitz scores routinely quadruple my best attempts. For a few short minutes, I had the leading score on Google Games' Diamond Dash, which lasted until my dear wife got a score that obliterated mine by a factor of 5. So, I made the logical decision: to write an automated Diamond Dash playing bot to beat my wife. At Diamond Dash.

DD is pretty similar to Bejeweled Blitz, except that instead of swapping pieces, you just click on a group of 3 or more contiguous pieces to eliminate them all. So, the logic is a little easier. Here's what I came up with.

Get the code

Its best score so far is ~480,000: about four times as well as I've ever done myself (and just a hair better than my wife's top score so far). The basic steps are:

  1. Parse a screenshot to get the current board layout
  2. Select a number of non-interfering moves to make
  3. Translate those moves into pixel coordinates and click those spots.

Of course, only step 2 of those can possibly be really OS-independent. I wrote the code on Linux, but with screenshot-taking and mouse-clicking adapted, you could run it on anything.

Taking a Screenshot

This uses the GTK library to take a screenshot. I think I took this from someone on stack overflow, so thank you to whoever that was.

Parsing the Screenshot

I took a screenshot of the play area, and cropped off a little rectangle corresponding to the top left of the play area. This function searches, very inefficiently, for that exact set of pixels, to orient itself within the screenshot. It only has to find it once, then it saves that location for speed. So, no moving the window! It returns a cropped pixel array of just the play area.

This bit of code takes that play area and reduces it to a single numeric matrix, where 0 is a diamond, and 1-5 are the various colors. This is what the rest of the program operates on. It does this by sampling every 40 pixels, with a 10x10px offset to get something within the color tile. This was chosen instead of the center because the colors are more consistent in the border between the tile bezel and the symbol.

Selecting where to click

This uses a recursive flood fill algorithm and modifies it to count instead. 

A big difference between Diamond Dash and Bejeweled Blitz is that the latter penalizes you heavily for misses. Most issues seem to stem from the lag between when the screenshot is taken and when the action is processed; sometimes the board changes in between. Some possible improvements:

  • Alternating sides between picks, to ensure that information acquired in a screenshot is still valid
  • Building up multiple non-interfering picks from one screen and running them all (with a longer delay)
  • Running a faster computer
  • Improving the play-area-finding algorithm for speed
  • Porting the whole thing to C for performance.