Archive

Archive for September, 2007

Operator overloading madness in python (equation builder)

September 27th, 2007

I work extra helping out as a lab assistant in the newbie programming course at the university. One of the students had a question that really didn’t matter much for the assignment, but it inspired me to write this small class, to play around a bit with abusing operator overloading to generate equations.

Basically the class is used to set up a variable, and that variable can then be used freely to create functions with one variable like this

from equationbuilder import FuncVar
>>> x=FuncVar()
>>> f = 3*x**2 - 5*x + 8
>>> f(2)
10
>>> f(3)
20

The class for this is somewhat fun in my opinion as it constructs the final callable by using nested lazy lambda functions.

from operator import add, sub, mul, div

class FuncVar(object):
    def __new__(cls, *vals):
        cls.__rmul__ = cls.__mul__
        cls.__rdiv__ = cls.__div__
        cls.__radd__ = cls.__add__
        cls.__rsub__ = cls.__sub__
        return super(FuncVar, cls).__new__(cls)

    def __init__(self, callfunc=lambda x:x):
        self.callfunc = callfunc

    def __call__(self, arg):
        return self.callfunc(arg)

    def __add__(self, other):
        return self._rfunction(other, add)
    def __sub__(self, other):
        return self._rfunction(other, sub)
    def __div__(self, other):
        return self._rfunction(other, div)
    def __mul__(self, other):
        return self._rfunction(other, mul)
    def __pow__(self, other):
        return self._rfunction(other, pow)
    def __neg__(self):
        return -1*self

    def _rfunction(self, other, op):
        if isinstance(other, FuncVar):
            return FuncVar(lambda x: op(self(x), other(x)))
        return FuncVar(lambda x: op(self(x), other))

Download script

No real point to this blog post other than to show up a few programming tricks that some people might now know about. The __new__ constructor in python for an example works wonders to set __rmul__ and so on to the same method as __mul__.
__rmul__ and the other __rXXX_ methods is called when the class is being multiplied (or whatever) by an object “from the left” such as

3 * my_instance

and the left object throws an NotImplemented exception.

The object also defaults to having a __call__ method of

lambda x:x

which means that it will simply return the value passed. As other objects apply their operations, this method will be nested inside other call-methods and when the object is finally called it will all fit together like a nice puzzle :)

buffi Programming & scripting, Python

querypy - Write HTML without writing HTML (by using python)

September 20th, 2007

I’ve never liked writing HTML, so I thought that I could create a tool that does it for me… so that’s what I did.
Link here

querypy let’s you write HTML by using python with a syntax heavily inspired by jquery’s “chaining”. It uses overloaded operators to get a simple syntax that is small but still powerful. Both HTML4 and XHTML is supported, and can be chosen by using an utility function. querypy structures your code into an object oriented tree structure which makes it easy to reuse and change parts of you HTML.

It should be noted that querypy is not meant to be used as CGI to create dynamic content, but rather as a design tool for creating templates. Afterwards you should use a nice framework like perhaps django to implement the actual content.

Here is an example of usage:

from querypy import *

html, head, body = HTML(), HEAD(), BODY()
html + head
html + body

head + ( TITLE() + "A Hello World page" )

body + ( H1() + "Hello world" )

print doctype_html4_strict()
print html

Which outputs

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML>
  <HEAD>
    <TITLE>
      A Hello World page
    </TITLE>
  </HEAD>
  <BODY>
    <H1>
      Hello world
    </H1>
  </BODY>
</HTML>

If you prefer XHTML, simply add use_xhtml(True) before printing the root node.
Here is the same example using XHTML and more chaining.

from querypy import *

use_xhtml(True)
print doctype_xhtml_strict()
print HTML() + ( HEAD() + ( TITLE() + "A Hello World page" ) ) + \
  ( BODY() + ( H1() + "Hello world" ) )

and it’s output

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
 <head>
  <title>
   A Hello World page
  </title>
 </head>
 <body>
  <h1>
   Hello world
  </h1>
 </body>
</html>

The project can be found at http://querypy.com. Feel free to drop me feedback here or by email.

buffi Programming & scripting, Python

python statements are (or rather can be) messy

September 15th, 2007

I recently realized something about python that I wasn’t aware about. Python statements doesn’t force you to use whitespace before or after them.

When it comes to the = statement, this is rather obvious I guess… I sometimes write stuff like

foo="bar"

In other cases I had no idea it worked like this… for an example this is perfectly valid

print"hello"

In a language that uses indentation to block statements for nice readability, it feels kind of weird to allow this since it can make your code really really messy. How about these examples that are all perfectly valid:

"foo"if"bar"else"foobar"
for(x,y)in[(1,2),(3,4)]:print(x,y)
[(y)for(x,y)in[("foo",2),("bar",4)]if"foo"in(x)]

Simply forcing whitespace before and after statements in python would in my opinion be wise… even though you really REALLY shouldn’t write code like this anyways.

buffi Programming & scripting, Python

Small jQuery-plugin for enabling/disabling animations

September 9th, 2007

I’ve been playing around a bit with jQuery for about a month as I’m developing an AJAX-driven admin interface for pici which is coming along nicely.

For this I’m also using some stuff from Effects in jQuery and some might concider animations and so on a bit bloat (although they are so pretty!) so I wanted some way of toggling them. That is, the user should be able to disable them and in that case simply have the data removed/added instead of nicely scrolled up/down.

I wrote a very small plugin for this called jquery.customeffects.js which is probably not a very appropriate name, but whatever.

A functional but not very pretty demo can be found here.

The plugin is only about 20 lines of code, but does it’s job and I thought I might as well put it up here, and not ONLY post about python all the time.
Download here

Using it is explained in the demo. Basically use

$.setFancyAnimations(true)

to enable fancy animations and

$.setFancyAnimations(false)

to disable them.

Then use

hideCustom(optional_params)
showCustom(optional_params)
toggleCustom(optional_params)

to handle the displaying/hiding of data just like the normal show and hide functions in jQuery.

buffi Programming & scripting

geektorrent goes live! First django powered bittorrent tracker/indexer?

September 3rd, 2007

geektorrent is a tracker made for geeks. It is supposed to be a place to gather legal content such as programming screencasts/conferences, gaming videos, physics papers and basically anything vaguley “geeky”. It is however NOT a tracker for the latest movie and software releases… there are plenty of those. Instead I hope to target a more specific group of people, and bring lots of interesting content together at a single site.

The basic rule is “don’t upload it if you think that the creator wouldn’t want it there”. Old tv-documentaries might be copyrighted, but if there are no profit to be made any more, I see no reason for not allowing it. If any copyright owner spot anything on the site that they feel have been uploaded against their will, I will of course remove the content. I want to be a nice guy and the best way for preservation of good content is global distribution.

To be honest I’m not 100% sure that this is a niche that needs filling, and that people will start to contribute to the site by uploading nice content, but there are only one way to find out :)

Visit me!
geektorrent

And now for some of the technology behind the scenes…

I’ve been planning on creating a torrent tracker for quite some time and have explored my options of technologies to use. The only one thing I was 100% sure of was that I was not going to use TBSource. I downloaded their source code to browse through it for ideas and it was just horrible. Since this is a extremely common php-application I was actually a bit surprised on how horribly designed it is. I could probably write an entire entry about this, but I’ll leave that for later… let’s just say that a torrent tracker/indexer is not a very hard thing to write, and I’m surprised that there aren’t any better open source options.

I did however have a look at using XBT Tracker as a backend, which did look quite nice, but turned out to be a bitch to interface with django, due to the lack of binary storage fields and it’s use of binary hashes. It was also a bit non responsive, and lacked decent documentation, but all in all it seems to be a decent option… just not with django. I actually made a complete working implementation using XBTT but it was so messy that I ended up scrapping that idea completely.

I basically ended up doing the entire thing in django, including the backend tracker. This will give some overhead (apache loves overhead!) for the announce, but will be easy to scale, and my implementation would actually not be very hard at all to change to include a separate server for the backend if needed later. I do tend to avoid premature optimization though, and I am 100% sure that this will scale just fine for now.

As far as I know there are no major (or minor?) bittorrent trackers/indexers powered by django so far, so this might be the first one (please correct me if I’m wrong) :)
Google only turns up an incomplete project anyways.

I do intend to open source my code base as a general django bittorrent tracker once it is up to my rather high standards, and proper documentation has been written, so hopefully people will have a viable option to TBSource rather soon ;)

buffi Programming & scripting, Python