Crosstips.org

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

Kung Fu

Fujian White Crane Kung Fu

Fry-IT

Fry-IT is the company I work for

Photos

Photoalbum, both old and new.

Zope

What I have and am doing with Zope

Receptsamlingen

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

Contact me

My contact details and how to contact me.

 

KungFuPeople.com
Do you train Kung Fu?
Or know someone who does?
Then check out KungFuPeople.com


Mobile version of this page Mobile version of this page

RSS

Hot topics

by Peter Bengtsson: Lack of transactions is definitely a key pain point. It changes your code a...

Speed test between django_mongokit and postgresql_

by Peter Bengtsson: I'm sure there are parameters to make it faster but there are parameters to...

Speed test between django_mongokit and postgresql_

by Peter Bengtsson: Both when it retrieves for editing and for deleting it does selects by key....

Speed test between django_mongokit and postgresql_

by Eas: Michael, there are other postgres tuning parameters that help with throughp...

Speed test between django_mongokit and postgresql_

by Alex: You're comparing 1000 transactions vs. 1000 inserts to a database that does...

Speed test between django_mongokit and postgresql_

by Michael Pasternak: I'm following your posts carefully :-) It seems, that "good old SQL" is of...

Speed test between django_mongokit and postgresql_

by Massimiliano Torromeo: What about SELECTs?...

Speed test between django_mongokit and postgresql_

by Peter Bengtsson: I could. Perhaps when time allows. Feel free to fork it on github if you fe...

Speed test between django_mongokit and postgresql_

by Henrique Carvalho Alves: Can you compare the timing for making queries? Single table/document queri...

Speed test between django_mongokit and postgresql_

by anonymous: D firm is a hot 1...

Terminator 3 Rise of the machines

Old entries


September, 2009
London Frock Exchange launched
My first Twitter app - KungFuPeople.com
Comparing jsmin and slimmer
Python Code Dojo London - 17 Sep 2009
"Hello John. It's Gordon Brown."
7 of the World's Most Irresponsible Companies

August, 2009
Cgunit - Online Gallery
To sub-select or not sub-select in PostgreSQL
Custom CacheMiddleware that tells Javascript a page is cached in Django
What a super user-friendly menu!
Table Of Countries Showing Drive Direction
The Secret to SEO Search Engine Optimization
Calling all kung fu people - kungfupeople.com
Google Reverse Geocoding vs. GeoNames
gg - wrapping git-grep
Public calendars on Google Calendar
More optimization of Peterbe.com - CSS sprites

2009
2008
2007
2006
2005
2004
2003

 

9th of March

Speed test between django_mongokit and postgresql_psycopg2

Following on from yesterday's blog about How and why to use django-mongokit I extended the exampleproject which is inside the django-mongokit project with another app called exampleapp_sql which does the same thing as the exampleapp but does it with SQL instead. Then I added a very simple benchmarker app in the same project and wrote three functions:

  1. One to create 10/100/500/1000 instances of my class
  2. One to edit one field of all 10/100/500/1000 instances
  3. One to delete each of the 10/100/500/1000 instances


>Read the whole text (325 more words)

8th of March

How and why to use django-mongokit (aka. Django to MongoDB)

How and why to use django-mongokit Here I'm going to explain how to combine Django and MongoDB using MongoKit and django-mongokit.

MongoDB is a document store built for high speed and high concurrency with a very good redundancy story. It's an alternative to relational databases (e.g. MySQL) that is what Django is tightly coupled with in it's ORM (Object Relation Mapping) and what it's called now is ODM (Object Document Mapping) in lack of a better acronym. That's where MongoKit comes in. It's written in Python and it connects to the MongoDB database using a library called pymongo and it turns data from the MongoDB and turns it into instances of classes you have defined. MongoKit has nothing to do with Django. That's where django-mongokit comes in. Written by yours truly.


>Read the whole text (1551 more words)

6th of March

Ubuntu Cola or Ubuntu Linux

Ubuntu Cola or Ubuntu Linux

Which came first?

Does it matter?

5th of March

Importance of public URLs and how enterprisecarsales.com gets it wrong

Importance of public URLs and how enterprisecarsales.com f's it up A friend of mine found a nice car she on www.enterprisecarsales.com so she copied the current URL from the address bar and emailed that to me. The URL was: http://www.enterprisecarsales.com/carsales/vehicleDetails.do?carIndex=1&vin=1GCHC24U36E112452 which by the look of it (notice the /vehicleDetails.do part of the URL) takes you to a page that says "Sorry, we are unable to complete your page request since the page you are trying to access no longer is available." How stupid is that? Come on, web developers made those kind of mistakes in 2001. Not 2010.

This means that people can't talk to each other about found matches on the site and this is something people want to do. Especially if you're going to spend $thousands on a car.

Come on Enterprise web team: install Django or something and give users what they want not your excuses.

28th of February

Massive improvement on sorting a fat list

IssueTrackerMassContainer is a simple Zope product that is used to put a bunch of IssueTrackerProduct instances into. It doesn't add much apart from a nice looking dashboard that lists all recent issues and then with an AJAX poll it keeps updating automatically.

But what it was doing was it recursively put together all issues across all issue trackers, sorting them and then returning only the first 20. Fine, but once the numbers start to add up it can become a vast sort operation to deal with.

In my local development copy of 814 issues, by the use of pympler and time() I was able to go from 7 Mb taking 2 seconds down to using only 8 Kb and taking 0.05 seconds.


>Read the whole text (409 more words)

27th of February

How girls/guys rate guys/girls

How girls/guys rate guys/girls It's of course a simplification but is it not true? Come on, admit it, isn't there something to it?

What do you think? As a man I must admit that it does feel like that. I don't know about the girls perspective so I'd love to hear what you think (keeping it mind that it's an exaggeration)

17th of February

Peterbe.com Bookmark

Looking for icons?

http://www.iconfinder.net/free_icons 

Check out these all free icons

13th of February

Last.fm Tube Tags

Last.fm Tube Tags Last month I marveled over the cute LastGraph which shows you a visualization of what artists you've been listening to on Last.fm lately in a neat way. Today I discovered this cute visualization: Tube Tags

I think it's only for paying Last.fm users since it says "VIP" next to the link. My understanding is that it shows the genres of music you've been listening too recently in a London Underground type of map way. Very neat.

Here's mine (31Kb PDF)

2nd of February

Haiti Earthquake: Who's given what?

Haiti Earthquake: Who's given what? If I've understood it correctly, this is a mashup made on Guardian's API made by someone not at the Guardian. More photos here

What's interesting about this chart, which I've never seen like this before, is the last one where they show how much money various countries pledged versus how much they actually delivered. It's something I've also wanted to see because it opens up a whole new dimension of truth to the equation. For example, Canada has pledged USD 130m to the Haiti Earthquake but they only delivered 51% of what they pledged to the 2004 Tsunami crisis.

27th of January

Healing Food Reference

Healing Food Reference Spotted this website called Healing Food Reference which is what the name says; a reference of food and their healing "power". From the home page:

"This site is part of a public education project created by Mike Adams, the Health Ranger, and hosted by Truth Publishing. Its purpose is to educate and empower consumers with information they can use to prevent and even help reverse degenerative disease. There are no commercial sponsors of this site, and neither Mike Adams nor Truth Publishing was paid anything to create this site."

Basically click on a type of food, for example tofu and you get a list of things it can help with such as fever and then from the fever page you can more foods that help.

At first I was a bit taken aback by the home page and huge amounts of text on it but once you're in it is so easy to use. Perhaps the reason the home page is jam packed with content is for his search engine optimization.

23rd of January

Guake, not Yakuake or Yeahconsole

I've been a big fan of Yakuake for a long time. It's a terminal you have open all the time in Linux that is shown and hidden, over any other windows, by a simply hit on the F12 button.

But as of more recent versions of Yakuake it has become really slow. It sometimes take 2-3 seconds from F12 press till you can type on the terminal. So I uninstalled it and tried Yeahconsole but I uninstalled it equally fast as I understood it was broken and didn't work at all despite being in the Xubuntu apt repositories.

Last but not least I ended up using Guake which not only works but also works really really fast. Screenshots here

20th of January

Peterbe.com Bookmark

oplop - How Oplop works, explained in plain English and in technical detail

http://code.google.com/p/oplop/wiki/HowItWorks 

If you want to just remember one single password and you want to use different passwords for different site then Oplop might be right for you.

18th of January

Tip: creating a Xapian database in Python

This cost me some hair-pulling today as I was trying to write a custom test runner for a Django project I'm working on that creates a test Xapian database just for running the tests. Basically, you can't do this:

 os.mkdir(database_file_path)

Because if you do you end up getting these strange DatabaseOpeningError exceptions. So, here's how you do it:

 import xapian
 xapian.WritableDatabase(database_file_path,
                         xapian.DB_CREATE_OR_OPEN)

Hopefully by blogging about this some other poor coder will save some time.

16th of January

Bookmarklet to replace the current domain with localhost:8000

If you, like me, have various projects that do things like OAuth on Twitter or Google or you have a development site that goes to PayPal. So you're doing some Django development on http://localhost:8000/foo and click, for example, to do an OAuth on Twitter with an app you have there. Then Twitter will redirect you back to the live site with which you've set it up. But you're doing local development so you want to go back to http://localhost:8080/... instead.

Add this bookmarklet: to localhost:8000 to your browser Bookmarks toolbar and it does exactly that.

Here's its code in more verbose form:

 (function() { 
    a = function(){
      location.href = window.location.href.replace(/http:\/\/[^\/]+\//,
             'http://localhost:8000/')
    };
    if (/Firefox/.test(navigator.userAgent)) { 
      setTimeout(a,0)
    } else {
       a()
    }
  })()

8th of January

LastGraph - visualizing your Last.fm usage

LastGraph - visualizing your Last.fm usage For those who use last.fm and like to visualize stuff with pretty graphs. For the really curious, here's mine of the last year (15 Mb)

23rd of December

China wrecked the Copenhagen deal

"Copenhagen was much worse than just another bad deal, because it illustrated a profound shift in global geopolitics. This is fast becoming China's century, yet its leadership has displayed that multilateral environmental governance is not only not a priority, but is viewed as a hindrance to the new superpower's freedom of action. I left Copenhagen more despondent than I have felt in a long time. After all the hope and all the hype, the mobilisation of thousands, a wave of optimism crashed against the rock of global power politics, fell back, and drained away."

From the brilliantly informed and well articulated article How do I know China wrecked the Copenhagen deal? I was in the room

Just so you know, I love China, but there's a lot of things I hate about it too. Admittedly, any country in their position would perhaps do the same as the force of people getting rich is more powerful than almost anything else. Please do take the time to read this article as it helps to give an interesting perspective on the post-Copenhagen-conference talks.

16th of December

Migrating with South on a field that uses auto_now_add=True

I have a Django model that looks something like this:

 class MyModel(models.Model):
    modify_date = models.DateTimeField(auto_now=True)
    ...

Retroactively now I wanted to add a field called add_date which uses the auto_now_add=True trick. The migration used in this project is South which is great but doesn't work very well with the auto_now_add=True because the field doesn't have a straight forward default. So, first I changed the field to this:

 class MyModel(models.Model):
    modify_date = models.DateTimeField(auto_now=True)
    add_date = models.DateTimeField(auto_now_add=True, null=True)
    ...

Notice the null=True which is important. Then I used startmigration to generate the code for the forward and backward to which I added a this stuff:

 class Migration:

    def forwards(self, orm):

        db.add_column('myapp_mymodel', 'add_date', orm['myapp.mymodel:add_date'])
        for each in MyModel.objects.all():
            # since MyModel is referenced elsewhere I can work out the oldest date
            oldest_date = get_oldest_related_date(each, 
                               default=each.modify_date)
            each.add_date = oldest_date
            each.save()

That way all old records will have the date (not entirely accurate but good enough) and all new records will automatically get a date. Is there a better way? I bet, but I don't know how to do it.

15th of December

Peterbe.com Bookmark

Homer Simpson playing Cry of the Black Birds by Amon Amarth


http://www.youtube.com/watc...=4&playnext_from=QL 

You'll have to believe it when you see it. Here's the orignal if you want to know who they are.

8th of December

Orphaned Land - Jewish Muslim Metal

Orphaned Land - Jewish Muslim MetalOrphaned Land is a great metal band from Israel who I've known about for some time but never researched much.

"Israel's ORPHANED LAND is probably the only band from this country that has managed to succeed at building up a huge following among Muslims and Arabian people"

I've never taken the time to listen to their lyrics and figure out what they're singing about. It's not a surprise that they're not pro one side only but I didn't know that they appeal to both sides which is quite fantastic.

17th of November

Comparing YUI Compressor and slimmer

YUI Compressor apparently supports compressing CSS. Cool! I had to try it and what's even more cool is that it's the only other CSS minifier/compressor that doesn't choke on CSS hacks (the ones I tried). The only other CSS minifier/compressor is my very own slimmer. So, let's see what the difference is.

Running the YUI Compressor 10 times on a relatively small file takes 0.3 seconds on average. Running the same with python 2.6 and slimmer.css_slimmer takes 0.1 seconds on average. I think most of this time is spent loading the jar file than the actual time of running the compression.


>Read the whole text (118 more words)

15th of November

Those Crazy Chinese

Those Crazy Chinese My friend Chris West has built a great new site called Those Crazy Chinese which describes itself like this:

"Chinese (Mandarin) is a beautiful and highly literal language - directly translated, many words have entertaining and occasionally logical meanings."

It's built in Django and it integrates to Twitter so if you're on Twitter just follow it there to get the latest additions of new interesting and amusing literal translations. This website is mainly geared towards people who are, like Chris, learning Mandarin.

8th of November

Mocking os.stat in Python

I have some code that checks that a file is treated differently if some time has passed. In other words, it reacts if the modification time is more than it was before. The code uses os.stat(filename)[stat.ST_MTIME] to do this. The challenge was to mock os.stat so that I can pretend some time has passed without having to wait. Here was my first solution which made running many tests sloooow:

 def test_file_changed(self):
     filename = 'foo.txt'
     expect_timestamp = int(time.time())
     ...run the unit test with 'expect_timestamp'...
     time.sleep(1)
     expect_timestamp += 1
     ...run the unit test with 'expect_timestamp'...

So, here's how I mock os.stat to avoid having to do the time.sleep(1) in the test:

 def test_file_changed(self):
     filename = 'foo.txt'
     expect_timestamp = int(time.time())
     ...run the unit test with 'expect_timestamp'...
     import os
     from posix import stat_result
     def fake_stat(arg):
         if arg == filename:
             faked = list(orig_os_stat(arg))
             faked[stat.ST_MTIME] = faked[stat.ST_MTIME] + 1
             return stat_result(faked)
         else:
             return orig_os_stat(arg)
     orig_os_stat = os.stat
     os.stat = fake_stat

     expect_timestamp += 1
     ...run the unit test with 'expect_timestamp'...

I hope this helps someone else who's trying to do the same. It took me some time to figure out that os.stat is used by lots of various sub routines in the os module so it's important to only mock the relevant argument otherwise you might get unexpected problems.

29th of October

"Frank Zappa: The Biography" by Barry Miles

Available on Amazon.com I've just read Frank Zappa: The Biography by Barry Miles. It's a detailed book on 380 pages about virtually every year of Frank Zappa's life. From his parents to his death.

I'm a huge Frank Zappa fan and have been for more than a decade. It's probably the most listened to artist ever in my life in terms of number of listened to songs. Actually not probably; definitely. I adore his music and his personality and this is the second book I read about him. The other book I read was Real Frank Zappa Book written by Peter Occhiogrosso based on biography interviews with Frank for the purpose of writing this book. That book was much more bland and emphasized particularly his early political work and also very much emphasizes on his work as a orchestral conductor/business man.

The detail work in this book is really fantastic. It's thanks to Barry's in-depth understanding of music and the music industry that you get deep down to the nitty-gritty details of Zappa's work. As always with books like this, it's not till you read about the lyrics that you fully understand the lyrics even if you have listened to them many a times. Some of these lyrics I'm actually kind of sad to have understood now as of reading about them in this book. For example, I now understand that the song We're Turning Again which is an up-yours to his old band members Mothers of Invention.

If anything bad can be said about the book it's that it sort of ends on a bad note (no pun intended), as it ends on the sad last few years when Frank was really sick and up to the point of his death. And also, I would have liked to find out more about Barry's own personal relationship with Frank because he couldn't possibly have written this book had he not admired the guy too.

There is no doubt in my mind that Frank Zappa is one of the most innovative and inspirational characters in twentieth-century music history. And probably show-biz too for that matter. Even though the book reveals some truths about Frank as a bit of "douche bag" I'm still firmly one of his biggest fans. If you wanna find out more about Frank Zappa this is most like the book to get.

Following is an extract from a quoted interview by Gail Sloatman who later became Gail Zappa:

"And I remember thinking, Oh my God! Here's this guy, I think he's extraordinary, it's such a different sensation! I know he hasn't taken a bath in four months and his moustache smells like peanut butter..."

She sums it up nicely in her own very personal words so well. There is something amazing about this guy beyond the less appealing facade.

25th of October

iPhone push notifications for Twitter with Prowl

iPhone push notifications for Twitter with Prowl Bruno Renié has written a nifty app:iPhone push notifications for Twitter with Prowl

With the power of Prowl it pushes a notification to your iPhone when someone mentions you on Twitter. You first need to install the Prowl app on your iPhone and then go to their website to get your notification key. Then, go to Bruno's site, sign in with your Twitter account (OAuth, so no password give-away) and badabing! you get instant notifications on your phone, for free, when someone mentions you.

If you're one of those people who use Twitter instead of instant messaging and have lots of mentions this might be excessive for you but if not it can be very useful if you are like me who is very slow to spot that someone has replied or mentioned your name.

Great work Bruno!

22nd of October

Make makes my website slow? DNS

Pagetest web page performance test is a great tool for doing what Firebug does but not in your browser. Pagetest can do repeated tests to iron out any outliers. An alternative is Pingdom tools which has some nifty sorting functions but is generally the same thing.

So I ran the homepage of my website on it and concluded that: Wow! Half the time is spent on DNS lookup!

FirstSecondThird

The server it sits on is located here in London, UK and the Pagetest test was made from a server also here in the UK. Needless to say, I was disappointed. Is there anything I can do about that? I've spent so much time configuring Squid, Varnish and Nginx and yet the biggest chunk is DNS lookup.

In a pseudo-optimistic fashion I'm hoping it's because I've made the site so fast that this is what's left when you've done all you can do. I'm hoping to learn some more about this "dilemma" without having to read any lengthy manuals. Pointers welcomed.

19th of October

What I hate about PIL and Image in Python

One really annoying thing about PIL is that it's importable as ImageandPIL. It leads me and other newbies to think if it's different. I don't want choices:

 Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
 [GCC 4.3.3] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
 >>> import PIL
 >>> import Image
 >>> ?

When PIL/Image is put into standard lib, can we call the module: imaging?

16th of October

Messed up columns in Django Admin

In case this bites someone else like it bit more and chewed off many many minutes of debugging time.

If you ever get weird columns in your Django Administration interface, I now know why that happens. See this screenshot example:

Messed up columns in Django Admin

This happens when you've defined a TEMPLATE_STRING_IF_INVALID in your settings.py. I always put in my local_settings.py this line:

 TEMPLATE_STRING_IF_INVALID = '{{ %s }}'

So that I can quickly see which variable references in template code is potential typos. I'm not a big fan of the implicit magic of equating absence to False/None so I try to avoid the confusion altogether.

12th of October

Automatically strip whitespace in Django forms

The current project I'm working has at the time of writing 20 different forms (90% model forms) instantiated in different scenarios. Django doesn't automatically strip whitespace in text based fields. So instead of doing this:

 class ContactMarketingForm(forms.ModelForm):
    class Meta:
        model = ContactMarketing
        exclude = ('contact',)

    def clean_notes(self):
        return self.cleaned_data['notes'].strip()

    def clean_name(self):
        return self.cleaned_data['name'].strip()

Instead I wrote a common class for all of my form classes to use:

 class _BaseForm(object):
    def clean(self):
        for field in self.cleaned_data:
            if isinstance(self.cleaned_data[field], basestring):
                self.cleaned_data[field] = self.cleaned_data[field].strip()
        return self.cleaned_data

 class BaseModelForm(_BaseForm, forms.ModelForm):
    pass

 class ContactMarketingForm(BaseModelForm):
    class Meta:
        model = ContactMarketing
        exclude = ('contact',)

Now all text inputs and textareas are automatically whitespace stripped. Perhaps useful for other Djangonauts.

8th of October

A user-friendly TinyMCE config

A user-friendly TinyMCE config When you enable TinyMCE you can either choose theme="simple" or theme="advanced". If you go for the simple you get one lovely little bar of buttons but it's missing the link button which is more important than most other buttons altogether. When you enable "advanced" you get three rows of buttons that makes you dizzy. I mean, should really be editing advanced tables in a WYSIWYG editor or mathematical equations?

Here's a config that I think works great. It's all in one row and it's got the bare minimum in terms of additional plugins (no extra downloads required). It's in Python but translates quite easily into Javascript:

 TINYMCE_DEFAULT_CONFIG = {
    'plugins': "fullscreen,paste,autoresize",
    'theme': "advanced",
    'theme_advanced_buttons1' : "bold,italic,strikethrough,bullist,numlist,"\
                                "separator,undo,redo,separator,link,unlink,image"\
                                ",separator,cleanup,code,removeformat,charmap,"\
                                "fullscreen,paste",
    'theme_advanced_buttons2' : "",
    'theme_advanced_buttons3' : "",
 }

29th of September

Funnier than Fail Blog: Fail Dogs

Funnier than Fail Blog: Fail Dogs The Fail Blog is funny but sometimes disgusting and borderline sad. Fail Dogs is almost better. A lot of the headlines they put on the pictures just makes it twice as fun. For example this one or this one

Enjoy!

 

Older entriesOrder entries