French American

04 Feb 2010, comments

I know I'm French because I:

  1. prefer living in France
  2. love French food
  3. prefer American television to French television
  4. love socialized medicine
  5. no longer care that Carrefour is closed on Sundays

I know I'm still American because I:

  1. find it easier to do business with Americans
  2. miss unsweetened Cheerios, bagels, and spicy food
  3. watch my American television in English
  4. wish it weren't illegal for French doctors and dentists to advertise that they speak English
  5. am not afraid to shop online

It's my impression that many are disappointed by the iPad. I think this is because, as digital professionals, we were hoping for something we could use as we perform our craft. Something that would let us leave our laptops at home. Sorry, but we're not Apple's target demographic.

In my analysis I'm going to divide all computer usage into two categories: production (of media) vs consumption (of media). We're producers -- and Apple sees a much bigger market among the consumers.

As a device for media production, the iPhone can claim points for producing tweets, and photo streams for flickr, and a few fingerpaintings, but that's about it -- in my production/consumption dichotomy for digital media, smartphones sit heavily on the consumption side of the fence (but aren't very good at it, really). Furthermore, the market for digital consumption is only getting started. Devices like the Kindle, Apple TV, and digital picture frames are still niche products; most of us buy printed books and magazines, and print our pictures on paper when we want to frame them.

Truth be told, many home laptops and desktop computers also sit heavily on the consumption side of the fence. That's why I think the potential for the iPad is very large. If the iPad can provide the best available experience for online media consumption, and I'm prepared to think it can, then how can it fail to do well?

On the other hand, whether or not the iPad will prove to be a compelling tool for media creation is an open and fascinating question. I predict success for working with photos and photo collections, playing with and performing music, and hopefully drawing. I also imagine we will find ways to repurpose the iPad (and its descendants) as an interesting input device to "real" computers. But I don't expect to need one for my work as a software developer any time soon (unless I decide to write iPad software, of course).

Before closing I have to mention that the way that Apple has positioned itself as a tollkeeper, charging for access to this media, and censoring content that harms its business model, is certainly annoying. I would really love to see someone rise up and offer compelling alternatives to the iPhone and iPad, but so far (and I speak as an Android phone owner) I am disappointed. As a potential application developer, fixing the problems in Android is beyond the scope of what I can do for my users. Google just doesn't seem to understand what's required to provide the same quality of experience that Apple gives its users. Must the freedom Google offers come at such a price?

Painless pain

28 Jan 2010, comments

I finally got around to trying the recipe for no-knead bread that Mark Bittman evangelized more than three years ago in the New York Times and on Youtube. This really is a remarkably painless way to make bread at home.

I did learn a few things in the process. The dough was a gooey blob after the first rise; there was no "seam side" after the folding. In fact, it's a stretch to call what I did folding, but I worked the dough for a minute. And the second "rise" was more of a "spreading out". None of this seem to matter though, as the bread turned out great. It did make a mess on the towel I put over it while rising, so next time I'll probably use a bit less water, and try to find some cornmeal or wheat bran to put on the blob before covering with the towel. Dusting it with flour was a bit of a mistake, since the flour absorbed the liquid and then the blob stuck to the towel, significantly reducing the size of the final loaf. I'll also use a bit more salt next time -- maybe I'll even measure the salt next time. And I was slightly worried, as we don't have a dutch oven or large enough covered pyrex casserole dish, but covering our large pyrex mixing bowl with aluminum foil worked fine.

I used pain de campagne flour, which is a mix of wheat and rye used in making rustic, country style bread here in France. It was a good choice; the results were everything I'd hoped for. Total effort was about half an hour (spread over 18 hours), but it will probably only take half of that the next time.

Recently I've been doing some work for neo.org, an NGO and social network based in Switzerland. During the past month I've integrated Twitter (authentication, direct messages, updates) and Paypal (purchasing) into this Ruby-on-Rails-based site, and looking back, I realize that I enjoyed one of these integration projects -- and not the other. Both projects were about the same amount of work, and required me to write similar amounts of code. I've been trying to figure out why working with Paypal was frustrating for me, while working with Twitter was fun.

Was it library/gem support? No, not really. Both twitter and paypal are widely used by rails sites, so it wasn't hard to find decent gems. I used the twitter and activemerchant gems, and both served me well.

Documentation? Yeah, this was a big part of the problem.

With twitter, I did spend some time reading out-of-date blog posts, but once I found that the latest versions of the twitter gem support twitter auth, I realized this gem was going to make my life as easy as I could expect it to be, and decided not to bother with the TwitterAuth gem (though I did find several bloggers recommending it). The sample twitter-app was a big help in understanding exactly how the pieces fit together. This meant that early on, I had a pretty clear idea of exactly what I was going to need to do. Moreover, twitter.com has great documentation. Pleasant to read, well organized, gets to the point.

For the Paypal integration, I quickly found Using Paypal with Rails, which was tremendously helpful. But I also found plenty of contradictory advice, some recommending Spree (a layer on top of ActiveMerchant), and a pretty strong recommendation from Cody Fauser for using PayPal Express, rather than the PayPal Website Payments Standard. After a fair bit of reading, I concluded that Spree is complex, imperfect, and wouldn't make my life any easier. I also concluded that using PayPal Express wasn't worth the extra effort required, given neo.org's simple requirements. But when it came to actually getting the work done, I found it very difficult to find answers to specific questions -- because Paypal's documentation is rather poor. They have a maze of similar products and protocols, and it is painful to get a clear overall picture of what's going on. I finally found this forum article buried away somewhere that clearly explains the various options available for getting back the financial transaction data, and I sorted out for myself why, when the user comes back to your site, the return or finalize action is sometimes called with a GET, and other times with a POST ... but it didn't make me happy. And none of the documentation I read makes the rather obvious point (in hindsight) that your testing has to be done from a publicly accessible server for Paypal's server to be able to POST back to you.

It's also worth noting that testing was more straightforward with Twitter than with Paypal, and the transition from development to production was also easier.

Although Paypal's poor documentation was a key factor in my dissatisfaction, I think the root cause of the problem is simply the complexity of Paypal's offerings. This makes it difficult to have good documentation, and makes it hard for newcomers to get oriented. The tools and backend admin interfaces are initially somewhat overwhelming, and after 3 days of use, not my friend. Somehow my test store got destroyed at one point; I have no idea what I did wrong. And several times I got mysterious errors while using their sandbox website (not errors from my client code, just errors from my manual interactions with the admin interfaces). In the end, everything seems to work fine, but ... I work with Ruby and Rails because they give me pleasure, and the tools are rich enough that it's possible to create things that are beautiful.

Paypal isn't beautiful. Twitter's okay. Fun integration projects bring more beauty into your life.

Link Roundup

07 Jan 2010, comments

Here are several items I found truly worthwhile, but none of them are going to elicit a post's worth of commentary from me.

iTunes is one of those pieces of software with which I have a love/hate relationship. I thought maybe I was the only one who cares that its podcast support sucks, but now I know I'm not alone. Paul Kedrosky tapped into my anger when he wrote Apple’s iTunes is Mrs. Amel.

On Christmas day Amazon's customers bought more e-books than printed books. Maybe that's not very significant, or maybe it's the beginning of a sea change.

On a related note, Seth Godin succinctly explains that bookstores are dead in It's not the rats you need to worry about.

And while I'm on Seth Godin, he really made me think with Fallback for the 2%, where he makes the point that no matter how clear your UI is, 2% of your users are going to screw up. So you either care enough to give them a way to recover (which can be a lot of work), or you accept that these customers are lost to you, forever (which obviously sucks).

If you are interested in what many observers would like to characterize as a battle between the iPhone and Android, you need to read Android Or IPhone? Wrong Question. It does indeed appear that Android is becoming the Microsoft Windows of the smartphone market. Sigh. How do I feel about my Android phone (I have an HTC Hero)? That's a subject for another post, someday. (It's another case of love/hate.)

Another subject where I could probably go on and on, but won't, is health care reform in the US. Instead, study this chart from National Geographic and this clearer one from fivethirtyeight.com. And then if you want to be able to laugh about the whole mess, watch this brilliant video: If Air Travel Worked Like Health Care.

Lime Ice Cream

04 Jan 2010, comments

For readers expecting some ruby or rails content, don't worry, I'm not turning this into a food blog. But over the holidays, my thoughts do turn to food.

We had some limes leftover from making Sweet Potato Salad (always spectacular) and Pad Thai (it was good, but we've yet to figure out how to nail this dish), and so yesterday Erin and I decided to experiment with making some lime ice cream. It was a first rate success!

At the outset we weren't sure if a citrus-based ice cream would work. Emily and Erin hadn't had much luck with their experiment making blood orange ice cream, so Erin searched on epicurious.com for evidence of frozen creamy lime deliciousness. She did indeed find a highly rated recipe, but we didn't care for the look of it -- it was one of those 6-egg-yolks-cooked-into-a-custard affairs. I'm sure it would've been good, but we were looking for something easier, and less heart-stopping. I'm not sure where my prized photocopy of Ben & Jerry's Ice Cream recipe book ended up after our last move, but I found their basic no-cook french vanilla recipe online with a couple of minutes of googling, and we modified it as follows (taking some quantity cues from the epicurious recipe).

1 C sugar
~1/2 C lime juice (the juice of 3 limes)
2 eggs
3 C thick, light cream (12% fat, comparable to half-and-half)
zest from one lime (optional)

We made a syrup using half the sugar and all of the lime juice. You want to cook this until the sugar is fully dissolved, then bring it to a boil, stirring frequently. After it boils for a few minutes it should be a sort of pale golden color. Then while the syrup cools a bit, whisk the 2 eggs for 1-2 minutes, until they become light and fluffy. Whisking constantly, slowly blend in the remaining half a cup of sugar. Then add the half-and-half (or cream or milk, or whatever dairy product you've chosen).

We included the zest from one of the limes, which looked and tasted great, but we did end up with a few chewy bits of lime peel that some might find objectionable, texturewise. The epicurious recipe proposes straining out the zest after steeping it in the cream for a while, but that's incompatible with our keep-it-simple-stupid philosophy here at alpinegizmo, so I say either include the zest, or not, but don't make things complicated.

At this point we were concerned that the acid in the lime syrup might curdle the milk, so we did a small scale experiment, which tasted great. So we slowly drizzled the still-rather-hot syrup into the egg/cream mixture, whisking as we went. And then we proceeded to freeze the ice cream, using our usual process. About 3 hours later, we were happily feasting on our first batch of lime ice cream -- which I'm sure won't be the last.

Making pancakes on Sunday morning has been my tradition ever since I left home more than 30 years ago. I fairly quickly settled on this recipe, which I'm sure I've made more than 1000 times by now. I had the pleasure of making a batch of pancakes for our friends Jim and Claudia this morning, and Claudia's parents who are visiting from Germany. Since they asked for the recipe, it seems like time to share.

First mix together the dry ingredients:

3 T sugar  
1.5 cups of white flour  
1/2 t baking powder  
3/4 t baking soda  
1/2 t salt

then add the wet ingredients:

3 T vegetable oil  
1 egg  
2 cups buttermilk  

Use a whisk to combine the wet and dry ingredients. Do not over work the batter. A few lumps won't matter, they will disappear during cooking. I find it is easier to get everything mixed nicely if I use only about 3/4 of the buttermilk at first, and then I add the rest until the consistency is just right.

In some places, like here in Quinson, buttermilk (lait fermenté) can be difficult to find (don't try to use lait caillé, I made that mistake once, it's way too thick). Satisfactory results can be obtained using runny yogurt, probably thinned with some milk to get the right consistency. Or you can curdle milk by adding some vinegar. But it is important to use some sort of sour or fermented milk product. The combination of the acid and the baking soda gives you the nice fluffy bubbles you want.

The temperature of the pan is quite important. You want it reasonably hot, and evenly hot. A cast iron pan or griddle, or a teflon coated crepe pan works well. Pour some batter in the center of the pan, and spread it out so it's not too thick. Cook on one side until the bubbles are popping and staying open afterward, then flip over and cook on the other side (not very long). With a teflon pan no oil or fat is needed for cooking. In a cast iron pan I use a thin coating of vegetable oil. While it is often said that you should plan to throw away the first pancake, these mistakes come from either having too much oil or fat in the pan at first, or having the pan too hot or too cold. With enough experience you can avoid these mistakes.

This will make about a dozen full-sized pancakes. Stretching the recipe is a bit of an art -- doubling works well enough, but in-between quantities using 2 or 2.5 cups of flour are tricky, because you basically have to use either one egg, or two. One egg will stretch out to handle 2 cups of flour well enough -- beyond that, use 2 eggs and scale the other ingredients accordingly.

Serve hot, with butter and real maple syrup, or honey, or jam or compote. (Fake pancake syrup is an abomination.) If you heat the toppings, that's really nice.

Update:

How could I have forgotten to mention variations? Blueberries are my favorite -- just throw some in each pancake after pouring out the batter in the pan. Some mushed banana or applesauce can be added to the batter itself -- with applesauce, reduce the milk somewhat, and be careful because applesauce will cause the pancakes to lose some of their structural integrity and they'll be difficult to cook through. Chocolate chips? No, I don't do that.

Or you can replace half a cup of the white flour (or more, up to a cup) with whole wheat flour, or buckwheat flour, or corn meal.

kickbike at the alster

After almost exactly a year, my time in Hamburg is at an end. I'll miss many things here -- pretty good Mexican food, really good Thai food, and the great bunch of Ruby developers at Xing.

This afternoon the weather was great and I decided to take one last ride around the Alster on my kickbike, which you can see above.

When friends see my scooter for the first time, they often look a bit puzzled and ask "Why?". Here are some reasons why I like this better than a bicycle:

  • After a long ride, my muscles are sore, but my joints are fine, nothing is numb, and my butt isn't sore. I have arthritis in my left foot, and for the past couple of years, long walks would result in days of pain. At first I was concerned that propelling myself on the kickbike would also hurt my foot, but on the contrary, it seems to have helped. My theory is that I've strengthened the muscles in my foot by using it this way; all I know for sure is that my foot doesn't hurt any more.
  • It works more of my body: not just my legs, but also the lower back, lower abs, and even the arms a bit.
  • It's simpler, lighter, and cheaper than a comparable bicycle. No pedals, greasy chain, or derailleur to deal with.
  • Because I can readily put my feet on the ground, I feel it's a bit safer when riding in a densely pedestrian urban environment.
  • And it's fun.

On my way home, I stopped at Qrito for one last burrito.

Just brilliant

31 Mar 2009, comments

Another brilliant list from McSweeney's: Email addresses it would be really annoying to give out over the phone.

Wow

24 Mar 2009, comments

With some of these youtube videos, even if parts are fake (and I have no reason to think this isn't legit), enormous imagination and effort were required. This video gets the alpinegizmo seal of approval.

Kings

23 Mar 2009, comments

If you want one new show to watch now that Battlestar Galactica has ended, make it NBC's new show, Kings. I haven't been this excited by imaginative television in years. In the US you can catch it on hulu. The ratings weren't good, by the way, so let's all cross our fingers and hope NBC gives this show a chance to breathe.

If you prefer to wait and watch a whole season of something at once, take a look at the first season of Damages, also on hulu. Both Glenn Close and Ted Danson play characters who will stop at nothing to get what they want -- and of course they are in conflict, and can't both win. Ted Danson is driven by greed and ambition; Glenn Close wants to bring justice to those ruined by Ted Danson. She's on the good side of this battle, but she's got more darkness in her than a black hole. And I've left out the appealing main character -- Glenn Close's young associate -- will she succumb and become just as twisted as her mentor?

[Part of the Rails on XML series.]

An essential part of working with XML and Ruby is being able to serialize ruby objects to XML. There are several approaches out there for doing this; the one that appeals to me most is the one implemented by Rails in ActiveSupport. It provides a nice to_xml method for your ActiveRecord objects, and deals with arrays and hashes that contain ActiveRecord models. For example, here's what you might get from a really simple blog engine in response to Page.find(:first).to_xml:

<?xml version="1.0" encoding="UTF-8"?>
<page>
  <allow-comments type="boolean" nil="true"></allow-comments>
  <body>blah blah blah</body>
  <id type="integer">1</id>
  <title>my first post</title>
  <created-at type="datetime">2008-01-08T17:52:54+01:00</created-at>
  <updated-at type="datetime">2008-11-26T17:01:51+01:00</updated-at>
  <user-id type="integer">1</user-id>
</page>

There may be more information here than we will need for XSLT rendering (eg it probably doesn't matter that id is an integer), but I like the thoroughness of this approach, and the way they handle arrays and hashes is quite nice.

For our purposes we need to be able to serialize to XML anything we might put in a controller instance variable. The xml_serialization gem adds support for integers, symbols, and strings, and arrays and hashes that contain them.

For example, {:numbers => [1, 2], :strings => ['one', 'two']}.to_xml

<?xml version="1.0" encoding="UTF-8"?>
<hash>
  <numbers type="array">
    <number>1</number>
    <number>2</number>
  </numbers>
  <strings type="array">
    <string>one</string>
    <string>two</string>
  </strings>
</hash>

We also cover the important case where you already have XML (eg from a database or web service) that you want to pass through unmolested.

@data = RawXML.new '<tag>content</tag>'

In this case, @data.to_xml returns the same string that went in, i.e. '<tag>content</tag>'.

[Part of the Rails on XML series.]

I am pleased to report that Mirai España has agreed to release as free software the code we wrote for using XSLT views in Ruby on Rails applications. I have packaged this software as two separate components: the xml_serialization gem for serializing ruby objects to XML, and the xslt_render rails plugin.

At this point documentation is lacking. However, there isn't that much code and the tests do illustrate how the pieces are intended to be used, so the adventurous might be able to drop this into an app and get it working. I do plan future posts that will explain more of the details, which I'm sure will help. However, I know a few of you are interested in seeing the code now, so I don't want to delay in releasing it.

Europeans often ask me why I moved to Europe (interestingly enough, I can't recall an American ever asking me this). One reason was to escape from the magical thinking so many Americans engage in. And which groups are most likely to need escaping from? Pew has prepared this handy chart.

relgionpew.png

This week I was noticing one of those small, but possibly revealing cultural differences between France and the US. It has to do with what doctors wear at work. I was having a routine examination done, and the specialist I was there to see -- male, mid-40s -- was wearing jeans and a long-sleeved fantasy sport league polo shirt. No white lab coat or stethoscope or any other of the traditional trappings of the medical profession (traditional, that is, from an American perspective). At first when I saw him coming and going about the office, I wasn't sure if he was the doctor, or a technician there to repair something. If I wasn't used to the fact that french physicians dress extremely casually, it never would've even occurred to me that he could be the doctor.

I'm not complaining, mind you. Just curious about what else might be different, but less obvious.

2008 in figures

24 Jan 2009, comments

  • Weeks at home: 30
  • Country points: 4
  • Airline flights: 36
  • Photos: 3222

Countries visited for the first time: Portugal, Russia, Latvia, Lithuania

Flight departures: Marseille (12), Madrid (11), Lyon (2), Hamburg (2), Nice (2), Riga (2), Amsterdam(1), Berlin (1), Paris (1), Porto (1), St Petersburg (1)

Note for travelers: calling 112 in Portugal is not guaranteed to get you someone who speaks English.

No ID required

23 Jan 2009, comments

Today is a travel day for me, and I'm writing these posts while sitting in various airport terminals. First Hamburg, and now Frankfurt. What I find rather odd is that it is possible to travel within Europe without ever showing any ID. I used my credit card to get my boarding pass, and I showed the boarding pass at security and at the gate. At the gate there wasn't even a person involved, just a barcode scanner.

Yesterday I decided it would be a good idea to modify the installation of mysql that I use on my laptop so that the data on the disk is encrypted. With google I found a few people looking for help with this, but no solutions, so I'll share what I figured out.

First some configuration details. I'm running mysql 5.0 on a macbook pro with leopard (OS X 10.5.6). I'm pretty sure the same approach I'm using will work across any similar setup, but your mileage may vary. Also, I installed mysql from mysql.com, but you should be able to easily adapt this technique to work with the version from macports.

After shutting down the mysql server, the first thing I did was to create an encrypted sparse disk image (using disk utility), move /usr/local/mysql/data to the new disk image, and create a symbolic link from /usr/local/mysql/data to the new, encrypted location. I expected that to pretty much take care of it (and if it had, I wouldn't be blogging about it). When I looked at why mysql would no longer start up, I found that the wrong user now owned the data files -- I owned everything, instead of the mysql user. Nothing chown can't fix, right? Wrong.

Turns out that the files and directories in mounted disk images are owned by whoever mounts them -- the ownership information stored in the filesystem within the disk image is ignored. Yikes! Fortunately, this is merely the default behavior, and can be switched off. If you bring up a mounted disk image in the finder's get info window, at the very bottom, inside the "Sharing & Permissions" section, you will find a checkbox labeled "Ignore ownership on this volume". It is checked by default; you want to turn this off.

You will notice that I gave everyone read and write permission to this volume. I'm not super happy about this, but so far I haven't found any other way to allow the mysql user to be able to reach inside and do what it needs to do. Of course, what this volume contains is a data directory that only the mysql user is able to access, so I don't feel too bad. Nevertheless, if someone finds a solution to this, let me know, ok?

The other problem I've found comes up when I want to unmount the mysql data disk image. I usually find the finder telling me I can't eject this volume because it is still in use. In these cases lsof is my friend, as in "lsof /Volumes/mysql-data". And the culprit is usually mds, aka spotlight. You can stop this by going into System Preferences > Spotlight > Privacy and adding the encrypted disk image volume to the list of things spotlight should not index. Unfortunately it seems that this preference is not sufficiently persistent -- I keep having to re-set it -- so I may resort to disabling spotlight entirely, or try spotless.

Of course, it is also necessary to mount the encrypted disk image before starting mysql, and to stop mysql before unmounting it. Kudos to anyone who goes to the trouble of cleanly automating these steps.

[Part of the Rails on XML series.]

Two really nice things flow from using XSLT for the views in the way I described last time, in Part 4.

First is that you get partials for free. To understand why this is so, you need to understand a little about how the XSLT language works. When you are writing a view in XSLT, you are describing a transformation from XML to HTML. You are saying, when you see this in the XML coming in, produce that in the HTML coming out. This means that setting up a controller action to re-render part of a page is staggeringly simple. All you have to do is provide a subset of the XML used to render the full page, and only the relevant portion of the HTML will be generated. You can use exactly the same XSLT view for both the full page and the partial.

The second thing you get is a much cleaner separation between your controllers and your views. Everything the views need will be, and must be, provided in the XML. And given the rendering pipeline we established, that means everything will come from the controller instance variables. Of course most everything in normal rails views comes from controller instance variables too, but it always possible to do something dirty in an rhtml view, like reach around to the models and include a bunch of business logic in your view. Since we have no ruby code in our views, these cheats are simply impossible. That may seem like a limitation, but it can be liberating to be able to say that there is a contract between the backend team and the frontend team whereby the backend team will produce XML that contains everything that’s needed, and the frontend team will produce HTML from that XML. We found it was a good thing to have a real boundary there.

[Part of the Rails on XML series.]

One of our project’s major goals was to use XSLT for the views, and to integrate an XSLT rendering path into Rails in as natural a way as possible. This meant that each typical controller action would have a corresponding .xsl file, rather than a .html.erb file.

An XSL stylesheet is a program that describes a transformation; in our case a transformation from XML to XHTML. In some ways the XSL transformation language (XSLT) is very awkward, but it is a programming language. For various reasons – because our client already had XSLT files for his site, because there were members of the team who knew XSLT and not Ruby, and because it just seemed cleaner – we decided to see how far we could get if we used pure XSLT for the Rails views, with no embedded Ruby.

We realized that if we didn’t use Ruby in these views, we would not have direct access to the controllers’ instance variables. We decided the most Rails-like approach we could think of would be to have the framework automatically make all controller instance variables available to the XSLTs, by serializing this data to XML, and then provide the resulting XML as the input to the XSLT view. At this point we decided it was time to dig in and read through the Rails ActionView code and figure out how to extend it to work this way.

We found it is pretty easy to add a new renderer to Rails, and we experimented with that approach for a while. Ultimately we found it better for our application to write a simple module that we include in our controllers. This module defines a render_through_xslt method that works like this:

Liquid error: No such file or directory – pygmentize -f html -O encoding=utf-8 -l ruby

The final version is a bit more complex, as we added support for rendering partials and doing internationalization.