Goodbye, old saddle

We had a lot of good times together, but I knew you were near the end when that rip started.

Tags:


Tweets for July 02, 2009

9:54 am
Ed McMahon, Farrah Fawcett, Michael Jackson, Fred Travalena, Karl Malden, and now Tuffy, our guinea pig.

10:02 am
Finally got around to fixing Dr. Twoot’s handling of newlines: http://xrl.us/bezg3b

2:55 pm
Just made a quick & dirty web page to show/distribute some photos to friends. No CSS, no JavaScript, just old-fashioned HTML via Markdown.

4:38 pm
Hey guys? It’s time to start fearing the reaper: http://xrl.us/bezjdq

4:42 pm
Alternate BOC tweet:

Therefore, send not to know For whom the cowbell tolls, It tolls for thee.

http://xrl.us/bezjdq

9:32 pm
I put my weather-getting script for GeekTool up on GitHub. http://xrl.us/bezkm5

This post was generated automatically using the script described here.


Tweets for July 01, 2009

6:28 am
There must be a bug in my calendar app—it’s showing no kids’ sports for the next few days.

9:05 am
Downloading updates to Tweetie and, at a whopping 533 MB, Myst.

This post was generated automatically using the script described here.


Iraq, June 2009

US military casualties in June were “normal,” so there was no movement to delay the redeployment of US troops from Iraq’s cities to military bases.

With the troops’ new role, maybe we’ll see another drop in the casualty rate.


iPhone Notes fonts again

In this post last week, I presented screenshots from my iPhone that showed the line-to-line spacing of certain fonts—Helvetica in particular—not matching the horizontal line spacing in the background image of the Notes app. Today, after reading this post by Beau Smith, I tried using Helvetica again, and this time it did line up. If I hadn’t taken those screenshots last week, I’d wonder if I had imagined everything.

So here’s today’s screenshot of a Note that’s written in Helvetica 16. I created it in Mail and synced it to my iPhone.

Similarly, here’s a note I made today in Mail using Georgia 16 and synced to my iPhone:

Obviously, in each case the line-spacing matches that of the background image—something that wasn’t true in the screenshots I took last week. Why the difference between then and now? Damned if I know, but I’m glad that Helvetica is now lining up for me, because that’s the font I really want to use in Notes.

For reasons explained in last week’s post, I’ve created in Mail a set of Blank notes1 that use Helvetica and synced them to my iPhone. To make a “new” note, I open one of the Blanks and edit it. The note stays in Helvetica, which is so much easier to read than Marker Felt.

There is, however, still some weirdness left in the Notes/Mail/font/sync system. I thought that changing the default Note font in Mail to Helvetica 16 would make it easier for me to make Blank notes.

Not so. Blank notes created with this default in Mail showed up in Marker Felt when synced to the iPhone. I had to set the Note font in Mail to something else—I capitulated to Apple’s desires and reverted to Marker Felt—and then change the font in each Blank note to Helvetica before syncing to get those notes to show up in Helvetica on the iPhone. After last week’s oddness, I have no confidence that this requirement is universal or even that it will still be a requirement for me next week; I’m just reporting what I see.


  1. The contents of each Blank note is just the word “Blank” on the top line. 


Tweets for June 29, 2009

10:29 am
Every once in a while I click on Trending Topics and come face to face with the unfiltered Internets. Scary.

5:38 pm
I’m just saying that people who’ve gotten on Paul McCartney’s bad side have been known to suffer untimely deaths.

5:40 pm
Sir Paul HATED Fred Travalena’s impression of him.

This post was generated automatically using the script described here.


Tweets for June 28, 2009

8:06 am
Picking up freebies at the Ricky Byrdsong Race Against Hate in Evanston while @JMoLawre runs the 10k.

1:27 pm
Very windy bike ride with @sorosweetie. Now over 850 miles for the year.

1:32 pm
How much would you expect to pay for this funeral?

1:35 pm
NOW how much would you expect to pay for this funeral?

10:44 pm
RT @chaptastic, @duncan, @kk: Holy crap! http://bit.ly/z6DK7 [It looks like the building fell over intact. Must be a foundation problem?]

10:46 pm
The classic video of James Brown, Michael Jackson, and Prince: http://xrl.us/beywhr

This post was generated automatically using the script described here.


JB, Michael, and Prince

For my money, this video is the reason YouTube exists. I thought of it when I heard of Michael Jackson’s death on Thursday, but didn’t have time to search for it until today.

Obviously shot in the mid-80s, the video raises several questions:

  1. What the hell was James Brown wearing? At times, it looks like a green house dress.
  2. What kind of cameraman fails to pull back at the first hint that Michael Jackson is going to dance?
  3. Did Prince ever get his jacket back? JB, like a dutiful mom, did his best to return it.
  4. And finally, you know you’re dealing with a weird group of people when James Brown is the most normal one onstage.

Tags:


Tweets for June 27, 2009

9:54 am
Excavating a broken gas line at the scene of a house fire. Pretty sure from the smell that one of the pets didn’t make it out of the house.

8:58 pm
NetNewsWire iPhone has been saying no updates all day long. Something must be wrong on the server end.

9:01 pm
The 12yo’s Little League season ended tonight with a tense 7-6 win just before the lightning started. Frosties all around!

This post was generated automatically using the script described here.


New weather script for GeekTool

I like having GeekTool display the current weather on my desktop, and I’ve written a script that gets the information from a NOAA website and formats it for GeekTool. Now there’s a new Python weather library, called pywapi, that simplifies the process of getting the data and extends it beyond just NOAA’s weather stations. I’ve rewritten my GeekTool script to use this new library.

The pywapi library is the creation of Eugene Kaznacheev. It provides a simple Pythonic interface to weather data supplied by

Google doesn’t have a weather page, per se, but it does provide weather info through an API. The Gismeteo service is in Russian, so I can’t give any advice on using it.

The current version of pywapi, version 0.2.0, has a bug that causes it to fail when accessing NOAA data. Fortunately, this bug is easy to fix before installation. I’ve described the bug and provided my fix on the pywapi Issues page—perhaps the fix will be rolled into the official pywapi distribution soon. Until then, follow these instructions to get a working version of pywapi:

Download the tarball to a convenient location and extract the code. Open the pywapi.py file and scroll to the bottom of the get_weather_from_noaa function. Change this code

for tag in data_structure:
    weather_data[tag] = current_observation.getElementsByTagName(tag)[0].firstChild.data

to this

for tag in data_structure:
    try:
        weather_data[tag] = current_observation.getElementsByTagName(tag)[0].firstChild.data
    except IndexError:
        pass

The original code only works if NOAA is returning every bit of information in the data_structure tuple. As it turns out, sometimes NOAA stations don’t report wind gust, wind chill, or heat index values. In those situations, the original code fails when the get_weather_from_noaa function is called. The revised code succeeds regardless of whether the data are reported or not.

After saving the edited file, execute

python setup.py build
sudo python setup.py install

from the command line, give your administrator password at the prompt, and the pywapi library will be installed in /Library/Python/2.5/site-packages directory.

To see what kind of data are available from the different services, open the examples directory in the pywapi distribution and try them out. Here’s pywapi-google-example.py, modified to return values for my town rather than New York:

1:  import pywapi
2:  import pprint
3:  pp = pprint.PrettyPrinter(indent=4)
4:  
5:  result = pywapi.get_weather_from_google('60566')
6:  pp.pprint(result)

The modification is on Line 5, where I’ve changed the argument to my zip code. The output looks like this

{   'current_conditions': {   'condition': u'Clear',
                              'humidity': u'Humidity: 29%',
                              'icon': u'/ig/images/weather/sunny.gif',
                              'temp_c': u'32',
                              'temp_f': u'89',
                              'wind_condition': u'Wind: SW at 3 mph'},
    'forecast_information': {   'city': u'Naperville, IL',
                                'current_date_time': u'2009-06-27 21:37:00 +0000',
                                'forecast_date': u'2009-06-27',
                                'latitude_e6': u'',
                                'longitude_e6': u'',
                                'postal_code': u'60566',
                                'unit_system': u'US'},
    'forecasts': [   {   'condition': u'Mostly Sunny',
                         'day_of_week': u'Sat',
                         'high': u'90',
                         'icon': u'/ig/images/weather/mostly_sunny.gif',
                         'low': u'65'},
                     {   'condition': u'Clear',
                         'day_of_week': u'Sun',
                         'high': u'83',
                         'icon': u'/ig/images/weather/sunny.gif',
                         'low': u'61'},
                     {   'condition': u'Thunderstorm',
                         'day_of_week': u'Mon',
                         'high': u'74',
                         'icon': u'/ig/images/weather/thunderstorm.gif',
                         'low': u'58'},
                     {   'condition': u'Mostly Sunny',
                         'day_of_week': u'Tue',
                         'high': u'74',
                         'icon': u'/ig/images/weather/mostly_sunny.gif',
                         'low': u'54'}]}

It’s a multi-level dictionary, from which you can pluck the current conditions and the forecast for the next few days.

Similarly, if I modify pywapi-yahoo-example.py to

1:  import pywapi
2:  import pprint
3:  pp = pprint.PrettyPrinter(indent=4)
4:  
5:  result = pywapi.get_weather_from_yahoo('60566', '')
6:  pp.pprint(result)

in which the arguments in Line 5 have been changed to my zip code and an empty string to give the Naperville results in US customary units. Running this example script yields

{   'astronomy': {'sunrise': u'5:20 am', 'sunset': u'8:32 pm'},
    'atmosphere': {   'humidity': u'40',
                      'pressure': u'29.78',
                      'rising': u'2',
                      'visibility': u'10'},
    'condition': {   'code': u'34',
                     'date': u'Sat, 27 Jun 2009 5:03 pm CDT',
                     'temp': u'90',
                     'text': u'Fair',
                     'title': u'Conditions for Naperville, IL at 5:03 pm CDT'},
    'forecasts': [   {   'code': u'47',
                         'date': u'27 Jun 2009',
                         'high': u'88',
                         'low': u'69',
                         'text': u'Scattered Thunderstorms'},
                     {   'code': u'24',
                         'date': u'28 Jun 2009',
                         'high': u'82',
                         'low': u'61',
                         'text': u'Sunny/Wind'}],
    'geo': {'lat': u'41.76', 'long': u'-88.15'},
    'html_description': u'\n<img src="http://l.yimg.com/a/i/us/we/52/34.gif"/><br />\n<b>Current Conditions:</b><br />\nFair, 90 F<BR />\n<BR /><b>Forecast:</b><BR />\nSat - Scattered Thunderstorms. High: 88 Low: 69<br />\nSun - Sunny/Wind. High: 82 Low: 61<br />\n<br />\n<a href="http://us.rd.yahoo.com/dailynews/rss/weather/Naperville__IL/*http://weather.yahoo.com/forecast/USIL0828_f.html">Full Forecast at Yahoo! Weather</a><BR/>\n(provided by The Weather Channel)<br/>\n',
    'link': u'http://us.rd.yahoo.com/dailynews/rss/weather/Naperville__IL/*http://weather.yahoo.com/forecast/60566_f.html',
    'location': {'city': u'Naperville', 'country': u'US', 'region': u'IL'},
    'title': u'Yahoo! Weather - Naperville, IL',
    'units': {   'distance': u'mi',
                 'pressure': u'in',
                 'speed': u'mph',
                 'temperature': u'F'},
    'wind': {'chill': u'90', 'direction': u'180', 'speed': u'14'}}

which is another multi-level dictionary with similar information. Yahoo! gives sunrise and sunset times, which Google doesn’t, but Yahoo’s forecasts only include today and tomorrow.

Here’s pywapi-noaa-example.py after my modification:

1:  import pywapi
2:  import pprint
3:  pp = pprint.PrettyPrinter(indent=4)
4:  
5:  result = pywapi.get_weather_from_noaa('KARR')
6:  pp.pprint(result)

The argument in Line 5 is the code for the NOAA station at the Aurora airport west of Naperville. Finding the best NOAA station isn’t as easy as just entering your zip code, but if you go to this NOAA page, you can find it pretty quickly.

The output from pywapi-noaa-example.py is

{   'dewpoint_c': u'20.6',
    'dewpoint_f': u'69.1',
    'dewpoint_string': u'69.1 F (20.6 C)',
    'latitude': u'41.77',
    'location': u'Aurora Municipal Airport, IL',
    'longitude': u'-88.47',
    'ob_url': u'http://www.nws.noaa.gov/data/METAR/KARR.1.txt',
    'observation_time': u'Last Updated on Jun 27 2009, 8:52 pm CDT',
    'observation_time_rfc822': u'Sat, 27 Jun 2009 20:52:00 -0500',
    'pressure_in': u'29.77',
    'pressure_mb': u'1007.6',
    'pressure_string': u'1007.6 mb',
    'relative_humidity': u'87',
    'station_id': u'KARR',
    'suggested_pickup': u'15 minutes after the hour',
    'suggested_pickup_period': u'60',
    'temp_c': u'22.8',
    'temp_f': u'73.0',
    'temperature_string': u'73.0 F (22.8 C)',
    'two_day_history_url': u'http://www.weather.gov/data/obhistory/KARR.html',
    'weather': u'Thunderstorm in Vicinity Light Rain Fog/Mist',
    'wind_degrees': u'220',
    'wind_dir': u'Southwest',
    'wind_gust_mph': u'18.4',
    'wind_mph': u'10.4',
    'wind_string': u'from the Southwest at 10.4 gusting to 18.4 MPH (9 gusting to 16 KT)'}

which is a simple dictionary with only current conditions, no forecasts. Still, I like the NOAA data set because it includes, when appropriate, the wind gust speed and heat index, items that neither Google nor Yahoo! provide.

So here’s my new GeekTool weather script, called weathertext:

 1:  #!/usr/bin/python
 2:  
 3:  import pywapi
 4:  
 5:  # Get the current conditions for the given station.
 6:  noaa = pywapi.get_weather_from_noaa('KARR')
 7:  
 8:  # This is the list of output lines.
 9:  out = []
10:  
11:  # Go through the dictionary and construct a list of the desired output lines.
12:  out.append('Last update:' + noaa['observation_time'].split(',')[1])
13:  try:
14:    gust = ', gusting to %s mph' % noaa['wind_gust_mph']
15:  except KeyError:
16:    gust = ''
17:  out.append('Wind: %s at %s mph%s' % ( noaa['wind_dir'], noaa['wind_mph'], gust))
18:  out.append('Relative Humidity: %s%%' % noaa['relative_humidity'])
19:  try:
20:    out.append('Wind Chill: %s F' % noaa['windchill_f'])
21:  except KeyError:
22:    pass
23:  try:
24:    out.append('Heat Index: %s F' % noaa['heat_index_f'])
25:  except KeyError:
26:    pass
27:  out.append('Temperature: %s F' % noaa['temp_f'])
28:  
29:  # Sometimes there's no heat index or windchill value (there should never be
30:  # both). If that's the case, add a blank line to the beginning so the output
31:  # is always 5 lines.
32:  
33:  if len(out) < 5:
34:    out.insert(0, '')
35:  
36:  print '\n'.join(out)

At the moment, it’s basically a rewrite of my previous GeekTool weather script, using the clean pywapi calls instead of a kludgy series of regular expressions to pull the desired information out of the NOAA results. I’ll probably add to it, gathering bits from the Google or Yahoo! results and mixing them into the output. I have GeekTool set up to display the output of weathertext—which I’ve made executable and keep in a “bin” directory in my home folder—in the lower left corner of my screen.

I have the temperature at the bottom because it’s the most important item and putting it at the bottom makes it the most likely to be visible.

Update 7/2/09
I’ve made some minor changes to weathertext since writing this post. Rather than updating the post every time I make a change, I’ve set up a GitHub repository where you can always download my latest version.

Tags: