Filtered by JavaScript, Python

Page 41

Reset

Lesson learnt with creating DOM element with jQuery

April 4, 2008
6 comments JavaScript

This took me some seriously wasted time to figure out yesterday. What I was trying to do was to create a DOM element of tag type A and insert it into the DOM tree of my page. As I was coding along, everything was working just fine in Firefox but the damn thing wouldn't show up anywhere in IE 6. I debugged and debugged and tried all kinds of different approaches and I just couldn't work it out. Then Karl Rudd gave the right hint on the jQuery mailing list.

Basically, what I was doing was something like this:


var a = $("<a>").attr('href','#').click(somefunction);
$('#toolbar').append(a);

What was then so strange is now less surprising. When I changed the <a> to a <span> it actually worked but just looked wrong with the rest of the site I was working on. Here's the correct way of doing it:


var a = $("<a></a>").attr('href','#').click(somefunction);
$('#toolbar').append(a);

Notice the difference between <a> and <a></a>. The strange thing is that to reproduce this I created this test.html page but here I noticed that in IE 6 it won't let you add any elements that are enclosing ones that are written as singulars. That's really strange since in the same javascript as the above stuff I did a $("<div>") which was working fine. I'll have to get back to figuring out why that one worked nad the A one didn't.

See you at PyCon 2008

March 11, 2008
0 comments Python

I'm going to Chicago on Wednesday for the PyCon 2008 conference. I'm going to stay at the Crowne Plaza (or whatever it was called) like many of the other people at the conference.

This is what I look like:

See you at PyCon 2008

If you see this mug, go up to it and say Hi. It speaks British, Swedish and some American and loves food, beer and tea which might be helpful to know if you would feel like to talk more to it. Its interests for this conference are: Grok, Zope, Django, Plone, buildout, automated testing, agile development and Javascript. Its main claim-to-fame is an Open Source bug/issue tracker program called IssueTrackerProduct which it is more than delighted to talk about.

I've never been to Chicago before and I'm really excited about Tuesday night as I've bought tickets to a Chicago Bulls NBA game (basketball). All other nights I'm hoping to socialise, get drunk, get full and get down and dirty nerdy all week. See you there!

CommandLineApp by Doug Hellmann

February 22, 2008
0 comments Python

I just read the feature article "Command line programs are classes, too!" by Doug Hellmann in the January 2008 issue of Python Magazine about his program CommandLineApp and I've tried it out on one of my old Python programs where I do the opt parsing manually with getopt. The results are beautiful and quick. It's sprinkled with Doug specific magic but I quickly got over that when I saw out easy it was to work with. There are still a few questions of things I didn't manage to work out but that will unfortunately have to wait.

If anything, the worst thing about this library is that it's not part of the standard library so either you have to tell people to sudo easy_install CommandLineApp in the instructions or include it yourself in your packages if you prefer to ship things with a kitchen sink included.

If you want to check it out in action, either subscribe to the magazine (and support the effort) or just download csvcat

input/textarea switcher with jQuery

January 11, 2008
2 comments JavaScript

Here's a very early version of a solution to a problem where you have an input box want to give the user the option to expand the box to a textarea if they want to enter more stuff such as multiple line content. Your implementation, when you attempt the same thing, might be differently but feel free to copy this as a good start for your own projects. The demo show how it works.

What was important for me in doing this was that I didn't want to get close to the XHTML at all since (in this particular case) it was generated from a widget mechanism and I wanted the expanding option a luxury only for those who bother with the full Javascript. The key solution for me was the ability to replace elements in the DOM tree and copy the attributes when going from input to textarea or the other way around.

Feedback welcomed. Bare in mind that this was a quick first attempt and that I haven't tested this on IE.

jQuery and Highslide JS

January 8, 2008
5 comments JavaScript

If you use the wonderful Javascript library jQuery and the wonderful (standalone) Javascript plugin Highslide JS of recent version you should be aware of something.

As of recent versions of Highlide the way the Expander function works is that it looks at an element's onclick attribute and not it's attached events which means that if a DOM element has the event but not the attribute you get a Javascript error. In older versions of Highslide you were able to do this:


$('a.highslide').click(function() {
   return hs.expand(this, options);
});

But that's no longer working since the attribute isn't set. Here's the new way of doing it:


$('a.highslide').each(function() {
   this.onclick = function() {
     return hs.expand(this, options);
   };
});

String comparison function in Python (alpha)

December 22, 2007
7 comments Python

I was working on a unittest which when it failed would say "this string != that string" and because some of these strings were very long (output of a HTML lib I wrote which spits out snippets of HTML code) it became hard to spot how they were different. So I decided to override the usual self.assertEqual(str1, str2) in Python's unittest class instance with this little baby:


def assertEqualLongString(a, b):
   NOT, POINT = '-', '*'
   if a != b:
       print a
       o = ''
       for i, e in enumerate(a):
           try:
               if e != b[i]:
                   o += POINT
               else:
                   o += NOT
           except IndexError:
               o += '*'

       o += NOT * (len(a)-len(o))
       if len(b) > len(a):
           o += POINT* (len(b)-len(a))

       print o
       print b

       raise AssertionError, '(see string comparison above)'

It's far from perfect and doesn't really work when you've got Unicode characters that the terminal you use can't print properly. It might not look great on strings that are really really long but I'm sure that's something that can be solved too. After all, this is just a quick hack that helped me spot that the difference between one snippet and another was that one produced <br/> and the other produced <br />. Below are some examples of this utility function in action.

Truncated! Read the rest by clicking the link below.

isArithmeticExpression() in Javascript

December 19, 2007
0 comments JavaScript

Following from some work that I blogged about two days ago (Calculator in Python for dummies) I've now extended the functionality thinking into the AJAX scripts that sit on top of this Python server-side functionality. How this was implemented is boring but the following function helped me a lot. Here's the code with a very basic unit test after:


function isArithmeticExpression(s) {
  return /[\d]\s*\+\s*[\d]|[\d]\s*\-\s*[\d]|[\d]\s*\/\s*[\d]|[\d]\s*\*\s*[\d]|[\d]\s*\^\s*[\d]/.test(s) &amp;&amp;
        s.split(/\)/).length == s.split(/\(/).length &amp;&amp;
        !/[A-Za-z_]/.test(s);
}

function assert(fact) {
  if (!fact) alert("Assert failure!");
}
assert(isArithmeticExpression('') == false);
assert(isArithmeticExpression('++123') == false);
assert(isArithmeticExpression('+123') == false);
assert(isArithmeticExpression('2+123') == true);
assert(isArithmeticExpression('2 + 123') == true);
assert(isArithmeticExpression('2 + - 123') == false);
assert(isArithmeticExpression('2 + 123') == true);
assert(isArithmeticExpression('(2 + 123)') == true);
assert(isArithmeticExpression('2^6') == true);
assert(isArithmeticExpression('(2+1))^6') == false);
assert(isArithmeticExpression('a+123') == false);
assert(isArithmeticExpression('1a1+2x3') == false);

Basically, it returns true if the string appears to contain only numbers and one of the expected operators +, -, *, / or ^ in between two numbers.

It's far from perfect. I can think of cases where it will actually fail. But those cases are very rare and are too unlikely to happy and cause a major problem in this application and I'd rather get on with it than to spend any more time on this. After all, this is just a Javascript that tries to help if it can. The server-side code needs to "perfect" and if someone enters a weird expression, the server-side error handling will at least pick it up.

Calculator in Python for dummies

December 17, 2007
17 comments Python

I need a mini calculator in my web app so that people can enter basic mathematical expressions instead of having to work it out themselfs and then enter the result in the input box. I want them to be able to enter "3*2" or "110/3" without having to do the math first. I want this to work like a pocket calculator such that 110/3 returns a 36.6666666667 and not 36 like pure Python arithmetic would. Here's the solution which works but works like Python:


def safe_eval(expr, symbols={}):
   return eval(expr, dict(__builtins__=None), symbols)

def calc(expr):
   return safe_eval(expr, vars(math))

assert calc('3*2')==6
assert calc('12.12 + 3.75 - 10*0.5')==10.87
assert calc('110/3')==36

Truncated! Read the rest by clicking the link below.

WSSE Authentication and Apache

December 13, 2007
1 comment Python

I recently wrote a Grok application that implements a REST API for Atom Publishing so that I can connect a website I have via my new Nokia phone has LifeBlog which uses the Atom API to talk to the server.

Anyway, the authentication on Atom is WSSE (good introduction article) which basically works like this:


PasswordDigest = Base64 \ (SHA1 (Nonce + CreationTimestamp + Password))

This is one of the pieces in a request header called Authorization which can look something like this:


Authorization: WSSE profile="UsernameToken"
X-WSSE: UsernameToken Username="bob", PasswordDigest="quR/EWLAV4xLf9Zqyw4pDmfV9OY=", 
Nonce="d36e316282959a9ed4c89851497a717f", Created="2003-12-15T14:43:07Z"

What I did was I wrote a simple Python script to mimic what the Nokia does but from a script. The script creates a password digest using these python modules: sha, binascii and base64 and then fires off a POST request. Here's thing, if you generate this header with base64.encodestring(ascii_string) you get something like this:


quR/EWLAV4xLf9Zqyw4pDmfV9OY=\n

Notice the extra newline character at the end of the base64 encoded string. This is perfectly valid and is decoded easily with base64.decodestring(base64_string) by the Grok app. Everything was working fine when I tried posting to http://localhost:8080/++rest++atompub/snapatom and my application successfully authenticated the dummy user. I was happy.

Then I set this up properly on atom.someotherdomain.com which was managed by Apache who internally rewrote the URL to a Grok on localhost:8080. The problem now was that the Authentication header value was broken into two lines because of the newline character and then the whole request was rejected by Apache because some header values came without a : semi-colon.

The solution was to not use base64.encodestring() and base64.decodestring() but to instead use base64.urlsafe_b64encode() and base64.urlsafe_b64decode(). Let me show you:


>>> import base64
>>> x = 'Peter'
>>> base64.encodestring(x)
'UGV0ZXI=\n'
>>> base64.urlsafe_b64encode(x)
'UGV0ZXI='
>>> base64.decodestring(base64.urlsafe_b64encode(x))
'Peter'

If you're still reading, then hopefully you won't make the same mistake as I did and wasting time on trying to debug Apache. The lesson learned from this is to use the URL safe base64 header values and not the usual ones.

geopy distance calculation pitfall

December 10, 2007
1 comment Python

Geopy is a great little Python library for working with geocoding and distances using various online services such as Google's geocoder API.

Today I spent nearly half an hour trying to debug what was going on with my web application since I was getting this strange error:


AttributeError: 'VincentyDistance' object has no attribute '_kilometers'

Truncated! Read the rest by clicking the link below.