Saturday, July 25, 2009

Ketchup

Time for a randomly hodge-podged style of a post, since it's been quite some time since my last update. As I alluded to in previous posts I have left my role as a technical engineer at Contegix in search of what I hope is my true calling: being a developer. Now, this move wasn't quite so simple, since in the process I've moved from my hometown of St. Louis, over to Chicago. Yeah, yeah I get it, insert your Cubs hate/love or Cardinals hate/love here. I'm now working for a development shop called Imaginary Landscape which focuses mainly on Python development. Obviously, I'm quite the Python enthusiast, so it's quite fitting. As a bonus, the company encourages the use of open source tools, and encourages contributing back to the open source community. Obviously, this is something I'm rather passionate about, so it's rather fitting.

I've been here in Chicago for roughly two weeks now though, and so far so good. We've had to go through a few changes to make ourselves comfortable here in the lovely city of Chicago, but most of them are actually upsides. For instance, I haven't driven a car in going on 7 days now. I walk to work every day, and most places that we need to go to on a regular basis are also in walking distance. As a result of everything feeling relatively close, we're now walking roughly 1.5 to 2 miles per day now. It's pretty nice too. If something does happen to be outside of walking distance they have this crazy public transportation thing in Chicago. I know, it sounds crazy, but it's actually pretty impressive, definitely not accustomed to that in St. Louis. I'll never understand how people in St. Louis could live without owning some form of vehicle. However, here in Chicago, unless I need to go grocery shopping or something of that sort, I don't need a car. Also, instead of going once for that big haul of groceries it's just easier here to grab what you need when you need it.It's a rather interesting change of pace, and so far much more enjoyable. I love just walking to work every morning. No traffic, or any annoying people to put up with. It's nice.

The biggest change however has to be the cost of smoking in Chicago. It's approximately $8/pack, or roughly $90/carton. That's compared to the $35/carton price in St. Louis. Obviously, $90/carton is just irresponsible. Hence, we're working on quitting. We're currently on day 4 and hanging in there fairly well thus far. Personally I'm a bit perplexed on the price. I understand that it's about $3 for the smokes, and $5 for the taxes. I'm pretty clear there, which puts the tax rate in the realm of astronomical, but whatever. What I don't get is the point. If the point is to make people quit smoking, alright, point made, and you win. However, if you're counting on that money to pay for roads 3 years from now, it doesn't add up. I mean, if everyone quits smoking, all that vice money goes away, and in this city/state that has to be a TON of money, cuz I see smokers everywhere around here. Wouldn't a more balanced tax be more profitable for the government? Ah well, what do I know, maybe they actually want healthy people instead of profits, but I doubt it. Alls well that ends well, and I'm on my way to being smoke free, so that's a good thing. Even if the tax logic is weird.

Finally, there's plenty of stuff to do here in this city. We have myriad of things to choose from to do with our time off. It's not like St. Louis where it seemed like there was never anything fun to do. Here, there's a bunch of fun stuff to do all over the place. Seems like it'll be awhile before we run out of entertainment here.

All in all, I'm ecstatic we made the move. I'm loving the job, the city, and the improvement to my quality of life that both the job and city have brought me. I'm far less stressed, more active, and have more time to actually enjoy life. It's a win all around.

Sunday, July 05, 2009

Yaba Release 0.2

I've decided to package up a new version of YaBa and arbitrarily call it a new version, donning it a shiny 0.2. It felt like a pretty good stopping point as I cleared all of my TODO sections, and also added the ability for themes, archives, and improved the search capabilities along the way. The major improvement in this version is the blurring of lines between stories, galleries, and articles. All three can show up in search results, archives, tag lists, and category lists. Galleries also show up on the front page as new items as well. Hence navigation of the fringe items becomes a bit easier with this release. 

Now if you're currently using 0.1 of YaBa (which I don't think anyone is currently), upgrading can be a bit tricky. I'd recommend starting up 0.2 with a new database, and dumping your 0.1 database straight into the new one. Then you should be ready to roll with all the new features and such. You might be able to get away with just putting the 0.2 files in place, running syncdb, and going on about your merry little way but I wouldn't bank on it. If you do have any issues, please email me though. I'd be glad to help out in getting you upgraded to the newest version. Anyways, without further ado: Download version 0.2 of django-yaba!

For more information on YaBa, please see the project page.

Saturday, July 04, 2009

Multiple Models, One Paginator

While working on YaBa, I found that I really needed a method to take items from multiple models, and paginate them as one major entity. In the case of YaBa I have galleries, articles, and the most common model of story/blog posts. Now, sure, there are likely a few different ways I could have gone about this. The easiest would have been to create a more general model, and used that for everything, however I wanted them to be separate. I wanted distinct articles and galleries that stood as their own entities when necessary, and didn't get clutterred up in the main feed. I need articles to be able to be buttonized on the main navigation bar, and I wanted galleries to be easily sortable in their own story list. All that being said, at times I needed them all to be very similar in structure, and to be able to be listed together in searches, archives, and the main page feed.

The three main protagonists in this story thus had to be built with similar traits in mind. They all had to be taggable, have slugs, tie to categories, and be searchable without offending the others. This obviously was pretty straight forward, not a big deal. Honestly, would have been a great place to leverage some inheritance really, but hindsight's 20/20 and apparently my foresight wasn't. Not a big deal, wouldn't have saved me all that many lines of code anyways. Besides, the problematic part was more in making these three different models merge into one entity, and still be usable in pagination scenarios (that ruled our itertools, which works great if you don't need pagination). I was very lucky to stumble upon the MultiQuerySet Snippet at Django Snippets. This incredibly helpful little snippet allowed me to chain multiple querysets into one larger queryset. Now I had the ability to merge my 3 querysets chock full of data into 1 master queryset to render to my templates in a paginated format. There was still one minor problem, MultiQuerySet doesn't do anything to help with the aspect of sorting.

By default, when using the MultiQuerySet snippet mentioned previously, all the items are sequentially thrown into the list, making your front page kind of strange. Visitors aren't very likely to want to push through ALL of your stories, and then ALL of your articles, just to see the newest gallery. If they are willing to do that, you have the best visitors ever, or you're running a self-help website for insomniacs with too much time on their hands. I had to find a crafty way to sort out the querysets into something more usable. Below is what I came up with:

def story_list(request):
stories = Story.objects.all().order_by('-created')
galleries = Gallery.objects.all().order_by('-created')
temp = MultiQuerySet(stories, galleries)
front_page = []
for x in temp:
front_page.append(x)

front_page.sort(key=sort_by_date, reverse=1)
paginator = Paginator(front_page, 5)
page = int(request.GET.get('page', '1'))
posts = paginator.page(page)

Currently on the front page, I don't list articles, but I do list both galleries and your more general blog posts. So, walking through this, let's start from the top. We grab all the stories and galleries, sorting them in the newest first, oldest at the back style. Then I create a MultiQuerySet objects in a temp variable that contains my two querysets. In return I get a nice queryset that I really can't do much with sorting wise, since it's not a "real" queryset, but it sort of is. The best way I found to handle the sorting action was to toss all the items into a list, and then use the built in Python list sorting functionality to sort it all out. As you can see I'm using a key function in the sort method of 'front_page'. That function's incredibly simple:

def sort_by_date(x):
return x.created

We're sorting by each item's created date asset that is in the list. After that we have a nicely sorted queryset like object, that for all intents and purposes at this point does exactly what we need it to do. We pass it off to the Paginator, let it do it's thing, and then I render it off to the template for the story_list function. Now I know, it doesn't look incredibly complex, and it actually is pretty easy. However, I hadn't really found anyone else mentioning a method of doing this, so I figured I'd share with the world how I went about it. I'm actually really interested in how anyone/everyone else is tackling a similar problem though, since I don't declare my method to be the best. It's just a means to an end I suppose. :)