Crosstips.orgCrosstips.org

My fun Crossword solver project. Crosstips.org & Krysstips.se

Kung FuKung Fu

Fujian White Crane Kung Fu

Fry-IT

Fry-IT is the company I work for

PhotosPhotos

Photoalbum, both old and new.

ZopeZope

What I have and am doing with Zope

ReceptsamlingenReceptsamlingen

In Swedish only. About my "Collection of Recipes" website.

Contact meContact me

My contact details and how to contact me.

  Mobile version of this page Mobile version of this page

RSS

Hot topics

by : im absolutely in lovee wid this song but i know only like 2 lines of it!!pl...

Find song by lyrics

by Paul: It's Right. I was not aware. But most websites promote paypal. Today, I reg...

PayPalSucks.com, can't be good for PayPal

by anonymous: some one help me please the lyrics of the song say something like this... "...

Find song by lyrics

by Peter: This is from Stars On Volume 45 Volume 2 by Starsound. It peaked at #2 in 1...

Find song by lyrics

by : I'm looking for a song, its a classic rock song and i havent found the name...

Find song by lyrics

by : thanks man , if you find it plz let me know!!!...

Find song by lyrics

by : i heard this song on the z103.5 (toronto) live at 5 streetmix.. it sounds l...

Find song by lyrics

by : does any one know a song that goes take a look at what i've done,amazing!...

Find song by lyrics

by anonymous: these are the lyrics to the theme song for zeke and luther on disney xd th...

Find song by lyrics

by : Sorry, I have heard it before too, I love it but I've never been able to f...

Find song by lyrics

Old entries


February, 2009
Krysstips.se
Tough Guy Challenge 2009 - Boston.com
The Albion, Shoreditch

January, 2009
How I Made a 1,474-Megapixel Photo
Acupuncture works for headaches
Rock stars and their parents
Nasty surprise of Django and gettext
Formatting numeric amounts in Javascript
Earth, observed - The Big Picture - Boston.com
Hellsongs
Does Semen Have Antidepressant Properties?
Secrets of success from Google co-founder Larry Page
The Big Storm Picture: November 2008
The Jesus story - A serious case of plagiarism
Ultimate Banksy Art & Graffiti Gallery | WebUrbanist

2008
2007
2006
2005
2004
2003

 

1st of July

My first iPhone web app - Crosstips iPhone interface

My first iPhone web app - Crosstips iPhone interface I've just finished my first fully iPhone enable web app (not to be confused with iPhone app which are installed onto the phone via App Store). It's here:

crosstips.org/iphone

It's basically a wrapped version of Crosstips that uses these sample resources to imitate a native app but in the Safari web browser.

It works really well and wasn't too hard to do. I think the key is to remember that the iPhone Safari is after all a web browser but it also has excellent support for AJAX (and jQuery). There are probably some bugs that I have spotted yet and there is work on the optimization but for now I'm happy.

So, if you like to solve crosswords in bed and you have an iPhone then bookmark crosstips.org/iphone

4th of June

Custom Fields in IssueTrackerProduct documentation written

Custom Fields in IssueTrackerProduct documentation written The Custom Fields feature started as a consultancy job in which we agreed the work can be open sourced as part of IssueTrackerProduct so I never got around to write an sensible high level documentation for it. Now I have! From the news piece about it:

"Custom Fields was a feature that was released almost a year ago but didn't have much documentation. Especially easy documentation that describes what it is and how it can be used. That has changed now.

In Custom Fields it is now described what they are and how they can become useful to you. It's such a powerful tool that very few "competing" issue/bug tracking systems can offer."

The written documentation is here: Custom Fields

Feedback appreciated.

1st of June

My dislike for booleans and that impact on the Django Admin

I've got this model in Django:

 class MyModel(models.Model):
    completed_date = models.DateTimeField(null=True)

My dislike for booleans and that impact on the Django Admin By using a DateTimeField instead of a BooleanField I'm able to record if an instance is completed or not and when it was completed. A very common pattern in relational applications. Booleans are brief but often insufficient. (Check out Ned Batchelder's Booleans suck)

To make it a bit more convenient (and readable) to work with I added this method:

 class MyModel(models.Model):
    completed_date = models.DateTimeField(null=True)

    @property
    def completed(self):
        return self.completed_date is not None

That's great! Now I can do this (use your imagination now):

 >>> from myapp.models import MyModel
 >>> instance = MyModel.objects.all()[0]
 >>> instance.completed
 False
 >>> instance.completed_date = datetime.datetime.now()
 >>> instance.save()
 >>> instance.completed
 True

I guess I could add a setter too.

But Django's QuerySet machinery doesn't really tie in with the ORM Python classes until the last step so you can't use these property methods in your filtering/excluding. What I want to do is to be able to do this:

 >>> from myapp.models import MyModel
 >>> completed_instances = MyModel.objects.filter(completed=True)
 >>> incomplete_instances = MyModel.objects.filter(completed=False)

To be able to do that I had to add special manager which is sensitive to the parameters it gets and changes them on the fly. So, the manager plus model now looks like this:

 class SpecialManager(models.Manager):
    """turn certain booleanesque parameters into date parameters"""

    def filter(self, *args, **kwargs):
        self.__transform_kwargs(kwargs)
        return super(SpecialManager, self).filter(*args, **kwargs)

    def exclude(self, *args, **kwargs):
        self.__transform_kwargs(kwargs)
        return super(SpecialManager, self).exclude(*args, **kwargs)

    def __transform_kwargs(self, kwargs):
        bool_name, date_name = 'completed', 'completed_date'
        for key, value in kwargs.items():
            if bool_name == key or key.startswith('%s__' % bool_name):
                if kwargs.pop(key):
                    kwargs['%s__lte' % date_name] = datetime.now()
                else:
                    kwargs[date_name] = None

 class MyModel(models.Model):
    completed_date = models.DateTimeField(null=True)

    @property
    def completed(self):
        return self.completed_date is not None

Now, that's fine but there's one problem. For the application in hand, we're relying on the admin interface a lot. Because of the handy @property decorator I set on the method completed() I now can't include completed into the admin's list_display so I have to do this special trick:

 class MyModelAdmin(admin.ModelAdmin):
    list_display = ('is_completed',)

    def is_completed(self, object_):
        return object_.completed
    is_completed.short_description = u'Completed?'
    is_completed.boolean = True

Now, I get the same nice effect in the admin view where this appears as a boolean. The information is still there about when it was completed if I need to extract that for other bits and pieces such as an advanced view or auditing. Pleased!

Now one last challenge with the Django admin interface was how to filter on these non-database-fields? It's been deliberately done so that you can't filter on methods but it's slowly changing and with some hope it'll be in Django 1.2. But I'm not interested in making my application depend on a patch to django.contrib but I really want to filter in the admin. We've already added some custom links and widgets to the admin interface.

After a lot of poking around and hacking together with my colleague Bruno Renié we came up with the following solution:

 class MyModelAdmin(admin.ModelAdmin):
    list_display = ('is_completed',)

    def is_completed(self, object_):
        return object_.completed
    is_arrived.short_description = u'Completed?'
    is_arrived.boolean = True

    def changelist_view(self, request, extra_context=None, **kwargs):
        from django.contrib.admin.views.main import ChangeList
        cl = ChangeList(request, self.model, list(self.list_display),
                        self.list_display_links, self.list_filter,
                        self.date_hierarchy, self.search_fields, 
                        self.list_select_related,
                        self.list_per_page,
                        self.list_editable, self)
        cl.formset = None

        if extra_context is None:
            extra_context = {}

        if kwargs.get('only_completed'):
            cl.result_list = cl.result_list.exclude(completed_date=None)
            extra_context['extra_filter'] = "Only completed ones"

        extra_context['cl'] = cl
        return super(SendinRequestAdmin, self).\
          changelist_view(request, extra_context=extra_context)

    def get_urls(self):
        from django.conf.urls.defaults import patterns, url
        urls = super(SendinRequestAdmin, self).get_urls()
        my_urls = patterns('',
                url(r'^only-completed/$', 
                    self.admin_site.admin_view(self.changelist_view),
                     {'only_completed':True}, name="changelist_view"),
        )
        return my_urls + urls

Granted, we're not getting the nice filter widget on the right hand side in the admin interface this time but it's good enough for me to be able to make a special link to /admin/myapp/mymodel/only-completed/ and it works just like a normal filter.

Ticket 5833 is quite busy and has been going on for a while. It feels a daunting task to dig in and contribute when so many people are already ahead of me. By writing this blog entry hopefully it will help other people who're hacking on their Django admin interfaces who, like me, hate booleans.

27th of May

Introducing django-spellcorrector

I've now made a vastly improved spellcorrector specifically tied into Django and it's models. It's the old class as before but hooked up to models so Django can take care of persisting the trained words. Again, I have to give tribute to Peter Norvig for his inspirational blog How to Write a Spelling Corrector which a large majority of my code is based in. At least in the tricky parts.

What's nice about this little app is that it's very easy to plug in and use. You just download it, put it on your PATH and include it in your INSTALLED_APPS. Then from another app you do something like this:

 from spellcorrector.views import Spellcorrector
 sc = Spellcorrector()
 sc.load() # nothing will happen the first time

 sc.train(u"peter")
 print sc.correct(u"petter") # will print peter
 sc.save()

 sc2 = Spellcorrector()
 sc2.load()
 print sc2.correct(u"petter") # will print peter


>Read the whole text (79 more words)

22nd of May

Crossing the world - new feature on Crosstips

Crossing the world - new feature on Crosstips I've added a very fun new feature on Crosstips called Crossing the world which shows real-time searches happening all over the world. Admittedly the traffic on Crosstips isn't particularly high, (At the time of writing, 1 search every 2 minutes) so you might have to sit there for a while until something happens. It's strangely addictive to watch it.

To do this I had to use all sorts of buzz words. AJAX, function cache decorators, GeoIP and Google Maps. I'm currently using the free version of GeoIP City Lite which seems to work on a large majority of all captured IP addresses. And since the map is sufficiently zoomed out you can't really tell how inaccurate it is.

One little detail I'm quite proud of is how the AJAX code understands how to change interval between lookups. Each time the server responds with something, the interval is reduced down but if there aren't any new searches the interval slowly increases again. This is done to minimize the number of useless server requests but at the same time try to make it react often if there are plenty of things to show. The next feature to add is Comet (like AJAX but push instead of pull).

Now if we could only get some more action on the site!! Tell all your grand-people to use this site when they get stuck on solving crossword puzzles!

UPDATE

I've just learnt that GeoIP is already shipped in GeoDjango so I've basically reinvented half a wheel :(

12th of May

Sequences in PostgreSQL and rolling back transactions

This behavior bit me today and caused me some pain so hopefully by sharing it it can help someone else not ending up in the same pitfall.

Basically, I use Zope to manage a PostgreSQL database and since Zope is 100% transactional it rolls back queries when exception occur. That's great but what I didn't know is that when it rolls back it doesn't roll back the sequences. Makes sense in retrospect I guess. Here's a proof of that:

 test_db=create table "foo" (id serial primary key, name varchar(10));
 CREATE TABLE
 test_db=insert into foo(name) values('Peter');
 INSERT 0 1
 test_db=select * from foo;
  id | name  
 ----+-------
   1 | Peter
 (1 row)

 test_db=#  select nextval('foo_id_seq');
  nextval 
 ---------
        2
 (1 row)

 test_db=begin;
 BEGIN
 test_db=insert into foo(id, name) values(2, 'Sonic');
 INSERT 0 1
 test_db=rollback;
 ROLLBACK
 test_db=#  select nextval('foo_id_seq');
  nextval 
 ---------
        3
 (1 row)

In my application I often use the sequences to predict what the auto generate new ID is going to be for things that the application can use such as redirecting or updating some other tables. As I wasn't expecting this it caused a bug in my web app.

11th of May

Most unusual letters in English language

I needed to find out what are the least used letters in the English language. I pulled down a list of about 100,000+ English words, split them all and made a list of about 1,000,000 letters. Sorted them by usage and came up with this as the result:

 esiarntoldcugpmhbyfkwvzxjq

It would be interesting to make a heatmap of this over an image of a QWERTY keyboard.


>Read the whole text (103 more words)

8th of May

To JSON, Pickle or Marshal in Python

To JSON, Pickle or Marshal in Python I was reading David Cramer's tip to use JSONField in Django to be able to store arbitrary fields in a SQL database. Nice. But is it fast enough? Well, I can't answer that but I did look into the difference in read/write performance between simplejson, cPickle and marshal.

Only reading:

 JSON 0.00593531370163
 PICKLE 0.0109532237053
 MARSHAL 0.00413788318634

Reading and writing:

 JSON 0.0434390544891
 PICKLE 0.0289686655998
 MARSHAL 0.00728442907333

Clearly marshal is faster but to quote the documentation:

"Warning: The marshal module is not intended to be secure against erroneous or maliciously constructed data. Never unmarshal data received from an untrusted or unauthenticated source."

Clearly simplejson is a very fast reader and the JSON format has the delicious advantage that it's "human readable" (compared to the others).

NOTE! I spent about 5 minutes putting together the script and about 10 minutes writing this so feel free to doubt it's scientific accuracy.


>Read the whole text (139 more words)

7th of May

Never seen before Google Server Error

Never seen before Google Server Error I've never seen a Server Error on Google before. I've seen errors before but they often indicate that the whole service is out for a brief moment. This time it feels like a bug that has caused it.

Don't get me wrong. I still thing Google search is the best Internet invention since e-mail.

29th of April

Lizard walk charity for the Claremont project

Lizard walk charity for the Claremont project THANK YOU ALL who sponsored me to do the lizard walk with the FWC Kung fu club on Saturday 25th of April for the Claremonth Project. Together I believe we raised over £3,000 for the charity and it was a fun event altogether.

Pictures available here

28th of April

Crosstips now has sparklines

Crosstips now has sparklines My crossword solving website Crosstips now has a cute little chart in the lower right hand corner. It's a sparkline. The line indicates how many searches have been done in the current month. The screenshot was taken on the 28th of April so it's the searches done in April and it's near the right hand side which is the maximum.

These charts are made with Google Chart which is something I've never had the great opportunity to try before.

Making the chart was quite a pleasure actually. I had it up and running within minutes just my looking at some examples. The lib I used to make it happen was pygooglechart which was, despite its lack of documentation, really easy to use.

How useful this sparkline is to the people who try to get unstuck on their crosswords I really don't know but it sure looks cool.

25th of April

mailto: considered stupid, especially with ?subject

I don't have any stats to back this up but if I look around the office almost a lot of people use Gmail or Hotmail or something web based. My family uses Gmail, Yahoo mail and Hotmail (and me on Gmail) for example. So it bugs me when websites use the mailto: thing. Especially if they rely on the Subject line.

Here for example, on the EDF Energy Contact us page, they have a long list of "Email us" links. They're almost all going to mailto:customer_correspondence@edfenergy.com but all with a different subject line:

 mailto:customer_correspondence@edfenergy.com?subject=Dual Fuel enquiry
 mailto:customer_correspondence@edfenergy.com?subject=Dual Fuel sales enquiry
 mailto:customer_correspondence@edfenergy.com?subject=Energy efficiency enquiry
 mailto:customer_correspondence@edfenergy.com?subject=Priority Services enquiry
 mailto:customer_correspondence@edfenergy.com?subject=Electricity prepayment enquiry
 mailto:customer_correspondence@edfenergy.com?subject=Gas prepayment enquiry
 mailto:customer_correspondence@edfenergy.com?subject=Home movers enquiry
 mailto:customer_correspondence@edfenergy.com?subject=Green Tariff enquiry
 mailto:customer_correspondence@edfenergy.com?subject=Meter Reading enquiry
 mailto:customer_correspondence@edfenergy.com?subject=Bill payment enquiry
 mailto:myaccount@edfenergy.com?subject=MyAccount query
 ...

Does that mean that I have to somehow copy the Subject line from each so that my email gets routed to the right department? I just don't know. Why can't they have different email address for each thing or a web form where I can email them there and then?

Using mailto: should be done very sparingly. Considering that most people (like my mom) don't know to right-click and select "Copy email address" I prefer this way to show an email address:

 <a href="mailto:more@userfriendly.com">more@userfriendly.com</a>

24th of April

Peterbe.com Bookmark

Tux - lterally in Linux code

http://www.100mb.nl/ 

22nd of April

Git + Twitter = Friedcode

Git + Twitter = Friedcode I've now written my first Git hook. For the people who don't know what Git is you have either lived under a rock for the past few years or your not into computer programming at all.

The hook is a post-commit hook and what it does is that it sends the last commit message up to a twitter account I called "friedcode". I guess it's not entirely useful but for you who want to be loud about your work and the progress you make I guess it can make sense. Or if you're a team and you want to get a brief overview of what your team mates are up to. For me, it was mostly an experiment to try Git hooks and pytwitter. Here's how I did it:


>Read the whole text (252 more words)

15th of April

Lesson learned: Unicodifying request variables in Zope

This cost me a good hour of debugging so I thought I'd share it in case anybody else stumbles across the same problem. In the end, to solve my problem I had to add debug statements to StringIO.py to be able to find out where in my Zope Page Template a non-unicode string with non-ascii characters appeared and messed things up.

The error I was getting was this, which I suspect several Zope developers have encountered before:

 UnicodeDecodeError: \
 'ascii' codec can't decode byte 0xc3 in position 46: ordinal not in range(128)

The traceback only mentions files in the innards of ZPT of which none you can really do anything about. We all know that the key to avoid Unicode error is to be consistent. You can do this:

 >>> '\xc3' + 'string'
 '\xc3string'
 >>> u'\xc3' + u'string'
 u'\xc3string'

But you can't do this:

 >>> '\xc3' + u'string'
 Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
 UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: 
 ordinal not in range(128)

So, how did I get these non-unicode strings into my application in first place. Simple, I have a search parameter q and end up with a URL like this:

 /bla/bla?q=régime

And the template had this little innocent piece of code:

 <input tal:attributes="value request/q"/>

That's what f'ed everything up. So, I ended up having to add this:

 <input tal:attributes="value python:context.unicodify(request['q'])"/> 

With this little helper function in the base class:

 def unicodify(self, s):
    if isinstance(s, str):
        return unicode(s, 'utf8')
    return s

So, hopefully by writing this it will help someone else making the same trivial mistake and not wasting their evening with sporadic print statements all over their frameworks code.

14th of April

Peterbe.com Bookmark

Fujitsu FLEPia

http://www.mobileread.com/f...d=3218&amp;d=1177094663 

Rumor has it's it's $thousands still if you can even buy one. The juicy thing about these is that they promise around 50 hours of battery life since it takes 0 power to show a screen. It only takes power to change the screen which makes it ideal for reading e-books.

More in this annoyingly narrated video

11th of April

TypeRacer Best online game in years

TypeRacer Best online game in years Typeracer is a game where you're competing with other typers by trying to write a text as quick as possible. One race takes about 1 minute.

Not only is it very well done and extremely "educational" but it's also fun. Unlike other games of the same genre you're not judged by your speed and accuracy. In Typeracer it's all about speed. Your mistakes is your problem since they stop your speed. It's hard to explain but it just works great. Play it and you'll see.

Having played this I realise that my spelling is absolutely terrible. I've grown to depend on the spellchecker in Firefox and when I'm doing programming I don't have to spell particularly much because I use auto-complete. At the moment I average around 55 words per minute which means I win quite a few races but still far far away from the high scores which start on 100+. Gotto to practice more!

8th of April

Google Calendar, iCalendar Validator but not bloody Apple iCal

I've got a public ical at: http://m.fwckungfu.com/calendar.ics

This works in Google Calendar and in the iCalendar Validator but when I try to import this as a file in Apple iCal I get this message:

"Error subscribing to the calendar

Data downloaded from http://m.fwckungfu.com/calendar is not valid."

WTF? Who's ass have I not kissed to get this working in Apple iCal? Does anybody know any reason why Apple iCal is being so trixy?

7th of April

Simple interface for Crosstips

Simple interface for Crosstips I've now made a simple interface alternative (not AJAX) to Crosstips. This one doesn't do any fancy AJAX to look up works and you just type in the unknown letters as a space (or a _ or a . or a *) so you don't have to know how many letters it is.

Here's an example

It feels refreshing somehow to go back from AJAX back to plain old GET requests. The best thing about this is that it will work on a mobile phone too. The way I've wired the page is so that if you visit the site with a mobile device (not an iPhone though) it will load the extremely cut down version of the layout which is more suitable for mobile phones. This means that people will be able to get unstuck doing crosswords in bed.

2nd of April

Shit trailer, awesome way to show it

I'm pretty damn sure I won't pay to see this movie in the cinema. I'm pretty sure I won't want to download it illegally and watch it either. But I have to admit this is a pretty awesome way to show the trailer.

Just watch it and you'll see what I mean.

31st of March

Head-to-head movie voting

Head-to-head movie voting There's really no good way to explain what The Great Movie Experiment is other than just testing it. It's quite addictive and you somehow feel like you're contributing to something great.

"The gist is that we're compiling a list of movies based on head to head votes, matching them up in a giant round-robin tournament."

It's not really what head-to-head voting is about but there are times I would like a third button when a film sucks. Many times you're confronted by one mediocre film and one film which is only ok; then you're "forced" to vote for the one that is only ok.

Great work Matthias!

17th of March

British or American English or just English

British or American English or just English My play site Crosstips.org is available in British English and American English. Obviously the difference is small but it's important.

What I've done is that if you're located in, say, France and visit the site it offers you the following language choices:

  • Svenska [goes to krysstips.se]
  • English (GB) [goes to en-gb.crosstips.org]
  • English (US) [goes to en-us.crosstips.org]

But if you're located in, say, England it only offers you the following language choices:

  • Svenska [goes to krysstips.se]
  • English [goes to en-gb.crosstips.org]

And likewise, if you visit the site from US computer you just get two options and it uses the en-us.crosstips.org domain. As an American or a Brit why would you be interested in the other English? I think this is a really good usability trick. It reduces the noise by removing options.


>Read the whole text (47 more words)

16th of March

Nginx vs. Squid

We all know that Nginx is fast and very lightweight. We also know that Squid is very fast too. But which one is fastest?

In an insanely unscientific way I added some rewrite rules to my current Nginx -> Squid -> Zope stack so that for certain static content, Nginx could go straight to the filesystem (where the Zope product holds the static stuff) to bypass the proxy pass. Then I did a quick and simple benchmark with ab comparing how to get a 700 bytes GIF image:

 squid: 2275.62 [#/sec] (mean)
 nginx: 7059.45 [#/sec] (mean)


>Read the whole text (143 more words)

12th of March

Too much Python makes Peter a shit Javascript developer

This murdered a good half hour of my time splattered with lots of alert() statements to debug. Basically, in Firefox you can do this:

 var word = "Peter";
 alert(word[1]); // "e" in Firefox, undefined in IE

This is the wrong way to get to character in a string in Javascript. The correct way is to use charAt() like this:

 var word = "Peter";
 alert(word.charAt(1)); // "e" in Firefox and IE

I don't know about the other browsers but finally Crosstips.org now works in IE7 too. I haven't even looked at it in IE6 and don't intend to either.

3rd of March

Sandisk SSD v/s HDD

Sandisk SSD v/s HDD I have for a long time been excited about getting one of those SSD drives to boost my laptop. Especially one of those SanDisk 40,000 RPM drop in replacement drives. Skimming around on YouTube there seem to be lots of videos showing how fast the new SSDs are at booting the operating system compared to HDDs.

BUT! These comments caught me attention:

chinesemilkman
"I've worked with those newfangled SSD Macs at my student computing support job and if memory serves, they run applications slower than your standard HDD Macs. I doubt any SDD storage product would run audio and visual as fast as a SATA II. Maybe one day they will optimize performance but in actuality, I have my doubts that any current SDD out performs top of the line HDDs in performance. AND COMPARING BOOTUP SPEED IS NOT A RELIABLE PERFORMANCE TEST! Lame marketing gimmick is what it is."

johnnyfast
"Interesting how NONE of the SSD tests show a real world multi-tasking environment.
I have an OCZ SSD 64 and it totally fails, as soon as my PC is doing 2 or more read/write multi tasks I get horrendous lock ups. It is going back to the shop as unfit for purpose.
SSD is a one trick (read speed) pony."

I mean, they "promise" speed, higher durability and lower power consumption. I was ready to almost accept the extreme prices and the disappointingly small sizes but if speed is only in boot up and single operations then I'd rather spend my money on RAM or CPU or something.

24th of February

To $('#foo p') or to $('p', $('#foo'))

For the performance interested jQuery users please check out this thread

For the impatient, read Stephens reply He benchmarked what I asked and concluded that $("p", $("#foo")) is much faster in jQuery 1.3.2. I've been coding this style in jQuery for all recent projects so I'm happy with this outcome.

UPDATE

John Resig himself joined in on the discussion and had this to say:

"You should always use $("#foo").find("p") in favor of $("p", $("#foo")) - the second one ends up executing $(...) 3 times total - only to arrive at the same result as doing $("#foo").find("p")."

UPDATE 2

Not only did John join in on the discussion but it also made him work on jQuery 1.3.3 (not yet released at the time of writing) so that it doesn't matter which format you use you get the same performance. See the benchmark here

23rd of February

Peterbe.com Bookmark

Propeller Island City Lodge Orange Room

http://www.propeller-island...detail/01/index.php 

How cool are these rooms? This is a hotel in Berlin that was recommended to me by a friend. I haven't been there but after having seen the pictures I definitely want to go to this hotel if/when I visit Berlin.

17th of February

Founder of Islamic TV station accused of beheading wife

Funniest sad news of the week:

"Muzzammil Hassan was charged with second-degree murder after police found the decapitated body of his wife, Aasiya Hassa"

And what makes this horrible sad news so funny:

"He launched Bridges TV, billed as the first English-language cable channel targeting Muslims inside the United States, in 2004. At the time, Hassan said he hoped the network would balance negative portrayals of Muslims following the attacks of September 11, 2001."

D'oh!

14th of February

To assert or assertEqual in Python unit testing

When you write unit tests in Python you can use these widgets:

 self.assertEqual(var1, var2, msg=None)
 self.assertNotEqual(var1, var2, msg=None)
 self.assertTrue(expr, msg=None)
 self.assertRaises(exception, func, para, meters, ...)

That's fine but is it "pythonic" enough? The alternative is to do with with "pure python". Eg:

 assert var1 == var2, msg
 assert var1 != var2, msg
 assert expr, msg
 try:
    func(para, meter)
    raise Exception
 except exception:
    pass

I'm sure there are several benefits with using the unittest methods that I don't understand but I understand the benefits of brevity and readability. The more tests you write the more tedious it becomes to write self.assertEquals(..., ...) every time. In my own code I prefer to use simple assert statements rather than the verbose unittest alternative. Partially because I'm lazy and partially because they read better and the word assert is highlit in red in my editor so it just looks nicer from a distance.

Perhaps some much more clever people than me can explain what a cardinal sin it is to not use the unittest methods over the lazy more pythonic ones.

Incidentally, during the course of jotting down this blog I reviewed some old inherited code and changed this:

 self.assertEqual(len(errors),0)

into this:

 assert not errors

Isn't that just nicer to use/read/write?

12th of February

Peterbe.com Bookmark

Female body builder picture galore

http://www.ccfitwear.com/FI...SHOW%20PICTURES.htm 

Female body builder picture galore If you, like me, is equally fascinated by female body builders this is a great page. It's quite incredible. I'm sure there's a large community of those who do it (men and women) and there's probably men out there who actually like this. I wish Michael Moore would do his next documentary on this instead.

 

Older entriesOrder entries