Commutative data types and their operations is a powerful idea.

Somewhere this fortnight I read that I should read "CRDTs: Consistency without concurrency control" <http://hal.inria.fr/inria-00397981/en/>. The basic idea is to have a data structure where for the same set of operations applied in any order will lead to the same state. If I have a number of replicants of this data structure then as long as all the operations are applied to each replicant -- in any order -- then the replicants will have the same end state. With concurrent replicants then all replicants will eventually have the same state. Commutative data types and their operations is a powerful idea.

Downgrading my iPhone to iOS 3

I finally took the steps to downgrade my iPhone 3G from iOS 4 to iOS 3. The lose of responsiveness of basic features in iOS 4 is in no way made up by the new features, especially as few of them work with the 3G hardware. I followed the directions on the Lifehacker page at How to Downgrade Your iPhone 3G[S] from iOS 4 to iOS 3.1.3.

One-liner to find all occurrences of property names within a stream of text

One-liner to find all occurrences of property names within a stream of text:
cat * | perl -ne 'while ( /\G.*?([-a-z\.]+\.enabled)/gi ) { print "$1=x\n"; }' | sort -u > /tmp/enabled
This posting is mostly to remind me that 1) print "..." while /.../ does not work and 2) to use \G to anchor the regular expression to the first and/or last match.

Having a Java generic class return a type reference to its specialized class. Aka, using the self-type.

Emulating "self types" using Java Generics to simplify fluent API implementation is a very good example of how to more effectively use Java's generics and inheritance. The "self type" solution is something I would not have imagined. Further, it is motivating to see what other effects can be achieved through Java's generics. Read the article for a compete understanding of self types and a use of them. For those wishing to skip to the conclusion, if you need a generic class instance to return a typed reference to the specialized class then it is coded
public class GenericsTest {
// We have a generic type here that needs to return from its check method
// a reference to the specialized type (that is, the generic's sub-class).
static class Common<SelfType extends Common<SelfType,ElementType>,ElementType> {

protected SelfType self() {
return (SelfType) this;
}

public SelfType check( ElementType e ) {
// do something here that is general to all sub-classes
return self();
}

// ...
}

static class Foo extends Common<Foo,Integer> {

public Foo doFoo() {
// do something here is is specific to Foos
return this;
}
}

static class Bar extends Common<Bar,String> {
public Bar doBar() {
// do something here is is specific to Bars
return this;
}
}

public static void main( String[] args ) throws Exception {
Foo foo = new Foo();
Bar bar = new Bar();
foo.check(1).doFoo();
bar.check("a").doBar();
}
}

// END

Tools needed to support a simple content organization and workflow

I like to use the file system. And I like to use the file system's default explorer: On the Mac this is the Finder, on Windows this is the Windows Explorer, and on Gnome it is/was Nautilus. I much prefer to have other tools integrate into the file system explorer than for the tool to have its own explorer. When this happens, it is then possible to create your own tools that support your workflows. (Note that in this posting I am concerned with explorer integration and not command line integration.)

Unfortunately, this has not been the norm and so we have iPhoto, iTunes, etc, having there own content organization that is independent of the file system. These content specific explorers are often created due to the weaknesses in extending the system's explorer but mostly it is because creating another explorer is just easier to both imagine and code. The up-shot is that we have organizational silos with little integration between them. And, worse, the inability to create your own specialized tools from the integrations.

This Sunday I spent far too much time tracking down tools that would allow me to use the file system to collect and organize content as follows:

1. Each content collection is a folder. I am comfortable with using the file system hierarchy for organizing and I am aware of the weaknesses of hierarchical organization. However, most collections can be organized into a primary hierarchy and augmented either by search or linking (aliases on the Mac and shortcuts on Windows).

2. Each folder will have, at least, one plain text file of dated notes. Each note is separated by a simple delimiter, for example, a row of dashes. My experience is that this one file of notes is much easier to review and keep updated than to place notes into individual files. With that said, a good tool that can hide the file-ness of the notes would be acceptable too. Until then, one file of notes and using Merlin Man's tip for adding content to it <http://bit.ly/a1kfV6> will do fine.

3. The primary hierarchy needs to be supplemented with full text search. Tagging is not enough and, moreover, tagging can be achieved via search by using specialized tokens: For example, in normal English typography a colon is always followed by a space and so the expression ":foo" distinguishes the tag "foo" from the rest of the text. Spotlight on the Mac is the system's full text searching facility. It is extendable so that other content types can be incorporated. The plugin I am looking for would index the dated notes in a file as collection of "records". (This Spotlight feature was introduced in OS X 10.6.)

The Spotlight plugin is the most specific tool that I need. While it is a Mac only indexing solution it is based on plain text content and so could be indexed easily under other operating systems. Unfortunately, as far as I can tell, and I spent a good amount of time looking, there is no plugin for indexing delimited content as records. There are plugins for content types that somewhat match, for example mailboxes, but there is no documentation on how to use them outside of their intended application. The up-shot that that for this very simple workflow I can not compose a supporting tool from existing parts. Looks like I am going to have to write my own Spotlight plugin: If anyone has skeleton code I can build upon please drop me a note.

Cat & tail

I needed to count the open and close events in an active log file. Since I needed to start the count at zero I needed to start counting at the first line of the log and continue as the log grew. I needed both cat and tail -f. Turns out that tail can do both using tail -c +0 -f events.log. And so all I needed to do was to pipe the output to the counting script. The script took several minutes to catch up from processing previous events to current events but the counts it displays are accurate.

Using gnuplot to plot a time-series in text

I needed to review a sizable time-series on a remote host. Since I work at the command-line here having the plot displayed in text would be very helpful. To do this I used gnuplot. The data has the form
2010-11-06T00:00:01  35
2010-11-06T00:05:01 38
2010-11-06T00:10:02 45
2010-11-06T00:15:01 38
2010-11-06T00:20:02 38
2010-11-06T00:25:01 38
...
Note the two spaces between the data columns. The command line & script to plot this data is
gnuplot <<EOH
set terminal dumb
set autoscale
set xdata time
set timefmt "%Y-%m-%dT%H:%M:%S"
set xlabel "Date & Time"
set ylabel "Count"
set title "Requests waiting on connection"
plot "data" using 1:2 with lines
EOH
which outputs

Requests waiting on connection
Count
160 ++--+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+-++
+ + + + + + + "data" using 1:2 ****** +
| ***** |
140 ++ ****** * ++
| ** * |
120 ++ ** * ++
| * * |
| * * * |
100 ++ * * * ++
| *** * |
80 ++ *** * ++
| * ** * |
| * ** * |
60 ++ **** * ++
| * ****** * |
40 +*************** * *************************** ++
*** ******** |
+ + + + + + + + + + +
20 ++--+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+-++
00:00 02:00 04:00 06:00 08:00 10:00 12:00 14:00 16:00 18:00 20:00
Date & Time
Must easier to see the trend in the data.

I found the following helpful in figuring this out http://linuxgazette.net/126/peterson.html.

Update: Use the watch command to turn the graph generation into a dynamic visualization. For example watch -n 60 bash plotting_script will run the plotting_script every minute and update the terminal.

Update: See the bash script timeplot for a useful expression of this posting.

Vi and a little macro to step through a file of data

I needed to review a large number of data in a file each of which had a variable number of lines. Luckily, each datum started with the pattern ^"http- and so using vi I was able to quickly review the data by

1) creating a macro to find the next datum and move it's line to the top of the screen
qn
/^"http-
zt
q
2) use the macro to move from datum to datum
@n
I found the following helpful in figuring this out http://www.pixelbeat.org/vim.tips.html.

If you want to change the schools RUN FOR SCHOOL COMMITTEE

Do the candidates for South Kingstown Town Council understand that the TC and the School Committee are separate municipal bodies? The TC can only make SC budget recommendations. Legally it must transfer the money requested by the SC. Re-read those letters to the editor and the full page advertisements and note how many start with school issues and not town issues. If you want to change the schools RUN FOR SCHOOL COMMITTEE.

Windows Phone 7 is worthy addition to smartphone market

A useful review of Microsoft's new Windows Phone 7 user interface. Glade to see some good news about an MS product. Generalizing on two data points -- Office's "ribbon" and now Windows Phone 7 -- it seems MS is making good usability observations and providing good solutions to, as said below, the 10- to 30-second needs.

"Nobody seems to be committing themselves to optimizing those 10- to 30-second phone experiences. Everyone is focused on building phones that you can stare at for thirty minutes. If this is truly the path Microsoft has followed, then they've made strong and brave choices."

http://www.suntimes.com/technology/ihnatko/2829294,ihnatko-windows-iphone-android-phone-102310.article

Welcome to Code City!

Why are city and municipal codes not public domain? Why, in fact, are copyrighted by private companies? It is a $10B industry.

Prototype of an Open Web App Ecosystem

Mozilla is prototyping an "open" application ecosystem. App store + installation + upgrades + payments. Nothing really new here except the "open" part. What really bothers me is that this really isn't going to help most people any time soon and, worse, when it is done it will be outdated.

http://blog.mozilla.com/blog/2010/10/19/prototype-of-an-open-web-app-ecosystem/

The premise of Open Web App that I WANT to install and application in my browser. I don't want to do this because this ties me and the application to the browser I am CURRENTLY using. I don't use one browser. I don't use one machine. Today I regularly use three machines -- one MacBook, one iPhone, and one Windows laptop -- and four browser instances -- two of FireFox, one of Safari, and one of Internet Explorer. Tomorrow I expect to be using even more machines -- iPads, Android pads, setup boxes, Wii, etc. I don't want to be tied to one machine and one browser -- even if I can choose which ones. I want to be free to sit at any browser on any machine and just use an application and my data.

What I really want is for applications and data to be separated so that I can pick which application I want to use today to surface (visualize) a data repository. More on that another day.

Jim O'Neill must not be reelected to the South Kingstown Town Council

Jim O'Neill must not be reelected to the South Kingstown Town Council. His campaign placards speak to his "Thinking Ahead", [speaking] "Truth to Power", etc. But O'Neill lacks the basic skills needed to bring synergy with others' ideas and to build coalitions that move their ideas into actions. Spend a few evenings at Council meetings and especially at joint workshops with the School Committee and you will hear the authentic O'Neill. He is belligerent. He is divisive. He is dismissive. In, short, he is a bully. O'Neill has had many terms in office to bring action on the issues he raises and yet he has not succeeded. Nor has he learned from these failures.

A new independence is needed at Town Hall. One that will work with other councilors and interested parties in moving ideas to action. Do not vote for O'Neill this November.

Please share this note with others.

New Commons office space

Digging through some old folders I found the following sketch of the New Commons office space in Providence. I really liked the ideas in this space. The hallway that connects the open offices. The french doors into the meeting space. Etc.

Safari and accessing an HTTPS site behind a web proxy

Safari, unlike FireFox and Chrome, will not let you access a web site behind a proxy server if that site has an untrusted SSL certificate. Safari will ask you to login into the proxy server and then, after some time, tell you it can't access the site. The way I found around this to to import the untrusted certificate directly into the OS X's keychain using Keychain Access. The steps I used are

1. Use FireFox to initially access the site and to accept the untrusted certificate.

2. Use FireFox's certificate manager at ForeFox / Preferences... / Advanced / Encryption / View Certificates to export the certificate. Use the PEM encoding and make sure to name the file with a ".pem" extension.

3. Use Keychain Access to import the certificate

You should now be able to access the web site from within Safari.

A Gentle Introduction to CouchDB for Relational Practitioners

"CouchDB is a document-oriented database written in Erlang that addresses a particular "sweet spot" in data storage and retrieval needs. This blog post is an introduction to CouchDB for those of us who have a relational database background."

The short introduction to CouchDB at 

http://blog.couchone.com/post/1167966323/a-gentle-introduction-to-couchdb-for-relational

is a fantastic writing example. Within a few paragraphs the author has conveyed the essence of the tool and for an experience tools user/evaluator the set of next questions that must be answered before it can be put to use -- security, contention, document size boundaries, etc -- can now all be asked discerningly.

How to add commands to the OS X "right-click" menu – Simple Help

"This tutorial will show you how to use OnMyCommand to create customized "right-click" (contextual) menus in OS X. If you're a recent Windows 'switcher', you might have noticed that the right-click options lack some of the commonly used tasks (move-to, copy-to etc). OnMyCommand allows you to add these, and hundreds of other commands, back to your contextual menu."

http://www.simplehelp.net/2007/06/12/how-to-add-commands-to-the-os-x-right-click-menu/

MongoDB is Web Scale

A very funny rant on no-sql repository advocates


I too have also been in favor or using /dev/null for document storage.

What is your toolset?

After quitting all the non-development tools running on my MacBook I realized this is another kind of Minimal Mac. This minimalism has little to do with a tidy surface but instead a tidy toolset. Apart from the Drag application used to take the screen shot these applications -- iTunes, NetBeans, Screen Sharing, FireFox, Skype, and Terminal -- are my toolset. What is your toolset?

Halo around the foremost window

I want to stop closing the wrong window in Mac OS X. This error is caused, in part, by OS X's poor contract between active and inactive window framing. So, when I bring an application to the front I want the front-most window to be quickly haloed and then not. This would greatly help the user to know which of the several application's windows is actually the foremost.

16 months is too short a time to adopt Wave

Google recently announced that it discontinuing its Wave communications tool [1,2]. Wave was announced in May 2009 and discontinued in Aug 2010. Wave existed for 16 months. Google states "Wave has not seen the user adoption we would have liked." The rate of user adoption for such a radical change in communication is not going to happen in 16 months. Facebook took many years and its services are based on existing means of communication. Skype and Twitter also took years and they too offer services based on existing means of communication. Wave has little precedent in the wild (although many academic ancestors). Only now is the company I am working for considering moving to Google Apps and that has been out for years. Change happens slowly. The time of rapid internet tools adoption is over. We are returning to a new normal.

Every group establishes the tools and protocols of communication very early in its formation. Only new groups -- and perhaps only new groups in new situations -- have the chance to immediately adopt new forms of communication. For every other group, the group needs a lot of time to 1) recognize what is being lost in the current means of communication, 2) understand the loss's cost to the group, 3) set out to discovered tools and/or protocols that enables both to continue the successful communication and to reduce/eliminate the recognized lose, and, finally, 4) adopt the change with planning for the concomitant communications turbulence. 16 months is far too short a time to adopt Wave. For those that have adopted Wave within those 16, the time since adoption has been far too short to understood Wave effectiveness.

Google pulled the plug on Wave too soon.

[1] http://googleblog.blogspot.com/2010/08/update-on-google-wave.html
[2] http://wave.google.com/about.html
[3] http://googleblog.blogspot.com/2009/05/went-walkabout-brought-back-google-wave.html

Corporate Blogs: Front Page Structure (Jakob Nielsen's Alertbox)

Jakob Nielsen has a useful posting today about how to organize a corporate blog's front page: "Showing summaries of many articles is more likely to draw in users than providing full articles, which can quickly exhaust reader interest." I agree. See the fully posting at

Corporate Blogs: Front Page Structure
http://www.useit.com/alertbox/blog-front-pages.html

Sounds in presentations

I am sitting at my studio desk now wondering where the wireless phone is. I can hear its ring and it sounds like it is coming from the house. Did Chris take the studio phone into the house? She says no. Then what the hell is happening? I have never been able to hear the neighbors' phones. It turns out that the sound is background noise in a video interview I am listening to! I have had the same experience when listening to pod-casts: I hear an email arrive and so I check my mail; I hear a text message arrive and I check my phone; while driving I hear an ambulance and I pull over. Perhaps these are just signs of my declining mental health or perhaps there is just too much directionless noise in our lives. Our physicality did not evolve for this.

My very first posting to this blog was about sound <http://calliopesounds.blogspot.com/2007/07/i-had-weird-moment-today.html>.

Gobby and reviewing some source code

Evans Lin and I used Gobby <http://gobby.0x539.de/trac/> last night to review a sub-system that he is implementing. It worked but was less useful than anticipated.

1. Gobby is a peer-to-peer networked application and so your application is both a server and a client. This kind of networking does not play well between corporate and ISP firewalls. The only way we were able to communicate was to have three instances of Gobby running: One for me, One for Evans, and one running on my home Linux box acting as a server. And even then, Evans needed to ssh tunnel to the Linux box. To effectively use Gobby in a WAN much consideration needs to be given to network connectivity.

2. As anticipated, Gobby's document management is very weak. The documents are listed alphabetically with no meta-data about ownership, modification time, directory path, revision number, etc. I also found the floating document list to get in the way more time than not.

3. When Evans and I were discussing our first document Evans asked if I was seeing his highlighting. I was not. We both assumed that not only would you see other's changes but you would also see other's highlighting. This is a good example of not knowing what you want until to actually trial your tools.

4. Gobby knows almost nothing about the documents it is presenting and editing. It does highlight the syntax of the document based to the document's file name extension. However, our experience with IDEs is that we want really good navigation between source code elements. For example, with Java source code we want, at a minimum, 1) class name to definition source file, 2) method name use to definition location in source file, and 3) method name definition to locations of use.

5. Gooby has a instant-messaging feature but we used Skype's voice chat. Gobby as an extension to Skype would be more useful.

Overall, Gobby has too many network connectivity issues and not enough document navigation features. If Gobby were to be implemented today then it should be a web application built using the Etherpad <http://etherpad.com/> and Bespin <https://bespin.mozillalabs.com/> toolkits with a little of the Nautilus file manager <http://live.gnome.org/Nautilus>.

A tool for informal review of a tree of documents is needed. (As opposed to a set of patches for which there are great tools. For example, Rietveld <http://codereview.appspot.com/>.) So, I will keep looking. Tell me if you find something good.

Streaming content for non-media applications

The vast majority of web app and mobile app use JSON or XML on the wire to transfer data. It is relatively easy to design a utility schema and textual data on the wire is easier to debug. The schema designs, however, tend to emphasize an analytical perspective rather than a performance one. For example, the schema for hierarchal data will typically look like this


node := data children
children := node*
data := field+
field := name value
name := string
value := string

The problem with this design is that it you can only know about the structure of the data only after reading the whole document. You can not do anything for the user between making the request for data and getting the last byte of the response.

I don't know about you, but I hate waiting for all the data when I don't want it. When I am in browsing mode or manual indexing mode [*] I only want to get the gist and move along quickly. For example, if I am flipping through a list of the movies playing at the local cinema I don't need an image of the movie's poster. What I do need is to know that there are 6 movies, the 6 titles, and the next two showings of each movie. When I settle on a movie then I might be interested in seeing the promotional poster, trailer, and reviews and so am willing to wait for this data to fill-into the UI. (Don't have me press a "more details" button, please!)

Most schema designers will create something like this


movies := (movie)*
movie := title rating director casting
poster-url trailer-url movie-reviews
showtimes
movie-reviews := star-rating reviews
director := person
casting := person part
person := string
part := string
showtimes := showtime+
showtime := start-time end-time
start-time := number ':' number
reviews := review*
review := person star-rating comment-string
...

You get the idea: A straight forward and clear hierarchical organization of the data. The problem with this design is that for web apps or mobile apps the app needs to read far more bytes than it needs to enable browsing and manual indexing. It needs to read all the bytes up to the last movie's node first byte just to know that there are 6 movies. That could be several thousand bytes of data just to know the number 6.

Network performance is not instantaneous. Cell network performance is worse than network performance. Schema designers need to stop designing data structures as though the data will be instantaneously transferred from the host to the client. We don't do this for audio or video and we should not do it with other data either. Data on the wire should be designed more as packets to be explicitly organized. And it should be ordered so as to ensure the application's usability remains high even under poor network throughput conditions.

In the case of the movie listings, the following is a better data structure


movies := count id* ( title |
showtime |
poster-url |
trailer-url |
... )*
title := id 'title' string
showtime := id 'showtime' timestamp
poster-url := id 'poster-url' url
trailer-url := id 'trailer-url' url
review := ...

Here the related data is explicitly linked together with ids, tags, and values rather than implicitly by position within a hierarchy. Next, order the transfer of data to the client such that the client can use progressive disclosure. The user will now be able to see some structure and some content and so be able to perform some interaction with the application before the whole structure and all the content is delivered.

In the case of the movie listings it might look like


6 m1 m2 m3 m4 m5 m6 ;
# now get the titles and next showtimes for the movies
m1 title Inception ;
m1 showtime 6:30 ;
m1 showtime 3:10 ;
m2 title The Sorcerer's Apprentice ;
m2 showtime 4:50 PM ;
m2 showtime 7:20 PM ;
m3 title Despicable Me ;
m3 showtime ...
m3 showtime ...
m4 title ... ;
m3 showtime ...
m3 showtime ...
m5 title ... ;
m3 showtime ...
m3 showtime ...
m6 title The Last Airbender ;
m3 showtime ...
m3 showtime ...
# now get the remaining showtimes
m1 showtime 12:00 ;
m1 showtime 9:40 ;
m2 showtime 11:45 AM ;
m2 showtime 2:15 PM ;
m2 showtime 10:00 PM ;
...
# now get the star-ratings for the movies
...
# etc

Here I am using a semi-colon delimited encoding to simplify this example. There is no reason to abandon using JSON or XML as the encoding. You must, however, use a streaming JSON or XML parser so that the application client is able to get at the data as soon as it arrives.

This lesson was taught to me by David Durand when we were working on MAPA at Dynamic Diagrams. A visualization within MAPA was a Java applet that displayed a map of locations within a web site. The maps needed to display the canonical path to the location, the local structure of the site around the location, and the kinds of pages there. The data structure we used to communicate the data needed to display the map had the structural data up front so the applet could start rendering the map (in another thread). Meanwhile, the details about each page came trickling in and could be rendered piecemeal to the existing skeletal frame as it arrived. (David wanted me to use fixed-width data but I could not bring myself to do that.)

It is only now that I more regularly use mobile apps that I really want his lesson to be spread as far as possible because mobile app usability in conjunction with cell network activity just plain sucks. I don't think the primary reason for this condition has to do with hardware, or the network, and, probably, not the algorithms. That leaves the data.

[*] Manual indexing is when you have a list of 10 items and you flip through them until you find the one item that you want. I am sure there is a interaction-design term for this but I don't know what it is.

RFPs that discourage response

Integrated Computer File Integrity Monitoring Infrastructure via http://www.transitchicago.com/

Wow! It is not until page 48 that you finally get some detail on what this RFP is asking for. And, of the 61 pages only 2 are about the work. I thought (mostly in passing) I might submit a proposal regards this request but the effort to complete the submission is by far more time consuming than the completion of the work itself. No wonder government costs are so high and RFPs are submitted by companies filled by mid-level employees.

Best jig ever: McDonald's Bun Troubleshooting Tool

http://englishrussia.com/index.php/2010/07/06/mcdonalds-how-it-works/

Animag Photo Stands

I love these photo stands. The price is high, but this does inspire me (the good Scott that I am) to make them myself. All you need is to pickup plastic animals (or other things you can cut in half!) from the yard sales (25 cents each), a hack saw (1 dollar), some epoxy glue, and two neodymium magnets per photo stand (50 cents each). Total cost for 4 photo stands is $6 and a lot of fun.

I bought a big box of these magnets for some LED throwies but do you think I can find them now? No.

Using logrotate to manage Apache Tomcat's catalina.out log file

Apache Tomcat does not roll its catalina.out log each day (or after a given size). It is a small annoyance but nevertheless it is an annoyance. The solution is to have logrotate do for you. Add the following to the crontab
0 0 * * * /usr/sbin/logrotate -v --state $HOME/var/logrotate.status $HOME/etc/logrotate.conf
Set the logrotate.conf to
$HOME/lib/apache-tomcat-5.5.28/logs/catalina.out {
daily
rotate 10
copytruncate
compress
missingok
}
# END
Notes: I run Tomcat from within its own user directory and so all paths are relative to $HOME. Logroate does not perform environment variable substitution on the configuration and so replace $HOME in logrotate.conf with the actual path.

Manual duplex printing with OSX presets

I have wanted to be able to manually print duplex for sometime but never scratched the itch until today. With a quick Google search and I discovered

http://www.maclovin.de/2009/03/manual-duplex-printing-with-osx-presets/
The basic plan is to print the document twice. The first print prints only the odd pages. The second print prints only the even pages and (very importantly) with a reverse page orientation. So, print the document using the first settings. Next, take the stack of pages from the output tray and place them in the input tray as is, that is, don't flip them or turn them in anyway. Lastly, print the again document using the second settings. The result is a duplex document with the pages in the correct order in the output tray.

Max OS X allows for creating printing presets and so I have created a "Duplex Pass 1" and a "Duplex Pass 2" presets. The only bug is that the "Reverse page orientation" setting (aka checkbox) seems to be independent of the preset so be sure to make sure it is unchecked for pass 1 and checked for pass 2.

HP has a very useful application for manual, duplex printing but it has stopped working since OS X 10.8.4.

Sidewalk Graffiti Provides Navigational Assistance For Subway Commuters

"A considerate cartographer wielding a stencil and a can of spray paint has left a helpful navigational compass at the top of the stairs outside the NRW train at Prince Street for commuters exiting the station. As even native New Yorkers cant attest, everyone has exited a subway station and needed a moment to reorient themselves; a directional compass will make it that much easier. The unknown compass crusader stenciled the sidewalk at the uptown 6 train station on Spring Street as well. "

http://nyctheblog.blogspot.com/2010/06/sidewalk-graffiti-provides-navigational.html

I love simple, unobtrusive signage. It can be used in physical space and virtual space. Brainstorming on this example from NYC that painted a compare rose at the exit of subway stations you could use the same technique too

* point to bathrooms near parking

* point to information booths

* point to insert-your-favoriate-coffee-franchise-here

What would you point too?

Helping out Instapaper

The Instapaper iPhone app is wonderful for reading web pages later. Some web site's content does not show up very well because the Instapaper parser can't determine which HTML elements contain the content and what is ephemera. To help it, web sites can add CSS classes that point directly at content and non-content. Add the "instapaper_body" class to the parent content element and "instapaper_ignore" to non-content within the content element. See Preview: Community text-parser configuration for more detail.

I can't swipe horizontally to read email

Yesterday I walked into the Burlington Mall's Apple Store and tried out the iPad for the first time. (I have decided to buy the new iPhone 4 rather than an iPad and so the impulse to have one has waned.) It was much smaller than I expected but this does make it more book-bag friendly. I was very impressed with its speed especially compared to my iPhone 3G. I really wanted it to have a cover. The screen just screams at you "Please take care of me! I am going to be scratched." I don't want a sleeve: Where would I put it when it is not in use? I want a cover that works something like a triptych that folds flat into the back of the iPad or can be folded for use as a stand.

I have been thinking about interface design for the iPhone and iPad for a while now. I have been working through ideas with the design of an issue tracking application as this is a tool I will use every day. (I am a software developer, after all.) I am greatly inspired by Mag+ design. It is such a deep source of ideas. The Mag+ magazine is virtually laid out in a very strong 2d space: The horizontal is used to hold the articles side by side and the vertical is used to hold the article's content. This is a very easy visual model to internalize and it can be used for lots of different kinds of content with strong peer relationships and long content. I had assumed that Apple had this idea too. You see it in their photograph applications, but I was wrong. When reviewing the iPad's email application I was shocked that I could not swipe to view the next or the previous email. This was such a natural gesture that I assumed I did something wrong. As far as I can tell, I did not. Afterwards I realized that I can't swipe horizontally with the iPhone either.

The A Future of Information Interfaces for Emergency Management

The video The Future of Information Interfaces for Emergency Management is a good envisioning of the very possible with the possible exception of the "grab and drop" transfer of visualizations between physical machines. The front line responders all have head mounted video and, I would assume, other environmental sensors. The amount of information given to the front line was less than what I would have expected. That is, there was too much emphasis on centralized management and control when distributed management and localized control is a better approach. Other interesting features in the video include

* big displays with three-heads being common
* virtual whiteboard+touch screen that shows the distant participant as if on the other side of the device.
* pie menus are finally (!) showing their strengths in a touch-screen world.
* more direct touch interaction with specialized virtualized controls.
* heads-up display on the truck's windshield.

MonoTouch and Apple's Section 3.3.1: Two Theories

I do believe that Mono has meaning for developers. Everytime I listen to the Mono folks I hear them saying the right things. Here is another one of the right things:

MonoTouch and Apple's Section 3.3.1: Two Theories

"[...] MonoTouch has been misrepresented, initially by Gruber and by most people covering the debate over section 3.3.1. Probably because few of them have actually used MonoTouch or because they are not familiar with .NET. Probably folks think that MonoTouch is .NET, and .NET is Microsoft's Java and draw their own conclusions.

MonoTouch brings the C# language and the core of .NET to the iPhone, but does nothing to provide a cross-platform UI experience or for that matter any sort of mobile device cross-platform APIs.

We bring the C# language, garbage collection, a type safe system that help reduce errors, make programmers happier and more productive on the iPhone while getting access to every single iPhoneOS API that they want to.

We have also been able to expose new APIs that Apple has exposed in record time thanks to the fact that we are not really an abstraction layer over the iPhoneOS, but merely a compiler that talks to the native APIs. [...]"

JConsole and JMXMP

For the record, if you want to use jconsole with an MBean server using JMXMP you need to run it using
java \
-classpath $JAVA_HOME/lib/jconsole.jar:$JAVA_LOCAL_LIBS/jmxremote_optional.jar \
sun.tools.jconsole.JConsole \
"service:jmx:jmxmp://$JMXMP_HOST:$JMXMP_PORT"
Other incantations just don't work. Define JAVA_HOME, JAVA_LOCAL_LIBS, JMXMP_HOST and JMXMP_PORT appropriately. Now, back to work.

Network activity records and the common good

The record of activities of users of Google, Facebook, Twitter, etc have enormous use in the service of the common good [1]. Google shows us how searching on flu and flu related terms bests the CDC's reportage on outbreaks by two weeks. Facebook's shear population size and its tools for instant affinity groups sees people helping people under good and adverse circumstances. And lack of Twitter activity is the same warning signal grasshoppers give [2]. The upshot of this is that in our current networked world these private institutions need to start making this activity record public.

At one time most decent roadways were private enterprises. They supported commerce and so tolls were used to support them. At some point, roads were seen as too valuable to be held in private hands and government took over the task of building and maintaining decent roadways. The same story can be told about potable water. But why did this not happen to the electric grid or the telephone infrastructure? I don't have an answer today but I do want to find out. I think the answer will lead to a better understanding as to our rights as citizens to having the activity records available for the common good.

[1] http://en.wikipedia.org/wiki/Common_good
[2] The Origins of Knowledge and Imagination. Jacob Bronowski. http://bit.ly/akd0gR

Whitelines Hard Bound A5 Squared Notebook

Varanasi has an almost perfect web site

Varanasi, http://www.varanasi-indian.com/, has an almost perfect restaurant web site. Just one page containing the menu, hours of operation, and location. And one page that works with a mobile browsers as well as a desktop browsers. No Flash. No extra navigation. No big pictures. No complex layout. It was a pleasure to use.

The food, by the way, is fantastic. I really enjoyed the Punjabi Eggplant with spice level 4.

Ranks and snap lines in Instaviz

A Graphviz features is the abilty to align nodes using "ranks" [1]. Does Instaviz [2] offer a means of using ranks? If not, I imagine a means of dragging a node to "snap" to one of several equidistant lines drawn on the canvas. In this way, the user is able to specify some node organization and still allow Instaviz to automatically layout the graph as a whole. (I think it is reasonable to limit the snap lines to be in one direction only per graph.)

[1] http://www.graphviz.org/pdf/dotguide.pdf
[2] http://itunes.apple.com/us/app/instaviz/id299022481?mt=8

UpdateFor example, I want a graph to have have three ranks: The first rank contains the nodes A, C, and E; The second contains B, D, F; And the third contains X. Without ranks the following definition

digraph rankexample {
A -> B -> X;
C -> D -> X;
E -> F -> X;
C -> X;
X -> C;
}

Creates this graph:

However, adding ranks (i.e. the "snap lines") to the definition

digraph rankexample {
{ rank = same; A; C; E; }
{ rank = same; B; D; F; }
{ rank = same; X; }
A -> B -> X;
C -> D -> X;
E -> F -> X;
C -> X;
X -> C;
}

I get the layout I was looking for:

Addressing the needs of individual and groups with predictability

There has been some good observations of failures to help customers affected by Iceland's volcano eruption. David Weinberger's blog has a typical posting http://www.hyperorg.com/blogger/2010/04/18/volcano-1-internet-0-01/. I think the roots to this problem are that money and effort is being spent on

1. style over substance, and
2. individual-casting over broad-casting.

The style over substance argument is very easy to see. Every travel website that I have used obscures the process's workflow (and the broader information architecture) with abusive Web 2.0 techniques. Most of these techniques require an inordinate number of communications between the browser and the server. The upshot is that under moderate load the website fails to respond with predictable timing. Without this predictability customers are greatly frustrated and this leads them to use a telephone where they can at least know what their predicted wait time is!

The casting issue is more difficult to see. There are more casting groups then just "me" and "everyone else". Depending on your service, customers can be group into multiple and overlaps groups. For example, specific airport groups, country groups, traveling with children groups, etc. Each of these groups have common and unique information and advice needs in times of emergency (and times of calm!). The general public group is, generally, the most useless group unless there is system-wide failure. Without addressing the needs of affinity groups you are not truly servicing the needs of your customers.

The upshot is, let's spend less money and effort on individual-casting with technical acrobatics and instead balance the money and effort on addressing the needs of individual and groups with predictability.

This posting was inspired by Mark Bernstein's posting http://www.markbernstein.org/Apr10/InternetFailure.html

Always include a telephone number

Whenever you find yourself typing or saying "call me" ALWAYS include a telephone number. It it only 7 numbers locally and 10 nationally. Obviously, this is a pet peeve of mine.

Tomcat, JMX and working at the local library

When working within a restricted IP network -- like those found at libraries, cafes, and other hot-spots -- make sure you run services on 127.0.0.1 and not "localhost". This will ensure that all network services you are working with -- and, in my case, developing for -- do not need to access the restricted network. For Tomcat 5.5.x you will need to edit ./conf/server.xml and add the attribute "address="127.0.0.1" to each <Connector> element. For example,
    <Connector
address="127.0.0.1"
port="8080"
redirectPort="8443"
minSpareThreads="25"
connectionTimeout="20000"
maxSpareThreads="75"
maxThreads="150">
</Connector>

<Connector
address="127.0.0.1"
port="8009"
redirectPort="8443"
protocol="AJP/1.3">
</Connector>

Looking for webapp suitable for community garden hub

I am looking for a webapp that combines

* Wiki
* Issue Tracking
* CRM

All of these can be -- and, perhaps, should be -- feature-light. This will be used by members of a community garden. Anyone know of a turn-key solution for this?

Using a proxy & reflection to access a JMX Standard MBean

A current project uses JMX to monitor the application. Using JMX's Standard MBeans makes publishing an application's health, for example, very easy. This is the "server" side of the story. The "client" side of the story is not so satisfying. The JMX API is designed to support a highly dynamic management environment. To this end, the API uses an indirect access to the data. The client uses textual, untyped descriptors to get, set, and invoke methods on mbeans. Unless you are building a general purpose client this leads to lots of code and mental overhead. For example, if this is your Standard MBean
public interface HugsMBean {
boolean isHappy();
int getHugs();
void addHugs( int hugCount );
}

To use the isHappy() method requires the code
MBeanServerConnection mbeanServerConnection  = ...

ObjectName happyMBeanName = new ObjectName( "com.andrewgilmartin.hugs:name=hugs");
Boolean isHappy = (Boolean) mbeanServerConnection.invoke( happyMBeanName, "isHappy", null, null );
if ( isHappy ) {
...
}

If you are using Standard MBeans to publish data it would be great for your client to also use the Standard MBean to access the data. For example,

MBeanServerConnection mbeanServerConnection = ...

HugsMBean hugs = ... // i.e. associate with com.andrewgilmartin.hugs:name=hugs
if ( hugs.isHappy() ) {
...
}

To this end, below is a little set of helper classes that use Java's reflection and proxy facilities to do just this. The first code we need is an invocation handler that will send attribute and invocation mbean requests between the proxy and the mbean server:
package com.andrewgilmartin.common.management;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import javax.management.Attribute;
import javax.management.JMException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

public class MBeanClient implements InvocationHandler {

private MBeanServerConnection mbeanServerConnection;
private ObjectName mbeanName;

public MBeanClient( MBeanServerConnection mbeanServerConnection, String mbeanName ) throws JMException {
this.mbeanServerConnection = mbeanServerConnection;
this.mbeanName = new ObjectName( mbeanName );
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ( method.getName().startsWith("get") && method.getParameterTypes().length == 0) {
String attributeName = method.getName().substring(3);
return mbeanServerConnection.getAttribute( mbeanName, attributeName);
}
else if ( method.getName().startsWith("set") && method.getParameterTypes().length == 1) {
String attributeName = method.getName().substring(3);
Attribute attribute = new Attribute( attributeName, args[0] );
mbeanServerConnection.setAttribute(mbeanName, attribute);
return null;
}
else {
return mbeanServerConnection.invoke(mbeanName, method.getName(), args, null);
}
}
}

And now we need a factory (or perhaps just a static creator method somewhere) to tie together the Standard MBean interface, the MBeanClient helper, and the proxy:
package com.andrewgilmartin.common.management;

import java.lang.reflect.Proxy;
import javax.management.JMException;
import javax.management.MBeanServerConnection;

public class MBeanClientFactory {

private MBeanServerConnection mbeanServerConnection;

public MBeanClientFactory( MBeanServerConnection mbeanServerConnection ) {
this.mbeanServerConnection = mbeanServerConnection;
}

public T create( String objectName, Class... mbeanInterfaces ) throws JMException {
T mbeanClient = (T) Proxy.newProxyInstance(
this.getClass().getClassLoader(),
mbeanInterfaces,
new MBeanClient( mbeanServerConnection, objectName ) );
return mbeanClient;
}
}

Now, connect the client and create the proxy
// connect to the mbean server
MBeanServerConnection mbeanServerConnection = ...

// create the mbean client factory
MBeanClientFactory clientFactory = new MBeanClientFactory(mbeanServerConnection);

// create the mbean client for the server's mbean
HugsMBean hugs = clientFactory.create("com.andrewgilmartin.hugs:name=hugs",HugsMBean.class);

// use the mbean client
while ( ! hugs.isHappy() ) {
hugs.addHugs( 27 );
}
System.out.println( "happy with " + hugs.getHugs() + " hugs");

Post script: Here is how to connect to a JMX server running on localhost at port 9999 using RMI:
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbeanServerConnection = jmxc.getMBeanServerConnection();

A vi command line helper

A great command line file editing helper is to combine find and vi so that you can skip specifying paths. For example, the command
vif IndexerTool.java
effectively is the same command line as
vi ./java/org/crossref/qs/citationdocument/index/IndexerTool.java
(for a current project.) The script is
#!/bin/bash
[ -z "$1" ] || vi $(find . -name $1 -type f)
You can use wild cards too. For example, this will edit ALL your java files
vif \*.java

Blogger and Twitter link

This tip is a reworking of the tip given in Blogger Buster: 16 Useful Twitter Tools for Blogger Add a simple "Tweet This" link. Since Blogger's links can be long, the code uses bit.ly to shorten the link. The code to use is
<!-- TWITTER -->
<a expr:href='&quot;http://bit.ly/?u=&quot; + data:post.url + &quot;&amp;s=&quot; + data:post.title + &quot; (via @YOUR-TWITTER-USERNAME)&quot;' target='_new' title='Tweet via bit.ly'>Tweet This</a>

somewhere within the DIV element
<div class='post-footer-line post-footer-line-1'>

Replace YOUR-TWITTER-USERNAME with your Twitter user name. See the original tip for more details.

Blogger and conditional widgets

Quick note that to make a widget/gadget conditional in Blogger you need to edit the template's HTML and add a <b:if cond='... tag. For example, the following makes the given HTML widget only display on the index page (the main page).
<b:widget id='HTML1' locked='false' title='' type='HTML'>
<b:includable id='main'>
<b:if cond='data:blog.pageType == &quot;index&quot;'>
<!-- only display title if it's non-empty -->
<b:if cond='data:title != &quot;&quot;'>
<h2 class='title'><data:title/></h2>
</b:if>
<div class='widget-content'>
<data:content/>
</div>
<b:include name='quickedit'/>
</b:if>
</b:includable>
</b:widget>

This can be useful if you want some introductory content to be displayed to the viewers of the home page but not to viewers of of the specific posting pages.

Also, a new feature of Blogger is "Pages". Pages are named postings that can be listed and accessed by direct links. There is also a widget for showing the pages as a list or as tabs.

Shell enhancement to round-robin through list of directories

When working at the command line (Unix mostly) I am often working with files in several directories at once. The pushd and popd commands are useful but require a strict stacked directory use and require too much planning for me to use efficiently. (Clearly, self actualization has reached a new level of specificity.) What would be better would be a way to change directories by rotating through a list of directories. Much as is done today with applications vis Cmd-Tab under Mac OS X and Alt-Tab under Windows. Configuring the list of directories should be via a hot-key. The hot-key should work not only when in the current working directory but also when using filename completion. Often, the directories I want to return to are discovered during filename completion. So, one hot-key is used to add and remove directories from the list and another hot-key to change directories to the next directory in the list.

Re: What the iPad Means for the Future of Computing

Comment regards Wired's What the iPad Means for the Future of Computing:

What the iPhone did (and iPad will do) is to bring back sanity to interface design. For decades UI vendors — Microsoft, Apple, HP, Sun, etc — brought to tool/application front-end development well considered and consistent structural and visual interface elements. The tool’s new users needed only to learn how these elements were applied to the business function to use the tool. The value of this UI work was, some how, lost during the rise of the web.

The other element of the iPhone’s success is single user focus. The iPhone becomes the tool/application in use. User multi-tasking is not a requirement to productivity. Switcher was one of Apple’s greatest productivity successes. It was ahead of its time and ahead of the capabilities of the hardware. The hardware in the iPhone and the iPad make switching to another application fast and into the same context you were when you left.

Microsoft's Our Productivity Future Vision


Genuinely enthralled with Microsoft's Our Productivity Future Vision. Lots of reviewing stuff and not enough creating stuff, however.

Update: When I worked for Mesa Systems Guild (10 years ago) the data point that drove the product was that for every 1 creator there there 40 users of the creation. I wonder what the ratio is today?