Blog posts in the english category.
-
Ever since I got my iPhone some weeks ago, I was constantly searching the App Store for the cream of the crop. To somehow document the results, here is a top ten list of my most used / favorite apps.
#1 - Things (8 EUR)
It wasn't exactly love at first sight, but after some getting used to, I really like the iPhone version of Things. It's one of these GTD apps, for your daily todo management. I'm definitely looking forward to syncing it with the desktop version once I have made up my mind about buying a MacBook.
I also tried the free version of Todo, which is very nice, too. People have been complaining about Things lacking tags and areas, but they already uploaded a new version and are waiting for Apple's approval.
#2 - Wikipanion (free)
Quick access to an iPhone friendly reformatted Wikipedia, beautiful UI.
The only thing that bothers me is that I have to scroll to the end of a search results list to switch the search language, but I realize most people won't use more than one language version of Wikipedia as heavily as I sometimes do.
#3 - Fahrplan (free)
Schedules for public transportation in Germany. Great app, even finds the closest bus stop via GPS.
#4 - Twittelator (free)
After trying TwitterFon and Twitterific, I stuck with Twittelator. There may be some minor rough edges in the UI (nothing really disturbing though), but feature-wise Twittelator is definitely top of the list.
#5 - MPoD (free)
Client for MPD servers. Pumping up the volume of the speakers in the living room playing music from the HDD in the workroom while standing in the kitchen is pretty neat.
#6 - Shopper (0,80 EUR)
Allows you to create a database of various items you frequently buy. You can the put any of these on your 'shopping list', ticking them off as you go through your local mall.
#7 - FStream (free)
Listen to web radios on the go.
#8 - Classics (0,80 EUR)
Small library of 13 classic books, lovely UI. Check out the video on their website.
#9 - Virtual Pool (0, 80 EUR)
The UI isn't the prettiest, but for less than 1 EUR you get a decent 3d pool experience.
#10 - Your app here!
OK, I couldn't really come up with ten apps, I have a couple more apps on my iPhone, but I'm not satisfied enough with any of them to include them here. -
The pyplog code has been moved from Google Code to github.
I plan on starting an i18n branch soon to mark strings for translation.
-
If you're using generic views in Django, you probably do something like this in your URLconf:
pages = Page.objects.all() [...] url(r"^pages/(?P
Now, say you want to show the title of these pages in a menu on each page. You add a new context_processor:.*)$", object_detail, { "queryset" : pages }),
from myapp.pages.models import Page pages = Page.objects.all() def add_pages(): return { "pages" : pages }When you add a page now, you'll notice that it won't appear in your menu because the queryset has been evaluated the first time it has been accessed, and will remain the same as long as the python interpreter isn't restarted. However, generic views appear to do the same thing and still show the most current content. They accomplish this by doingqueryset = queryset._clone()
on each call. A cloned queryset will always be non-evaluated at first, which means that generic views will hit the database each time they're called. You could of course do that as well, but you feel bad about grabbing those pages out of the database at every single request. My solution for this in pyplog was the following:
from django.db.models.signals import post_delete, post_save class CachedQuerySetManager: """ Manages a list of querysets that are automatically updated whenever an object is added to or deleted from one of them. """ def __init__(self): self.querysets = {} def __getitem__(self, key): return self.querysets[key]["queryset"] def add(self, model, manager = "_default_manager"): self.querysets[model] = { "queryset" : getattr(model, manager).all(), "manager" : manager, } post_delete.connect(self.update, sender = model) post_save.connect(self.update, sender = model) def remove(self, model): post_delete.disconnect(self.update, sender = model) post_save.disconnect(self.update, sender = model) self.querysets.__delitem__(model) def update(self, sender, **kwargs): self.querysets[sender]["queryset"] = \ getattr(sender, self.querysets[sender]["manager"]).all() cached_querysets = CachedQuerySetManager()The above example would look like this:
from myapp.pages.models import Page from myapp.util.query import cached_querysets cached_querysets.add(Page) def add_pages(): return { "pages" : cached_querysets[Page] }Now the queryset is reset everytime a page is added or deleted. Note that you should of course only do this with QuerySets that you can afford to completely keep in memory (read: just a couple of objects). The QuerySet passed to a generic view never gets evaluated itself, so that it's very cheap to have it around. The above code however keeps the evaluated QuerySet and will increase memory usage in favor of database load.
You probably won't need this if you're using traditional caching (memcached), but for the folks that choose to go without it, this little helper might come in handy.
Note that the CachedQuerySetManager class above is part of pyplog and therefore published under the GPL license. See pyplog's LICENSE file for more information. -
After quite a while of photographic idleness, Martina and I had a very fun pin-up shooting today.
Not all of the photos turned out quite as pin-uppy as we originally intended them to be, check them out at deviantART or my local gallery. -
I recently checked-in a complete rewrite of pyplog to Google Code. Django 1.0 is now supported and a lot of awful code had to go. I'll be adding some new install instructions to the wiki soon.
Pages:
1,
2