2008-08-19

Peanut butter jelly time

Do I save money eating PB&J for lunch every day at the office, or am I just making myself miserable? I sometimes wonder about these things. Here is my analysis.

I often eat PB&J for lunch when I am at work. Local restaurants charge $5-8 for a reasonably tasty and filling meal. Over the course of a year (assume 45 weeks x 5 days/week x $6/day), that's a lot of money: $1350.

Here's the price breakdown on the daily PB&J ingredients:
  • I buy bread at the expensive corner store. The store is more of a vice store, making almost all their money on cigarettes and lottery tickets. I feel silly walking out with a loaf of whole grain bread. They charge $3.89 per loaf. Each loaf contains 16 slice, or eight sandwiches, for a price of $0.49 per sandwich.
  • I like plain old peanuts in my peanut butter. That means I buy the relatively expensive wholesome brands like Teddie at $2.69 per jar. According to the label, there are 14 servings per jar. I probably use more than that, so let's call it 9 sandwiches per jar, at $0.30 per sandwich.
  • As far as I can tell, jam is jam. I use the local grocery store brand at $3.79 per jar. The label tell me there are 45 servings per jar. As with the peanut butter, I probably use more than the typical amount, so let's call it 30 sandwiches per jar, at $0.13 per sandwich
My total price per sandwich is $0.92. I eat two PB&Js per day, so that's $1.84. The total price per year (5 days per week x 45 weeks/year x $1.84/day) is $414.

$1.84 for lunch is a good deal, and the annual savings of almost $1000 makes me feel great!

When I really have to eat out, best value is the samosa chole chat for $4.50 at Punjab Foods & Spices/Chai Cafe. It is as super delicious and filling as it is inexpensive. Yum!

2008-08-16

MBTA insecurity

Anatomy of a Subway Hack is an interesting look at some of the MBTA's security problems, both physical and electronic. Here are some highlights:
Ryan, Anderson, and Chiesa deserve thanks for letting us know about these problems.

2008-07-27

Porter Square apartment for rent

Email rent3@kasperowski.com

3 bedrooms
1.5 bathrooms
975 square feet

Includes parking, private laundry, private storage, private back yard space

Well maintained apartment on tree-lined cul-de-sac
Recently renovated, open floor plan
2 blocks from the Porter Square T and commuter rail station
Near Davis Square
A short walk to shopping, restaurants, parks, yoga, martial arts,
Leslie, Harvard, elementary schools, etc.

$2150/month
No fee









2008-07-23

Spring Integration

Mark Fisher of SpringSource gave a talk on Spring Integration at Monday night's Boston Java Meetup. Mark has been with SpringSource for 2.5 years. He is a Spring committer and leads the Spring Integration project.

Spring Integration 1.0 is scheduled to be released in about 1.5 months. Spring Integration is an application of many of the ideas in the book Enterprise Integration Patterns and its related web site.

Spring
Mark began with an introduction to Spring. Fundamentally, Spring is an inversion of control (IoC) container, offering dependency injection, aspect oriented programming (AOP), and enterprise support libraries. It supports a POJO based programming model. He gave an overview of Spring features:
  • In Spring 2.5, you can use annotations instead of or in addition to the usual Spring XML configuration files.
  • @Autowired annotation
  • @Test annotation, the EasyMock library
  • AOP for transactions: uses the @Transactional annotation, delegates to the transactionManager that you wired in the XML config. Mark recommends using AOP for anything that's not in your business logic/problem domain, that you'll apply to numerous objects or methods. Doing so lets you focus on business logic.
  • JDBC templates, e.g. getSimpleJdbctemplate().query("select id, balance from account here customer_name=?", accountMapper, customer). In his example, he also uses a PramaterizedRowMapper. The advantage of the JDBC and other templates is that Spring handles the mundane set up work and exception handling for you.
  • JMS templates: Configuring a JMS listener is easy. They are a complete replacement for message-driven beans, and no EJB container required.
Some consequences of using Spring are that your domain model is simplified, layers enforce separation of concerns, and interface contracts promote loose coupling.

A meetup member asked why Spring uses AOP instead of @Interceptor. Mark replied that a problem with that approach is that you must annotate each method @Interceptor everywhere--you can't use AOP cut points defined by regular expressions, for example. He commented that it is still an open question whether EJB3's Interceptor approach is powerful enough

Enterprise integration patterns
Mark continued with an overview of enterprise integration patterns:
  • Pipes and filters architecture: conceptually, just like Unix pipes and filters
  • Message: send Messages through the pipeline. A Message is just a wrapper around a Java object.
  • Message channel: decouples producers from consumers. Can bepoint-to-point or publish/subsribe.
  • Channel adapter: connects a source to the messaging system. Can be anything, like a message bean, a web request, or a file system object.
  • Service activator: lets you invoke any POJO method without the service knowing that it's being using that way
  • Message translator: a payload transformer, converts the type or format of a message
  • Content enricher, content flter: add to or remove from message content
  • Content based router: determines the target channel based on payload type, property value, or header attribute. Decides where to send message. For example, the router might send a message to either the VIP service or the standard service based on importance of sender.
  • Splitter and aggregator
Spring Integration API
Following that, Mark presented the Spring Integration API. In a nutshell, Spring Integration implements enterprise integration patterns in Spring. The primary implementation points are:
  • interface MessageSource.receive: receives messages
  • interface MessageTarget.send: sends messages
  • interface MessageChannel.send, .receive
  • interface MessageHandler.handle
  • Message Bus: aware of components (hadlers, sources), connects them to channels, turns everyting on, runs a task scheduler, creates message end points, and ties them to channels
As a user of Spring Integration, you will specify things in your XML config file or via your annotation-based configuration, e.g. @Handler. You won't, for example, implement the MessageSource interface directly in your business code. This is consistent with Spring's theme: use domain objects everywhere; don't write any special messaging code.

Mark showed us some great demos and code examples, all of which are included in the Spring Integration distribution.

Additional features on the Spring Integration road map include:
  • Additional XML support, including XSLT transformations
  • Quartz scheduling
  • Support for additional channels, including RMI, email, and more

2008-07-16

How to assemble the Shaker all in one loft bed

This is a pictorial guide to assembling the Shaker All in One Loft, sold in the Boston area at Bedrooms. This series of photos is my step by step disassembly, with the photos reversed for assembly.

At Bedrooms, the bed is called "Shaker All In One Loft Twin/Twin" and is item #2000. For cross reference, a label on the bed calls it the Innovations Model # 261 Shaker ALL IN ONE TWIN, from Hartford, CT.

This catalog image from Bedrooms shows the bed completely assembled in its model habitat:



Here are the step by step assembly photos:























































Done!

Here is the simple command line I used to rename the photos and sort them from disassembly order to assembly order:
$ n=0; for f in `ls -1 *.JPG | sort -r`; do newname=${n}.jpg; if [ $n -lt 10 ]; then newname=0$newname; fi; mv $f $newname; n=$(($n+1)); done
My original photos were 8 megapixels each. To resize the images to 1024x768, I used ImageMagick and this simple command line:
$ for f in `echo 2008-07-13-jake-bed-disassembly/*.jpg`; do convert $f -resize 1024x768 2008-07-13-jake-bed-disassembly-1024x768/`basename $f`; done

2008-07-15

Location: OpenCellID and WIGLE

I have been thinking about mobile location based services (LBSes) for a long time. My typical user story is, "Alice and Bob are eating dinner in a restaurant. They decide they want to see a movie. Using her phone, Alice looks up nearby movies, theaters, and show times and buys two tickets to the next showing of a fun movie. They pay their bill and go to the theater." Other user stories have them looking for a cafe or a night club. Whatever it is, they are away from their home PCs, they have a mobile connected device, and they want information that is relevant to their current location.

Moviefone's mobile web site solves the user story. You tell it your zip code, and it tells you about the movies, theaters, and show times near you. One problem with this is that you might not know your current location's zip code. Another problem is that zip codes are geographically large. The nearest movie theater in my zip code is two miles away, but the nearest movie theater is only one mile away, in another zip code. The ideal LBS automatically knows where you are and has good precision.

The iPhone Google Maps application is compelling because it locates you automatically, using cell tower triangulation, WiFi access points, or GPS on iPhone 3G. In one very poorly controlled test I conducted, it takes about 5 seconds for Maps to locate you by cell tower, another 5 seconds for the more accurate and precise WiFi location, and another 20 seconds or so for the very accurate and precise GPS location. (These are very rough timings, to be taken with a grain of salt.) iPhone exposes this to developers through the Core Location API. On Windows Mobile, Google Gears exposes a similar API to developers. What APIs are available to other developers, or to developers who want a generalized way to locate the mobile user?

OpenCellID is an open database of cell tower IDs and their geographic coordinates. The first problem is that it is incomplete. For example, there are no database entries for cell towers in Western Massachusetts or on Cape Cod. You might be able to pay another provider for more complete data, but you would encounter the next problem: it is difficult to obtain the local cell IDs through the phone. Most handsets do not expose location data, through JSR-179 or any other accessible API, and carriers do not expose cell tower IDs through WAP HTTP headers. Finally, cell tower based location is not precise enough to solve some problems, such as what street am I on. On the positive side, finding location by cell tower is fast, and might be precise enough for some applications (what city am I in?).

WIGLE is an open database of WiFi access point SSIDs and their geographic coordinates. WIGLE's static and interactive maps show the amazing density of WiFi access points in urban areas. In the city, a WiFi based location can be very accurate, and precise enough and fast enough for most applications. The advantage over GPS is that it works inside buildings, where GPS might not work. The primary disadvantage is that the device might not have a WiFi radio or it might be too far away from a WiFi network. (Thanks to the Adeona FAQ for pointing me to WIGLE.)

If you are building a location based service, cell tower ID and WiFi access point SSID are two pieces of information that you might be able to use, either in the absence of GPS or as an alternative to GPS. WiFi SSIDs are probably the best approach for users stories like "Alice and Bob are eating dinner in a restaurant..."

2008-07-12

Critique of iPhone Dvorak keyboard

Unfortunately, the iPhone Dvorak keyboard hack isn't as good as it could be. There are two problems with it. First, the key clue is Cyrillic, not English. By "key clue," I mean the key that the keyboard displays above your thumb. When you press a key, the key is displayed above your thumb, and the keyboard doesn't type the key until you raise your thumb. This improves your typing accuracy because your thumbs obscure the keys, and you can move your thumb around the keyboard until you find the key you want, then release. While I can touch type Dvorak, touch typing doesn't translate directly to thumb typing. I need the key clues. The key clues, though, are Cyrillic, so they are useless for English.

The other problem is the lack of autocompletion. When I type English words on the QWERTY keyboard, the iPhone does a great job correcting my mistakes, and it learns my peculiar vocabulary and jargon to its autocompletion dictionary as I go. As with the key clue, this is a great boon to typing accuracy. The Cyrillic based Dvorak hack does neither--there is no autocompletion. The only way to correct your mistakes is to actually correct your mistakes. (It's funny how we whine about things not working well, when they didn't even exist five or ten years ago.)

So while it's nice that there is a Dvorak keyboard hack, in practice, I rarely use it. I thumb type QUERTY on the iPhone, just as I would on any other phone, and touch type Dvorak on the PC's full size keyboard.