Hours of Operation
Dec 16th, 2008

As you probably know, I've been working on a Django-based re-build of BostonChefs.com (the new version of which is actually live now, but due to DNS propagation issues isn't yet available to 100% of people which is why I haven't yet written a post about it). Among other things, BostonChefs.com provides information on some of the fantastic restaurants in the Boston area. One piece of information it provides is the hours of operation of those restaurants. In order to store this information I created a model called HoursOfOperation. It looks like this:

class HoursOfOperation(models.Model):
DAY_CHOICES = (
('0', 'Sun'),
('1', 'Mon'),
('2', 'Tue'),
('3', 'Wed'),
('4', 'Thur'),
('5', 'Fri'),
('6', 'Sat'),
)
restaurant = models.ForeignKey("Restaurant")
meal_period = models.ForeignKey("MealPeriod")
day = models.CharField(max_length=3, choices=DAY_CHOICES)
open_time = models.TimeField(default=datetime.datetime.now)
close_time = models.TimeField(default=datetime.datetime.now)

def _get_hours(self):
return "%s - %s" % (self.open_time.strftime('%I:%M%p'), self.close_time.strftime('%I:%M %p'))
hours = property(_get_hours)

As you can see, each 'hour' is related to a restaurant and a meal period, which allows us to display the information in a manner similar to that you might find on a store's front sign. For example, if you go to the Grill 23 & Bar page (my personal favorite restaurant in Boston, although Craigie on Main is a decent challenger), you'll see something like this:

DINNER
* Sun: 5:30 p.m.-10 p.m.
* Mon-Thur: 5:30 p.m.-10:30 p.m.
* Fri: 5:30 p.m.-11 p.m.
* Sat: 5 p.m.-11 p.m.

Building a list like that out of the above model proved slightly more difficult that I might have hoped. It required quite a lot of template logic, including writing a custom filter. The block of template code necessary to generate that list looks like this:

<div class="hours">
{% regroup restaurant.hoursofoperation_set.all by meal_period as periods %}
{% for period in periods %}
<div class="hoursMealPeriod">{{ period.grouper }}</div>
{% regroup period.list by hours as hour_list %}
<ul>
{% for hour in hour_list %}
<li>{{ hour.list|collapsedays }}</li>
{% endfor %}
</ul>
{% endfor %}
</div>

As you can see, somewhat complex. Those nested {% regroup %}s can be nasty to wrap your head around, if nothing else. But basically it's taking the set of HoursOfOperation objects related to the restaurant, grouping them by meal period, then taking the subset of those objects for each meal period, and grouping those by the hours of the day they represent. So what you're then left with is a list of all the different time periods (still represented as HoursOfOperation objects) that the restaurant is open for a given meal period, and the days on which it is open during those hours. As you can see above, the days are represented by number of the day of the week (0 for Sunday through 6 for Saturday).

Converting that list integers into something like 'Mon, Wed-Fri' was not very easy, and certainly not something I wanted to try to tackle using Django's template tags. I ended up drawing heavily on my hazy memories of CS 127 (many thanks to Dave who taught me all about recursion way back then) and creating a filter that considers the list of HoursOfOperation objects as a list of those integers, then recursively converts it into a list of lists representing the subsets of contiguous days in the list. So if you start out with [1, 3, 4, 5] you end up with [[1, 1], [3, 5]] which is then converted into 'Mon, Wed-Fri'. After several false starts I ended up with this beauty of a Django template filter:

from django.template import Library
from django.template.defaultfilters import time

from types import ListType

register = Library()

def simplify(index, found, days):
high = index+1
mid = index
low = index-1
if not found:
days[low] = [days[low], days[low]]
if high >= len(days):
if not isinstance(days[-1], ListType):
if days[-1] == days[-2][1]:
days.pop(-1)
else:
days[-1] = [days[-1], days[-1]]
return days
if int(days[high].day) - int(days[mid].day) == 1 and (found or int(days[mid].day) - int(days[low][0].day) == 1):
days[low][1] = days[high]
days.pop(mid)
high = high-1
found = True
else:
if found:
days.pop(mid)
found = False
return simplify(high, found, days)

@register.filter
def collapsedays(value):
hours = "%s-%s" % (time(value[0].open_time), time(value[0].close_time))
days = simplify(1, False, value)
for i in range(len(days)):
if days[i][0] == days[i][1]:
days[i] = days[i][0].get_day_display()
else:
days[i] = "%s-%s" % (days[i][0].get_day_display(),
days[i][1].get_day_display())
return "%s: %s" % (', '.join(days), hours)


The world's best hot dog
Nov 10th, 2008


Well, I just got back from Iceland on Saturday. It was a great trip, and I'm definitely planning on returning in the not so distant future with Jessi. As promised I kept a photo blog with my iPhone, still available here: http://gallery.me.com/josh.ourisman#100051. Unfortunately, even though I was able to get WiFi nearly everywhere, for most of the trip I had trouble sending emails, so I didn't take as many pictures as I otherwise would have on my iPhone. I do have a ton on my camera, however, and I'll be putting those online soon.

Our trip was definitely an interesting one. It was put on by Abercrombie & Kent, a luxury tour company, for a handful of travel agents such as my dad and a few other professionals in the travel industry. The flight over was on A&K;'s private jet, a 757 leased from Icelandair and fitted out for total luxury. It seats, I believe, about 50 passengers, and has a lounge area where we were served a fantastic dinner consisting of caviar served in the Russian style followed by our choice of lamb, red snapper, or, I think, chicken. Needless to say, this was not your typical airplane dinner. Nor, unfortunately, is it anything that I'm likely to experience again anytime soon.

After landing we, along with two A&K; guides, were handed off into the capable hands of Luxury Adventures who spent the week taking us on a whirlwind tour of all the attractions that Iceland has to offer around Reykjavik including the Hellisheiði Geothermal Plant, the Blue Lagoon, the Eyjafjallajökull glacier, the Geysir geyser (the root of the word geyser), the East-Ranga river (purportedly one of the best salmon rivers in the world), the site of the first Icelandic parliament (from around 972 C.E. or so), and a dizzying array of other beautiful and amazing sites which I'll try and post more specifically about once I get the pictures off my camera.

I also got to check off an item that has been near the top of my to do list for years: eat whale. While at the Hotel Ranga we had a fantastic dinner in which I got to sample not only whale, but also puffin (which tastes, unsurprisingly, a lot like duck) and reindeer (which also unsurprisingly tastes a lot like regular venison). I did not, unfortunately, get to check off the other food item that I was hoping to while in Iceland: kæstur hákarl, though I plan to on a future trip.

Anyway, on to the hot dog.

It turns out that Reykjavik is home to the world's best hot dog in the form of Bæjarins beztu pylsur (which translates as 'best hot dog in town'). It's a small stand on Pósthússtræti, which just so happens to be the same street as the hotel we were staying at: the Hótel Borg. I had mine 'ein með öllu' (with everything), at the suggestion of a friend of mine from Reykjavik, and it was truly fantastic. Apparently the hot dogs in Iceland are mostly made of lamb, but also with some pork in them. It was absolutely delicious, and quite affordable at only 250 króna which, last week, was about $2, though this week is about $1.

Which brings me nicely to my next topic: the exchange rate. This past week, it was about 125 króna to the dollar. However today the króna was put back on the international currency market at a reduced value and is currently at 225 króna to the dollar. As a result, Jessi and I are seriously considering going back for a long weekend this coming weekend. Thanks to Icelandair's vacation packages it would only cost $799 per person for two round trip tickets and two nights at a hotel in Reykjavik, and only another $55 per night to extend the trip. It's kinda hard to turn that sort of deal down, especially for a trip to a place as amazing as Iceland. They have a number of other packages as well, and I'm looking forward to taking advantage of them for both a winter trip to experience the darkness of arctic winter, and spring and/or summer trips for some hiking and backpacking across volcanic plains and glaciers.

Long story short: I love Iceland. I don't think a single day went by when we discovered some new thing about the island nation that inspired me to declare my intention of moving there. However by far one of my favorite things about the country has nothing to do tourism or even really our trip at all. While we were driving around the country side we saw tons and tons of what we were told were summer homes. When we asked what Icelanders do in their summer homes the answer was: read. Apparently Icelanders are amongst the most prolific readers in the world and, as evidence, there is a three story bookstore on Austurstræti (I think I spelled that right) in Reykjavik that was open, and filled with people sitting down reading, well after all the other shops had closed up for the night (6pm on non-summer weekdays). If you've been reading my blog for a while you might know that I find the US' abysmally low level of reading to be be very depressing, and the idea of a country where the national pastime appears to be reading is quite appealing to me.