Archive for the ‘Uncategorized’ Category.

Learning hg as a git user

As my friend, Jason Chu recently noted, I am primarily a git user who has discovered a need to understand and use Mercurial. I am trying to refrain from judgment on Mercurial, as I’m easily bored by bikeshed discussions and holy wars. I have a pragmatic “use what you like and let me use what I like” philosophy, but when you are interacting with other people’s code, you occasionally have to use what they like.

I have read several articles that I do not intend to link to discussing the differences, and cheat sheets of hg equivalents of common git commands. These are utterly useless. Mercurial and git have different design philosophies, as Jason noted, even though the end result of their usage is much the same. If you’re comfortable with git, and interested in learning Mercurial, you may find my own eureka moment helpful.

hg commit is not the same as git commit.

Most comparisons of git and hg do not notice this distinction, but I was really puzzled by how hg could be more powerful than Subversion and supposedly equally powerful to my beloved git until I came to this realization.

In git, when you make a commit, you are creating local history that can be easily changed, modified, or ratified. You can rebase over those changes as many times as you like. You can use git commit –amend to change the commit or add changes to it. The history is not remotely considered “permanent” until you push it to a public repo, and even then, there are times when it is acceptable to rewrite it.

Conversely, in hg, when you commit, you are doing what the word actually says: committing. You are saying “this commit looks the way I want it to, I am finished with it.” You may not be pushing the commit to a remote repo any time soon, you may not be publishing it, but you have written in sandstone that this commit is complete.

I say written in sandstone, rather than stone because there are a variety of hg commands and extensions that allow local history editing, rebasing, and rollbacks. I haven’t learned how fluid these extensions are compared to equivalent history modification in git, but the feeling I am getting is that such changes would be considered much more invasive in hg than in git. History editing is a third party extension; this says to me “not officially supported” (as compared to built-in extensions like Mercurial queues). Mercurial typically desires us to think of a commit as an object that is permanently in the history. Many of the other slightly-deeper-than-cosmetic differences between the two systems seem to stem from this same basic difference.

In git, I have gotten quite used to coding first, and then creating an appropriate history later. There are numerous other potential workflows with git, but that’s the one I like. At first, I thought this was impossible or very difficult with Mercurial. However, when I realized that “commit” falls somewhere between the commands “commit” and “push” in git, things started to fall into place.

Mercurial has a powerful tool called queues that allow you to manipulate history to your heart’s content before you call commit. I’ve been using these effectively to create a workflow that I am comfortable with. It’s not the same as what I’d do in git, not remotely, but the overall outcome is similar.

A related basic understanding that is a little better documented than the difference between hg commit and git commit is the following:

hg branch is not the same as git branch.

Once again, hg branch lies somewhere between git branch and git push origin. When you call hg branch, you are stating an intent that the branch will be public. In git, you can have as many unpublished branches as you want. In Mercurial, this behavior is better achieved by the use of bookmarks, although I’ve found that Mercurial queues are easier to work with.

There are many tutorials for new hg users coming from a svn background, and a few tutorials for those coming from a git background. If you are hoping to learn Mercurial effectively, I suggest avoiding most of those options. It is much better to study Mercurial from the perspective of a programmer who hasn’t seen version control before. Such coders don’t exist (I hope!), but this attitude allows you to learn how the new system should be used, not how to make it behave like a system you are previously used to.

For mercurial basics, I strongly recommend http://hginit.com/, an irreverent and entertaining tutorial on the simpler concepts.

I had a lot of trouble understanding hg queues until I read the hg book chapter on the topic I intend to read the entire red-bean book at some point, as it appears to be much more coherent than the official Mercurial documentation. Now that I’ve been playing with hg queues for a day or so, I have come to understand that they can cover several common git tasks that appear to be missing from hg, including stashing, rebase -i, and similar. The key takeaway is you don’t commit your queues until you are quite certain you want them to become permanent history.

I haven’t yet figured out just when to choose hg queues over hg bookmarks, but a good read for getting used to hg bookmarks can be found here.

I strongly recommend enabling the hgk extension Just add the following to your ~/.hgrc. This will enable an hg view command that is more similar to gitk than it should be, considering the basic differences between branches in the two systems.

[extensions]
hgk =
mq =
bookmarks =

(The second line is for enabling hg queues and third enables bookmarks.)

Overall, I suspect that I will always prefer git to hg. However, unlike subversion, I think Mercurial does supply me with tools I need to work effectively. Different tools from git, but effective nonetheless.

One beef I have with both git and Mercurial is that they violate the “one best way to do things” principle which makes learning, communicating about, and deciding how to use them more complicated than it needs to be.

My first Blackberry

I don’t often post reviews of hardware. However, RIM is getting a bad rap lately, and all the cool kids are using Android or IPhone these days. I have been severely disappointed with the three Android phones I’ve had to date, and I have had too many bad experiences with touch keyboards to take the IPhone seriously. That left me with a choice between a Nokia Windows device or a Blackberry. I purchased the Blackberry Curve 9360. I wasn’t expecting much, but having used it, I don’t think I’ll ever go back.

From all the market hype, I expected the Blackberry to be inferior to Android. My expectations were therefore blown away. This is hands down, the best device I have ever used. Unlike Android, everything just works, and there are no force closes. The battery lasts a good 2.5 days under normal usage, compared to less than a day on my Android devices. RIM has put a LOT of thought into their OS design, and everything just flows. This phone is a joy to use, instead of an irritant.

The Curve doesn’t have a touch screen, but I never miss it. I’m willing to say, in fact, that the trackpad is a superior method of input for serious usage. Granted, a touch screen is great for mobile games, but I don’t waste time with that sort of thing. While pinch to zoom action on maps and images is quite pretty, on my Android phones it tended to be flaky and annoying (I’ve heard this is not the case on iPhones). One click zooming on my blackberry is more effective.

Actually, I did miss the touch screen when using my web browser at first. Trying to use the trackpad as a mouse was irritating until I increased the sensitivity. Now that the cursor moves as far and fast as I expect it to, I’d say that the interaction is about comparable to touching links and buttons. The touch action is more intuitive overall, but I used to find under Android’s browser that 1 time in 3 the phone would activate a different link from what I had thought I touched. The trackpad pointer never does this. The tradeoff leaves me sitting on the fence; either method works, but neither is optimal.

Of course, there are Blackberry devices with touchscreensI originally wanted to get a Torch 9810 to get the best of both worlds. I doubt I will do that when I upgrade, simply because I’ve unexpectedly proven to myself that the touch screen is not the wonderful idea that Steve Jobs told us it was.

The Blackberry OS 7 is extremely responsive, even though the Curve hardware specifications are modest compared to high power Androids, or even higher power Blackberries. I never have to wait for text to show up on the screen or for activities to complete. The tools that Blackberry is known for, namely messaging and email are even more pleasant to use than I had been led to expect.

The Blackberry market app is a bit of a disappointment. It doesn’t seem to find apps that I know exist, and I normally find it easier to search google on the phone and install an OTA link than to download through the market. Another annoyance is that you need to perform a Windows-like reboot whenever you install new apps. However, this is a rare task for me; I have never been one to download a lot of apps. On my Androids, I tended to replace the stock apps with sexier ones from the Android market (The Go dev team’s contacts, messaging, launcher, and other tools are particularly nice). I feel no need to do this under Blackberry; the stock apps are too good to replace. I have heard there is a lack of selection of Blackberry apps, but I personally haven’t missed it. To be honest, the argument that Android has a much bigger selection of apps in its market is severely watered down when you realize that many of these are fart sound boards or sexy lady wallpaper collections.

The Curve’s camera takes very clear still pictures. The flash is small, but indoor shots seem to be high quality. Digital camera technology is pretty much a solved problem these days; I doubt that any one phone is going to outperform another in this regard. I haven’t bothered with the video camera, so I don’t know how it compares.

Call quality is definitely clearer on this phone than any other device I’ve ever used, including landlines. I have no idea what sort of noise cancellation or other technology is involved, or if the towers in this area have been improved since I last used them. I know they’ve been updated to 4G, but I don’t know how that is expected to affect call quality. I like that the phone usage is a single button press; it highlights that the dialer is not just another app on the phone. I’ve had Android get stuck in another app when trying to answer an incoming call. This doesn’t happen with the Blackberry; calls take priority.

All the reviewers that say they are far superior to any other hardware manufacturer’s keyboard are understating the truth. In just a couple weeks of usage, I am already more accurate than I have been on any soft or hard keyboard on the Android devices I’ve had. I’m also quite a bit faster. Typing an e-mail on a soft Android keyboard used to be annoying enough that I’d wait until I was sitting at my computer. The two Android hardware keyboards were much better, but I could easily write entire book chapters on this phone if I wanted to. The keys are easy to press and give a satisfying click on each keystroke. The keys seem deceptively small, but are easy to locate and press. It took a bit of practice to get used to the keyboard. I was dissatisfied at first, but if you use a BlackBerry phone for more than a day, the learning curve is gone. Compared to the three months I spent trying to learn a soft Android keyboard, this is exceptional!

One other thing I like about the phone is that it acquires a wireless connection in almost no time at all. My ancient laptop takes a couple minutes to connect to a WPA protected network, and my Android phones have all been equally slow. But the Blackberry, for some reason, can do it in no time at all.

I don’t want to be sounding too harsh on Android. If you like Android or like Google’s offerings, than by all means, stick with it. However, if you’re like me, and stumped for a good alternative, don’t let the negative media attention RIM has received fool you. This is a high quality piece of hardware running a high quality collection of software.

Pyjaco in a real app: Todos with local storage

I didn’t get the memo, but there appears to be a movement to demonstrate emerging web technologies with a simple todo list application, much as hello world is used to introduce programming languages.

In my last post, I introduced using jQuery with Pyjaco, the PYthon JAvascript COmpiler. Since then, I’ve made several contributions to the project and have been involved in diverse discussions with Pyjaco developers regarding the current and future status of the project. This post goes further by acting as a tutorial for writing a basic todos app using Pyjaco.

Pyjaco is alpha software. It is hard to write valid code, and harder to debug. I’ve managed to both lock up Firefox and hard crash it while using the Pyjaco library.

On the positive side, Pyjaco is under active, rapid development. The head developer, Christian Iversen is extremely responsive to both questions about Pyjaco, and to code contributions. This is a project with a lot of potential, and I see it as the current best bet for Python programmers hoping to avoid javascript one day in the future.

In spite of the hiccups, it is possible to generate a working javascript app using just Pyjaco. Here’s how.

Let’s start:

mkdir pyjados
cd pyjados
virtualenv2 venv --distribute --no-site-packages
source venv/bin/activate
pip install git+https://buchuki@github.com/buchuki/pyjaco.git@run_script

First we create a directory to work in and install a virtualenv. Pyjaco does not currently work with python 3, so in Arch Linux, I use the virtualenv2 command. We then activate the virtualenv and install the pyjaco package. Here I am installing from my personal fork, as it contains some changes for generating the built-in standard library that have not yet been merged upstream. You should normally install directly from chrivers’s git repository using pip install git+git://github.com/chrivers/pyjaco.git.

Now let’s create a basic HTML 5 page with jQuery loaded:

<!DOCTYPE html>
<html>
  <head>
    <title>PyJaco Todo List Example</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
  </head>
  <body>
    <h1>PyJaco Todo List Example</h1>
  </body>
</html>

We can load this in our web browser using a file:// URL. This is the only HTML page in our app, and it can be refreshed to load our changes as we work.

Pyjaco doesn’t simply translate Python into Javascript. Rather, it creates a basic standard library of Python-like objects that are utilized in the compiled javascript code. I wasn’t too keen on this idea when I first heard it, as it introduces a dependency that currently weighs in at 65K before minification and compression. While this is not a terribly heavy library, there are efforts under way to shrink the builtins or to dynamically generate it to contain only those builtins that your code actually touches. At any rate, we need to ensure this library is available to our code. First we generate the library:

pyjs.py --builtins=generate --output=py-builtins.js

pyjs.py is the name of the pyjaco command. It is expected to be renamed to pyjaco in the future. The --builtins=generate option tells pyjaco to generate the standard library, while the --output flag provides the filename for the new library file:

$ ls
index.html  py-builtins.js  venv

We then need to load this library in the head of our html file. Let’s also load the future pyjados.js script at this time:

  <head>
    <title>PyJaco Todo List Example</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
    <script type="text/javascript" src="py-builtins.js"></script>
    <script type="text/javascript" src="pyjados.js"></script>
  </head>

Now, before we start coding the Python file that will be compiled to Javascript, I want to discuss what I consider to be the most confusing aspect of Pyjaco development. There are basically two types of variables in Pyjaco, Javascript variables, and Python variables. Javascript variables refer to “normal” variables that you would call in Javascript. These include alert, window, document and the like, as well as variables in third-party Javascript libraries, such as the ubiquitous jQuery. Further, any attributes on those objects are also Javascript variables, and the return value of any methods will also be Javascript variables.

Python variables, on the other hand, refer to any variables that you define in your Python source code. If you create a dict or a list, for example, it will be compiled to a list or dict object from the standard library we just generated. In the compiled script, of course these Python variables are represented by Javascript objects, but from the point of view of a Pyjaco coder, it is important to keep the two types of files separate. Almost all the bugs I have encountered in my Pyjaco code have been caused by confusing the two types of variables.

The distinction between python and javascript variables introduces a couple of complications to writing Pyjaco compatible python code. First we need to flag all of our Javascript variables using a decorator on methods that access them. Second, we need to explicitly convert our variables between Javascript and Python any time we access one from the other. I’m told that this conversion can — and one day will — be done automatically by the pyjaco multiplexer, but in the meantime, we need to make it explicit. We do this by using two javascript functions supplied with the standard library we just generated, appropriately named js() and py(). You will see examples of these shortly.

When I finally figured out the distinction, my first thought was, “ok, let’s prefer to always work with python variables.” Therefore, in my initialization code, I tried jQ=py(jQuery). Unfortunately, jQuery is a rather large object, and the py function apparently recursively converts all attributes from javascript to python. I ended up with a stack overflow.

Now, let’s create our first python code and watch it compile to Javascript. Name the file pyjados.py:

def setup():
    print "Pyjados Hello World"
 
jQuery(js(setup));

First we write a python function named setup. This function is a python object. jQuery is a javascript object that expects a javascript object as input. Therefore, we wrap setup in a js() call and pass the result into the jQuery function. jQuery will now run setup when document.ready is fired.

Now we compile the code using the following command inside our activated virtualenv:

pyjs.py --watch pyjados.py --output pyjados.js

You’ll notice the command doesn’t exit. That is the --watch option at work. If you now make a change to pyjados.py and save it, it will automatically recompile it. The output file pyjados.js is regenerated each time. This is the file we included in our html file. So now, open that html file in a web browser using a file:// url. Make sure the Javascript console is displayed and reload the page. You should see the words “Pyjados Hello World” printed on the console. Pyjaco automatically compiles print statements into console.log output.

Before we start implementing our Todo list, let’s look at an example of accessing a javascript variable inside a function. Change setup.py to utilize alert, as follows:

 
@JSVar("alert")
def setup():
    alert(js("Pyjados Hello Alert")
 
jQuery(js(setup));

Did you look closely at that code? There is a missing close bracket on the alert line. You’ll see the syntax error in your console where pyjs.py is watching the compiled code. Add the bracket and let it automatically recompile itself:

 
@JSVar("alert")
def setup():
    alert(js("Pyjados Hello Alert"))
 
jQuery(js(setup));

Let’s analyze this snippet. First, notice how we told the compiler that alert is a Javascript variable when used inside setup(). This is a bit odd, since the JSVar decorator is never actually imported into the namespace. This is a bit of magic in the Pyjaco compiler, just pretend it has been imported.

Second, notice that since alert has been flagged as a JSVar, it must accept a Javascript variable. However, the string “Pyjados Hello Alert” is a Python variable. Therefore, we convert it using js() as we pass it into the alert call.

Now let’s prepare to create some working todo-list code. Start by adding a form for submitting todos and a list to render the todos to the html body:

  <body>
    <h1>PyJaco Todo List Example</h1>
    <form id="add_todo_form">
      <input type="text" id="add_box" placeholder="Add Todo", autofocus="autofocus">
      <button id="add_button">Add Todo</button>
    </form>
    <ul id="todo_items"></ul>
  </body>

Nothing too exciting here. Note the ids on the elements, since we’ll be utilizing these from Pyjaco using jQuery selectors.

Now back into the python file. Let’s create a class to manage the various todo elements:

class TodosApp:
    @JSVar("jQuery", "js_add_form")
    def __init__(self):
        js_add_form = jQuery(js("#add_todo_form"))
        js_add_form.submit(js(self.add_todo))
 
    def add_todo(self, event):
        print "form submitted"
        return js(False)
 
def setup():
    todo_app = TodosApp()
 
jQuery(js(setup));

The __init__ function hooks up the form’s submit button to a method on the object. Notice that we need to flag not just jQuery, but also js_add_form as a javascript variable. Pyjaco does not (currently) know that a javascript variable is returned when calling a method on an existing javascript variable. I like to add the js_ prefix to variable names to help remind myself that this is a javascript variable.

In an ideal world, we could convert this variable to a Python variable using py(), but as noted earlier, calling py on a jQuery object results in a stack overflow or browser crash.

Also pay attention to the way we wrap the self.add_todo method name in a js() call when we pass it into the submit handler. The submit method is a javascript function expecting a javascript object.

The def add_todo method has its single parameter flagged as a @JSVar, since the method is being called internally by jQuery when the event occurs. We also wrap the False return value (to prevent event propogation on the submit handler) in a js() call so that jQuery recognizes it as a javascript false rather than a (true) object named False.

Try the code. Ensure the compiler recompiled it, and reload the html file. Enter some characters into the text box and use the Enter key or the Add Todo button to submit the form. The words form submitted should be displayed in the javascript console.

Now let’s actually store and render a newly added todo. The todos are stored in memory in a python dict object. Initialize this object by adding the following two lines of code to the end of __init__:

    self.todos = {}
    self.next_id = 1

And rewrite add_todo as follows as well as a new method named render

    @JSVar("event", "js_add_box")
    def add_todo(self, js_event):
        js_add_box = jQuery(js("#add_box"))
        self.todos[self.next_id] = py(js_add_box.val())
        js_add_box.val('')
        js_add_box.focus()
        self.next_id += 1
        self.render()
        return js(False)
 
    @JSVar("js_todo_items")
    def render(self):
        js_todo_items = jQuery(js("#todo_items"))
        js_todo_items.html("")
        for id, todo in sorted(self.todos.items()):
            js_todo_items.append(js('<li>%s</li>' % (id, todo)))

Note that the todos dict is a Python object, so when we insert the value of the js_add_box into it, we must convert it from a javascript object using py(). Also note how, because we are writing in a python function, manipulating the python value self.next_id requires no conversion, and calling the python function self.render is also clean.

In the render function itself, I think it’s pretty cool that string formatting using % is supported by pyjaco (as an aside, the str.format method introduced in python 2.6 is not yet available) and that the python sorted() function is available. Note also how we can loop over items() on the self.todos dictionary just as if we were using a normal python dictionary.

Now let’s add the ability to complete todos. Let’s start by adding a template string as a class variable, and use that string inside the render function. This illustrates that pyjaco supports class variables:

class TodosApp:
    list_item_template = """<li>
    %(text)s
    </li>"""

and we change the for loop in render to:

        for id, todo in sorted(self.todos.items()):
            js_todo_items.append(js(TodosApp.list_item_template % {
                "id": id,
                "text": todo}))

Reload the page again and notice how checkboxes have been displayed beside each todo. The next step is to make clicking these boxes actually complete the todos. We add a couple lines to our __init__ method to connect a live click event to the checkbox items, which now looks like this:

    @JSVar("jQuery", "js_add_form", "js_checkbox")
    def __init__(self):
        js_add_form = jQuery(js("#add_todo_form"))
        js_add_form.submit(js(self.add_todo))
        js_checkbox = jQuery(js("input[type=checkbox]"))
        js_checkbox.live("click", js(self.complete_todo))
        self.todos = {}
        self.next_id = 1

Don’t forget to add js_checkbox to the JSVar decorator.

The complete_todo method looks like this:

    @JSVar("event", "jQuery", "todo_item")
    def complete_todo(self, event):
        todo_item = jQuery(event.target).parent()
        id = int(py(todo_item.attr("id"))[5:])
        del self.todos[id]
        todo_item.delay(1500).fadeOut("slow")

The first line is using exclusively javascript arguments, and returns the <li> element containing the checkbox that was clicked. The id = line converts the javascript string id attribute of this element (which looks like “todo_5“, as defined in list_item_template) into the python integer id of the todo. The remaining lines simply remove that todo from the internal list and from the DOM, after a 1.5 second delay.

In fact, we now have a fully functional todo list that allows adding todos and checking them off. Now, as a bonus, let’s try hooking this up to the HTML 5 localStorage object so that the list is maintained across page reloads. We start by adding a store() method to our class:

    @JSVar("localStorage", "JSON")
    def store(self):
        localStorage.setItem("todolist", JSON.stringify(js(self.todos)))

The main line of code is easiest to read from the inside out. First we convert the self.todos dict to a normal javascript object using the js() function. Then we call JSON.stringify on this object to create a string suitable for insertion into localStorage.

Now add this call to the end of the two methods that manipulate the todo list, add_todo and complete_todo:

        self.store()

.

Refresh the page, add a couple todos, and inspect the localStorage object in your console. You should see the stringified dict in the todolist value.

Now all we have to do is ensure the self.todos dict is loaded from localStorage when the app is initialized. Add the following to the end of the __init__ method (make sure to add js_stored_todos to the JSVars decorator):

        js_stored_todos = localStorage.getItem("todolist")
 
        if js_stored_todos:
            stored_dict = dict(py(JSON.parse(js_stored_todos)))
            self.todos = dict([(int(i), stored_dict[i]) for i in stored_dict.keys()])
            self.next_id = max(self.todos.keys()) + 1
 
        self.render()

Note that calling py() on the output of JSON.parse creates a python object, not a python dict. The code is therefore wrapped in a call to dict(), which converts the object to a dictionary.

Unfortunately, the resultant dict contains keys that are strings, whereas our original dict used integer keys. So a pure-python list comprehension is used to convert the dictionary to one with integer keys. This line is a bit hard to read, but I wanted to include it to demonstrate that Pyjaco can parse list comprehensions. Finally, we set self.next_id using the python max() call, which Pyjaco also automatically translates into javascript.

Try it out. Load the pyjados HTML file, add some todos, check a few of them off, then close and reload the web browser. Your todos will be stored!

I hope you’ve enjoyed this introduction to Pyjaco. It is a nice tool with a lot of potential. Currently, I find writing Pyjaco code to be approximately equally tedious to writing Javascript code. However, I feel that as I learn the ins and outs of Pyjaco, and as the developers continue to refine and improve the compiler, Pyjaco may one day be a perfectly viable alternative to writing pure Javascript or to the rather too Ruby-esque, but otherwise excellent Coffeescript.

pyjaco and jQuery

After giving up on CoffeeScript, I decided to play around with Pyjaco the Python to Javascript Compiler.

While the code is readable, there is very little in the way of end-user documentation. I hope to address this with this blog post. The Pyjaco examples all embed generated javascript in an html page. I needed a way to generate an external Javascript file as I would include in an HTML file. I also wanted to find out if I could use Pyjaco with jQuery.

The first step was to install a development version of Pyjaco:

git clone https://github.com/chrivers/pyjaco.git

Pyjaco normally requires a generated Javascript file mapping Python builtins to Javascript to be included with the created Javascripts. This must be generated:

cd pyjaco
python2 generate_library.py
cp py-builtins.js ~/pyjaco_test # directory for my new page

The next step was to create an HTML file that included jquery, the py-builtins.js script above, and a yet-to be defined javascript file named clicker.js that will be generated from a yet-to-be-defined python file. I also add a couple of DOM elements (a heading and paragraph) that are to be manipulated via jQuery:

<!DOCTYPE html>
<html>
<head>
<script type=”text/javascript” src=”jquery-1.6.4.min.js”></script>
<script type=”text/javascript” src=”py-builtins.js”></script>
<script type=”text/javascript” src=”clicker.js”></script>
</head>
<body>
<h1>Click me</h1>
<p id=”when_clicked”></p>
</body>
</html>

That’s the easy part. Writing python code that compiles to correct Javascript is the hard part. Pyjaco doesn’t currently provide very useful compile-time errors, and it also does not yet map javascript errors back to the input python.

There are (at least) two ways to compile python code in Pyjaco. The first, which is used in the Pyjaco examples, and appears to be the preferred method at this time is to create a custom main() method that uses various pyjaco.Compiler methods to combine the functions into a string of text. See https://github.com/chrivers/pyjaco/tree/devel/examples for three examples.

However, I was looking to have a complete python file that compiles to a complete javascript file. Pyjaco supports this as well, using the provided pyjs.py script. It took some investigating to understand how to reference javascript variables inside python functions. Decorator syntax is used to expose the variables for jQuery, Math.random, and Math.floor in the following example. The mystifying bit is that because we will be compiling this file to javascript as a string, it is not necessary (or possible) to import the JSVar decorator, as was done in the Pyjaco examples linked above.

# clicker.py
@JSVar("jQuery")
def ready():
    jQuery('h1').click(on_click)
 
@JSVar("jQuery", "Math.random", "Math.floor")
def on_click():
    if jQuery('#when_clicked').html():
        r = Math.floor(Math.random() * 255)
        g = Math.floor(Math.random() * 255)
        b = Math.floor(Math.random() * 255)
        color = "rgb(%d, %d, %d)" %(r,g,b)
        jQuery('#when_clicked').attr('style', 'background-color: ' + color)
    else:
        jQuery('#when_clicked').html("you clicked it!")
 
jQuery(ready)

Notice that I’m using the jQuery function instead of the $ alias, since $ is not a valid variable name in Python. This is a rather odd looking mix of Python and Javascript functions, but it works.

I had to repeat the compile and test step a few times before coming up with the above file. The script can be compiled using the pyjs.py that comes with the pyjaco source distribution (and, thanks to a simple patch I submitted, will come with the binary distribution in the next release.) Here’s how the script is run:

python2 ~/code/pyjaco/pyjs.py -N --output clicker.js clicker.py

The -N option tells pyjs not to generate the builtin library that we created manually in the first step.

This translation step creates a clicker.js file that looks like this:

var ready = function() {
    var __kwargs = __kwargs_get(arguments);
    var __varargs = __varargs_get(arguments);
    var $v1 = Array.prototype.slice.call(arguments).concat(js(__varargs));
    jQuery("h1").click(on_click);
return None;
}
var on_click = function() {
    var __kwargs = __kwargs_get(arguments);
    var __varargs = __varargs_get(arguments);
    var $v2 = Array.prototype.slice.call(arguments).concat(js(__varargs));
    if (bool(jQuery("#when_clicked").html()) === True) {
        var r = Math.floor((Math.random()) * (255));
        var g = Math.floor((Math.random()) * (255));
        var b = Math.floor((Math.random()) * (255));
        var color = str('rgb(%d, %d, %d)').PY$__mod__(tuple([r, g, b]));
        jQuery("#when_clicked").attr("style", ("background-color: ") + (color));
    } else {
        jQuery("#when_clicked").html("you clicked it!");
    }
return None;
}
jQuery(ready);

I find this rather unfortunately difficult to read. There is code for argument parsing that would not have been needed if I had hand-written javascript. Further the use of “mock” python builtins makes the javascript look less javascripty. However, the original python file looks much more readable than an equivalent javascript one would. I am hopeful that improvements to pyjaco will cause it to generate more readable javascript with less extraneous code.

The entire example can be found on my github fork

Christian Iversen is actively working on Pyjaco right now. I am excited about this project and hope that further community involvement will help it evolve into a practical and useful tool. I intend my next patch to be an autocompile tool that monitors files in one directory for change and outputs .js files in another directory, one of CoffeeScript’s killer features. I am also considering a port to Python 3.

I can’t use CoffeeScript

I had some space between wrapping up my last contract on December 20, and starting my new job on January 16. I decided it was finally time to build a simple task management system, something I’ve attempted to do and never finished several times before. I currently use RememberTheMilk, which is a lovely service, but I don’t like paying them for mobile access. Further, even though I trust this small company, I see no reason to share intimate information about the tasks I accomplish every day with them. My long term goal is to pull as much of my personal data out of the cloud as I possibly can. This project is a step towards that goal.

There are numerous open source task manager apps out there that I’m sure would suit my not-too-exotic tastes. However, I also wanted to take this opportunity to learn a bunch of new technologies for an offline-enabled and mobile-enabled web application.

Therefore, I’ve spent most of my vacation time so far researching some technologies I haven’t had a chance to explore in the past year. JQuery Mobile was at the top of the list. I think it’s a lovely framework and I expect to continue using it.

I also wanted to try out CoffeeScript, as I’ve always hated writing Javascript, and I wanted to use some sort of client-side ORM for localstorage. I looked at backbone.js, but was more attracted to Spine.js. I have spent three days studying and playing with these two technologies. I am still undecided about Spine.js, but I have come to the conclusion that CoffeeScript is not for me.

I understand all the hype around the project. JavaScript really does suck. And CoffeeScript does suck less, it has pretty language features and it is much more succinct than JavaScript. I can imagine a lot of people being really excited about CofeeScript, especially Ruby and PERL programmers, and possibly even php programmers.

But not Python programmers. I tried to learn Ruby several times, and each time I was left with a foul taste in my mouth. It’s not a bad language, it just doesn’t fit in well with my personal philosophy. My personal philosophy happens to coincide almost exactly with the Zen Of Python. I chose Python because it matched my philosophy… not the other way around.

Like Ruby and PERL, CoffeeScript violently violates what I consider the most important rule of Python: “There should be one — and preferably only one — obvious way to do it.” I’m not going to argue why this is a good idea, I understand that some programmers prefer the “even if I don’t understand it, I can write code that will probably work” paradigm that Ruby promotes.

The simple truth is, writing CoffeeScript leaves me feeling like I’ve done something dirty, no less dirty than writing JavaScript. There is no incentive for me to add a layer of complexity (the CoffeeScript to JavaScript compile step) to my code when I know my code is going to be “ugly” either way.

CoffeeScript is a wonderful idea. It’s far better than JavaScript. It’s just not good enough. Luckily, the Python community is already working on pythonic answers, including the evilly poorly documented pyjaco and the less-than-well maintained pyvascript and pyjamas projects. I hope one of these or a new upstart will soon gain community momentum so frontend development is no longer painful.

Internet Privacy for Dummies

I know my recent blog entries have tended towards rants on Internet privacy. It blows my mind that more people aren’t worried about it.

I’m not one to repost links on my blog, my readers know I prefer to have new content as much as possible. But this link is a wonderful summary of why normal people should be worried about privacy, and it’s outlined in a way that your mother can understand:

http://donttrack.us/

It doesn’t go as far as I would like (Facebook tracking is an even more serious offence), but it’s a good start for people who need to understand why privacy should be taken seriously.

This link is an advertisement for the duckduckgo search engine. I personally have switched from Scroogle to Starting Page. It is billed as the worlds most private search engine and has apparently been independently verified by a third party. However, Duck Duck Go may be a viable alternative as well.

My friend Matthew did not like the RequestPolicy plugin that I recommended because it required too much interaction to make sites work. He found the Ghostery plugin which works for most web browsers and does an exceptional job of removing most data trackers without any user interaction. I love this plugin! I’ve been using it for a month or so now and have experienced no broken websites. I trust it enough to put it on my family’s web browsers without them experiencing any breakage. Protecting their privacy will indirectly protect mine.

I am still being tracked on my mobile phone browser. If anyone can recommend a similar plugin for Blackberry or Android browsers, I would appreciate it.

I’ve started using bookmarks and search bookmarks a lot more often again. I had gotten in the habit of using the omni-bar for everything. Now instead of Googling the weather in some city, I search Weather Underground directly. Instead of searching google for a word definition, I search m.dictionary.com directly (the mobile site has a cleaner interface than their main one). Instead of searching for a site I had stumbled across in the past, I bookmark the site the first time I see it so I can request it without letting any search engines know I was looking for it.

“You should be on Facebook”

As I’m preparing to leave Switzerland, a lot of my friends have tried to pressure me to join Facebook so they can keep in touch. This isn’t going to happen due to privacy concerns I’ve mentioned many times before. I’d additionally like to counter a couple arguments people keep making in Facebook’s favour.

The most commonly voiced conviction is that “Facebook is so convenient,” or in the case of certain overly excitable individuals, “Facebook is soooooooooo convenient.”

I really shouldn’t have to point this out, but if Facebook were truly convenient, they would provide tools to send me a message or invite me to your events even though I don’t have an account with them. One obvious way to do this would be to integrate the Facebook messaging system with e-mail. Then you’d be able to communicate with me and anybody in the world who has an e-mail address. Facebook may connect over 800 million users (depending how many of those accounts are actually bots trying to harvest your data), but e-mail is able to connect around 2 billion people, and I am one of the 1.2 billion that are not on Facebook.

Of course, Facebook could be even more convenient if they allowed you to keep in touch with your Grandma who doesn’t know how to use a computer. Perhaps they should also support an option for mailing a letter via conventional post.

There is also no reason Facebook shouldn’t allow you to invite me to events by sending e-mails to people who do not use their service. It’s not hard to implement a non-member RSVP service; I’ve done so myself for two different client projects. The fact is, Facebook is deliberately restricting these conveniences for their own benefit.

The second argument I often here is that if I join Facebook I’ll “get to” keep up with all my friend’s lives. It is always worded as though I am missing out on some sort of privilege or basic right.

This is a bit more personal than the convenience argument. The truth is, since the adoption of the Internet, it has become trivial for absolutely anybody to author absolutely anything. Written information is a basic commodity. This puts the power in the reader’s hands, instead of the author’s.

In short, the reader has the privilege of choosing what they will read, and whose written information they will consume. The author is not granting privileges to the reader (despite the “all rights reserved” designation we still see on formally published articles).

Most people are not very good authors, and I’m sorry to say, most of the information disseminated via Facebook (that is not also available elsewhere) is simply not of interest to me.

I’m not saying my friends aren’t interesting, nothing could be further from the truth! But I prefer personalized messages in which we discuss things that are of mutual interest. I acknowledge that most of the stuff in my life is not of interest to any one of my friends. However, for those topics, facts, or events that I know you are interested in, I am happy to spend the time crafting a message meant for your eyes only in which I discuss those things I know you will care about. I won’t discuss Canadian politics if you live in Europe. I won’t discuss complex technical topics unless you’re as fascinated by them as I am. I won’t send you links to my sketches unless you’re interested in art. I would appreciate the same care from you; please don’t send me stupid cat photos, I’m not interested. I don’t care about celebrity or even local gossip. I’m not interested in the latest viral Internet meme.

Google has made an effort to address both these concerns with Google Plus. They have integrated Plus with Gmail, Google Talk, and SMS services so you can still keep in touch with me even though I have deleted my Google Plus profile. The whole Circles architecture is designed to address the second issue, although in my opinion it has failed to do so.

In summary, as I covered in my last post, Facebook does not provide such “convenient” services that they are worth the extremely high value of the data they wish to take from me in payment. If you choose to restrict your personal interactions only to the portion of the population who is active on Facebook, that is your prerogative. In turn, I will choose to keep in touch with those people who are willing to use services that I find more convenient.

Killing the Google habit

We live in an age where information is power. It is so valuable that companies like Google and Facebook are willing to give us amazing services for free in exchange for the information we give them, both about ourselves and others.

The cost of these “free” services is the information we choose to provide. Most of us are so eager to not spend money that we happily give away a wealth of personal details, including:

  1. every e-mail we send or receive
  2. every chat message.
  3. every location we want to find
  4. contact details for everyone we know
  5. our general relationship to every person we know (using services like Google Plus circles or Facebook groups)
  6. every photo we take
  7. every news article we read
  8. most of the websites we visit (if Google analytics, “like this on Facebook”, “share this on Twitter”, or other trackers are enabled on the site
  9. every term we search for
  10. our appointments, tasks and meetings
  11. our documents
  12. our purchases and shopping habits

In short, we now share a huge percentage of the collective information about our entire lives with various online services, and in exchange for what? Convenience, of course. Safe backup and storage. Free access from any computer with an internet connection.

I think we’re getting shortchanged. I don’t think most services are worth the information we sacrifice to use them. This information is extremely valuable, yet we give it away for easy methods of keeping in touch. This article is a summary of the things I am doing to keep my personal information personal. It’s not strictly a question of privacy, although that is also important. It’s more about protecting information that has value from theft by these giant corporations.

Facebook is the company that makes me the most nervous. I don’t trust their shady, ever changing privacy policy. Therefore, I closed my Facebook account well over a year ago, and I use the excellent Firefox plugin RequestPolicy to prevent them from knowing which web pages i visit. As a backup, I have also customized my hosts file to prevent any requests to the Facebook domain and other trackers.

I feel the cost of the Facebook service is too high. I am not willing to “pay” for this service with information about the sites I visit, the people I communicate, and the things I say to those people. Of course, they still have a certain amount of information about me that I cannot protect alone. People probably still tag my name in photos, link to my websites, or try to invite my e-mail address to join the service. These people are giving away the knowledge of our relationship. I can’t help that, as it takes two to keep a secret. Overall, however, I am comfortable with the relative unknown that I am to the company.

Amazon is another company that causes apprehension. They know my reading habits and shopping habits. Even if I don’t buy through them, I research many products on their site. Worse, Amazon provides a large chunk of computing power to numerous other websites that I use. In most cases, I likely don’t even know which sites are using AWS services. In theory, Amazon has access to data stored on those systems. In practice, I suspect the cost of mining that data is prohibitive at this time. Nevertheless, the data exists and Amazon algorithms may one day desire access to it.

Google is the third and largest major data collector. I trust them with a lot more of my personal data than anyone else. In some cases, their services are so useful that I am willing to pay for it with this information. In other cases, I have been unaware of just how much information I am giving them. I’ve been considering each of Google’s services in light of what I am paying for it and have come to the following conclusions:

Google Analytics provides me absolutely zero service in exchange for telling Google almost every site I visit. I have solved this in the same way I solved the Facebook issue: The Request Policy plugin and a modded hosts file for backup.

Google News is a nice service, but it’s not worth the cost of allowing Google to know every article that is of interest to me. Further, I have been allowing Google to decide which articles I should seen. Ostensibly this is in the name of convenience; I don’t have to sift through articles I am not interested in. This convenience has an added cost. I have given Google the opportunity to “warp” my view of the world by picking what windows i see into it. I don’t believe Google would maliciously hide articles from me to prevent me from knowing about that information (even though they do this in China on behalf of the government, but they have the opportunity to do so. Worse, they can easily accidentally hide articles from me that prevent my getting the whole story. Their algorithms are certainly not infallible. If I want news on a controversial subject, they may only show me the side of the story I “probably” agree with. This doesn’t allow me to make an unbiased judgment of my own.

Google Reader is a related tool that is not worth the cost of allowing Google to know what feeds or articles I find interesting or amusing. I have quit using Google News already and will be dropping Google Reader requests this week.

Gmail is an interesting question. I gave up Gmail last summer because I wasn’t comfortable with Google having access to every email I write. However, some e-mail server somewhere must necessarily have access to that information. E-mail has to be stored somewhere. I currently use Zoho mail, but intend eventually to migrate to a personally maintained e-mail server. One interesting thing about Gmail is that even though I do not use the service, Google still has access to every message I send to someone who has a Gmail address. I am willing to pay this cost for two reasons. First, it is not feasible to find other forms of communication for each of my contacts that uses Gmail. Second, the message has to be stored somewhere, and if the user receiving it trusts Gmail over some other service, that is their prerogative.

Google Chat has the same problem. I am in the process of moving my Google Talk contacts to a Jabber account. For the select few people I communicate with who use Jabber, Google does not have a record of our chat. However, most of my contacts are Google Chat users. I have to decide if the convenience of talking to these people through an instant message is worth the cost of allowing Google to see all those messages. For the time being, I don’t expect to change my habits.

I don’t think I understand the purpose of Google Plus. I’m still playing with it, but the service it offers doesn’t seem to justify letting Google see my semi-private communications. I expect to phase it out of my daily routine in a month or two. I don’t mind Google indexing my intentionally public posts, but I can just as easily make public posts on my blog. The information they obtain in the form of circles (i.e: whether I consider them a friend or coworker or acquaintance) is too valuable to give away freely.

Google maps is the most difficult service to walk away from. If I want the convenience of a mapping application without the cost of telling Google or some other online service my exact location, I guess I’d have to buy paper maps or a GPS that is not web enabled. My current favourite Google maps feature is the way it automatically remembers searches I made on the web when I look them up again on my Android phone. For the time being, I am willing to provide sensitive information about my location in exchange for the service Google supplies. However, I suspect I am overpaying.

Google search, of course, is the great big question mark. It is impossible to search the web without giving some system information about what you want to search for. Services like Scroogle can prevent Google from knowing who made the search, but that doesn’t stop Scroogle from having it.

I have noticed that about 40% of my searches return a Wikipedia page as the first result and that I usually click that link when it comes up. There is no need for Google to know that I searched for something on Wikipedia. I have therefore set up Wikipedia as my default search engine and created a shortcut bookmark named “g” to search Scroogle.

In addition to knowing which terms I search for, Google also knows which links I click in the search results. There is a Javascript click handle on each link reporting to Google that I have clicked it. The service Google provides me in exchange for this information is custom search results based on what they think I will click. Aside from suffering from the same problems I described with Google News, this service is simply not worth the value of the information they are collecting from me. From its inception, Google was able to provide uncannily accurate search results without this extra knowledge about me. My solution? All Google searches are now routed through Scroogle.

Google Translate is a service that I am willing to supply with information about my inane translation requests in order to see the translations. I will continue to use this service. My French is so basic, that I don’t think Google can get much of a profile of me from it.

At this point, Google map’s sync with my phone, and my continued evaluation of Google Plus are the only Google services that I need to be logged into my Google account to use. I therefore expect to be staying logged out of my Google account by default by early next year. I also hope to disable my account altogether by the end of 2012.

One non-google service that also has a great deal of information about me is Remember The Milk. They know every task I complete. Worse, I pay them for the privilege of having this information (I have the RTM pro account in order to sync with my phone)! I intend to spend a weekend writing my own self-hosted web-based task management app that will be accessible from both phone and laptop someday soon.

Do you think I’m too paranoid about what Google knows about me? Consider Cory Doctorow’s short story, Scroogled, which was written in 2007. We are a lot closer to the eventuality he describes than we were five years ago. Seems somewhat prophetic, doesn’t it?

Finally happy with folding in vim (or how to get an overview of a python file)

I’ve always found vim folding to be somewhat mysterious. No matter which of the foldmethods I used, it seemed like it was always too tedious or too manual.

Today, while editing a python file over a remote connection that has high enough latency to interfere with rapidly scrolling through the file, I finally set out to solve this problem. My goal was to get an overview of the file. Yes, there are plugins or ctags to do this, but I don’t have ctags installed and have tried different plugins that didn’t really work as I wanted.

Indent folding does essentially what I want; when all folds are closed, I can see the overview of classes and module-level methods in the python module. When they are open, I see the whole file. I always felt that Indent mode should be ideal with whitespace-driven python, but in the past, I found that the default settings left far too many folds to work with.

I already new about the foldminlines setting which only creates a fold if more than a specific number of lines is displayed. But today, I discovered foldnestmax.

This setting is the maximum number of folds in the file. In a python file, if I set it to 1, folding happens only at the classes or module-level functions in the module. If I set it to two, it happens at each method in each class. I don’t get a bunch of internal folds that I don’t want.

Another setting that I discovered today is foldlevelstart. If set to 99, opening a new file will always have all the folds expanded, which is what I want.

So now I have exactly what I want: a few top-level folds are created automatically based on indentation, but I don’t have to fuss with interior indentation in other folds. Now I needed a refresher on how best to interact with these folds.

  1. zM Close All Folds Switch to “overview” mode
  2. zR Open All Folds Switch to normal editing
  3. zo Open Fold Open the class or method under the cursor
  4. zc Close Fold Close the class method I’m currently editing

The last one is the most useful, because it works from anywhere in the method. If I’m done with that method, I just zc and it’s hidden from site. I don’t have to worry about collapsing multiple levels of indentation or creating manual folds. It just works.

There are other fold commands; see :help fold for an overview, but just using these settings and memorizing these four commands seems to be all I need.

I suspect that javascript would also work well using a foldnestmax of 1. HTML would probably not work as well since normally the entire body is the top level of intent. Perhaps a foldnestmax of 2 or 3 would be helpful here. Luckily, I can change these values on per filetype basis using autocmd.

My Linux Rig Interview

It’s pretty rare for me to link to other people’s articles in this blog. I don’t believe in regurgitating information. However, this link is not regurgitated, it’s an interview I gave to http://mylinuxrig.com/ so it’s my own words:

http://www.mylinuxrig.com/post/9557009605/the-linux-setup-dusty-phillips-developer