"We have certain work to do for our bread..."

John Ruskin, Seven Lamps of Architecture:

We have certain work to do for our bread, and that is to be done strenuously; other work to do for our delight, and that is to be done heartily: neither is to be done by halves nor shifts, but with a will; and what is not worth this effort is not to be done at all.

Thanks to http://www.everymac.com/

Thank you http://www.everymac.com/ for the information and instructions for replacing my 2010 Mac Mini's hard disk.

Copy & Cite Bookmarklet

I don't know why it is such a hard task to create a browser extension for copy & cite. Since none work to my liking, here is a simple bookmarklet. (This posting is mostly so I don't loose the code.)
var selection = "";
var ranges = window.getSelection();
if ( ranges.rangeCount > 0 ) {
   for ( var i = 0; i < ranges.rangeCount; i++ ) {
      if ( i > 0 ) {
          selection += "\n\n";
      selection += ranges.getRangeAt(i);
else {   
   var titles = document.getElementsByTagName("title");
   if ( titles.length > 0 ) {
      selection = titles[0].textContent;
var subject = "FYI:" + selection.substr(0,50) + (selection.length > 50 ? "..." : "");
var body = selection + "\n\n" +window.location.href;

Use the tool at http://mrcoles.com/bookmarklet/ to create your own bookmarklet.

$2.50 per row house

The machine rental and materials costs make each row house cost about $2.50 each. AS220 charges $25 for a 2 hour block of lab time. The 1/16" chipboard is $7 for 25 sheets. Each row house takes 2 sheets of chipboard and about 10 mins to setup and cut. Therefore, $25 / 120 min * 10 min + $7 / 25 sheets * 2 = $2.64. (These costs do not include the incidental costs of shipping, parking, a Cafe Tobe from Coffee Exchange, etc.)

If we add the cost of my time then they are priceless!

Assembled row house

I made the time to finally assemble the laser cut row house. Here are two photos of the assembled building. I think it is a little out of scale for 15mm, but am hopeful it will be useful.

I learned much in assembling these buildings.

  • I need to increase the laser power a small amount so as to ensure that each edge is cut all the way through.
  • The 1/16" chipboard is a good material choice, but like all cardboard it tends to warp. To mitigate this, I will add internal structure the next time. More specifically, a hollow rectangular plate around the inside, top of the walls.
  • The method of creating stone work around the windows is too fussy. The next time I will cut it out from 1/32" card and glue around the window opening.
  • A better method of aligning the floors is needed. The improvised teeth I cut work, but are ugly.
  • I improvised a number of jigs to aid assembling the house. I will include these to be cut alongside the house parts the next time.

If anyone wants the row house patterns send me an email.

Finally, charred edges!

Many thanks to Shawn Wallace who helped me complete my introduction to using AS220 Lab's Epilog laser cutter this afternoon. I was able to cut 8 building of two different designs on 12" square, 1/16" thick chipboard. Next step is to assemble them to see how accurate mine and SketchUp's measurements are. To be fair, however, the conversion pipeline between the SketchUp drawing on my MacBook and final output to the cutter is very long -- SketchUp to PDF to iDraw to PDF to Corel Draw to Epilog driver to Epilog hardware.

Too Fat Lardies' "Talking Tactics"

For the WWII gaming novice like myself Richard Clark of Too Fat Lardies is writing a serialized tactics tutorial "Talking Tactics." Well worth reading. Currently there are seven parts

  1. Introduction
  2. The patrol phase
  3. Deploying for the attacker
  4. Deploying for the defender
  5. Fire & Movement
  6. Resource placement
  7. Fish & Chips

I will update this posting as more parts are published.

Update: The Lardies have assembled all the postings into a single PDF document. The document is available in the files area of their Yahoo.com mailing list.

Wargames magazines

In the US the wargaming press is limited to three general audience magazines. Perhaps there are more, but I am unaware of them. They are

  • Wargames, Soldiers & Strategy
  • Wargames Illustrated
  • Miniature Wargames (with Battlegames)
Without a doubt your money is well spent on Wargames, Soldiers & Strategy. Its coverage of historical periods, rule sets, battle scenarios, available miniatures, and informative columnists is well rounded. And the Editor seems like a guy you would want a pint and a conversation with. I subscribe and will renew.

Wargames Illustrated was my first wargames magazine subscription. It continues to be a excellent source of inspiration, but its recent purchase by Battlefront Miniatures is clearly changing the weight of page counts from the broad hobby to Flames of War and WWII. I subscribe, but am considering not renewing.

I find Miniature Wargames interesting some of the time, but mostly I find the tone, as best I can describe it, as matronly. A nearby games store has back issues for several past years available and I have bought, read, and find these older issues and under a different Editor more appealing then the current issues. I will not subscribe.


SketchUp models and templates

In my posting Dimensions from photographs with perspective I noted that SketchUp is a tool that needs a trained user. Well, I stopped putting off training myself and within a few hours I was quite comfortable with the basics of it. I know enough now to be able to create a building similar to the one photographed in the previous posting, for example

The yellow roof is there to help me orientate myself when viewing the model in elevation only. I also only use parallel projection for all work in 3D.

With the model finished, I used the Flattery plugin to take each face of the model and lay it down on to the XY plane to create a printable template from which to construct the building in the real world. I also experimented with the Unfold plugin and the brilliant Pepakura Designer application, but for my needs Flattery was just right. (Note that Flattery does not yet work with SketchUp 2015.)

I assembled some parts of the building so as to understand first-hand some of the issues that arise from this process. The first issue is simply keeping track of the parts; I would like to be able to automatically number each face so that once flattened I have a reference to the 3D model in place. A consequence of this is that the template should be printed upside down so that the markings are on the back of the face and not on the front. Doing this also leads to the idea of applying the template to patterned materials. I should note that I am not interested in printing features onto the faces -- such as brickwork, shingles, window frames, ivy, or "rising damp" -- as these models will be enhanced with moulded windows, doors, and other dimensional findings, and then painted.

The template was printed on thin card stock and so material thickness was not an issue in assembling. However, the material I plan to be using -- for example, chipboard, plywood, and MDF -- does have thickness and so I am now learning how to incorporate this construction element into the SketchUp design. I found the videos "Sketchup and Laser Cutting: Making Teeth and Slots" (parts one & two) to be very helpful in getting started with adding dimension. (I am not interested in the interlocking teeth as my models will be glued.) The second video also shows how to flatten the model and to adjust the faces to account for material loss during laser-cutting.

Cats are evil creatures that break Ps on the keyboards with their kneading

Cats are evil creatures that break Ps on the keyboards with their kneading. A big thank you to HP for all their helpful product repair support pages.

High School freshman year is a blizzard of handouts, worksheets, and single pages of notes

High School freshman year is a blizzard of handouts, worksheets, and single pages of notes. None of which are dated. None of which use any system of ordering (e.g., "handout 21 of 97"). I am appalled that my children's teachers can not provide a comprehensive set of materials at the beginning of the year. (What have they been doing all Summer?) When there is no "text book" there are few means for the child to advance or review. When the "text book" is so fractured how can the child know what is missing? How can a parent help in such chaos? This really is no way to provide an education.

Dimensions from photographs with perspective

I needed to calculate the dimensions of some historical buildings for which I only had photographs. A WAG is acceptable as I am only making rough models of the buildings. However, I did want to know how to do it with more accuracy and so looked around for an answer. SketchUp has a facility to do this and it is remarkably easy to use. Unfortunately, the rest of SketchUp is not as it is a technical tool that expects a trained user. So I kept looking around and finally found a clear explanation of the algorithm to use.

The key to understanding the algorithm is that you make right angled triangles in a plane perpendicular to a known height. For the rest of the explanation I am going to quote the author and present his diagram:

"Starting from the corner C of the building, draw a horizontal line on the image plane. This line represents a horizontal line in space, parallel to the image plane and at the same distance (and so the same length scale) as the vertical edge of the building above C, so you can measure lengths along it. It intersects the line AB, along the other side of the building, at B. (B is not necessarily the opposite corner of the building; this particular perspective view just happens to have the corners drawn about the same distance from the central corner A.) Now triangle ABC, in space, is a right triangle (assuming the corner A of the building is a right angle). You know the length BC of the hypotenuse (by measuring with a ruler calibrated to the vertical edge C, as I've shown with the green 45-45-90 triangle--just coincidentally, this is about the same height as the building for this drawing) and the length AC of one leg, so you can find the true length AB of the other leg by AB2=BC2-AC2.

"All this assumes that your camera isn't imposing too much distortion on the image. It would probably be a good idea to test this (take a picture of an object of known dimensions at similar lens zoom settings and with similar perspective) to see if this provides accuracy sufficient for your purposes."

Found at Dimensions from photographs with perspective.

3mm awe

Over at Lead Doesn't Bleed, Mr Blanchette painted 3mm Napoleonic figures using 14 applications of color! Remember that 3mm is the distance from foot to eye. And there are hundreds of them. I am in awe.

A bookmarklet for use with Kindle "Your Highlights" page

I heard Maria Popova's Kindle highlights lament on Tim Ferris's podcast and thought I would try to solve some part of it. Below is a bookmarklet that when used while viewing the highlights page will replace the page with data from the original page and then present in a format and style suitable for copy & pasting into Evernote. It has had VERY limited testing, but perhaps you will find it useful. Note that since this code uses HTML scraping to gather the data any change Amazon.com makes to the format of the original page may adversely affect the bookmarklet's functionality.

var O = $('<div class="books"/>');
var S;
var xs = $("#allHighlightedBooks").children();
for ( var i = 0; i < xs.length; i++ ) {
  var x = $(xs[i]);
  var c = x.attr("class");
  if ( c.indexOf("bookMain") != -1 ) {
    t = $('.title',x).text();
    a = $('.author',x).text();
    l = $('a',x).attr("href");
    b = $('<div class="book"/>').appendTo(O);
    $('<div class="title"/>').text(t).appendTo(b);
    $('<div class="author"/>').text(a).appendTo(b);
    $('<div class="link"><a href="'+l+'">'+l+'</a></div>').appendTo(b);
    S = $('<div class="selections"/>').appendTo(b);
  else if ( c.indexOf("highlightRow") != -1 ) {
    h = $('.highlight',x).text();
    n = $('.noteContent',x).text();
    l = $('.linkOut',x).attr("href");
    x = $('<div class="selection"/>').appendTo(S);
    $('<div class="selection"/>').text(h).appendTo(x);
    $('<div class="note"/>').text(n).appendTo(x);
    $('<div class="link"><a href="'+l+'">'+l+'</a></div>').appendTo(x);
  '<style>' +
  'div { margin-bottom: 1ex; }' + "\n" +
  '.title { font-weight: bold; }' +

The following code is also at https://gist.github.com/andrewgilmartin/26fd5b2ce02a3219c96c. Any suggestions on how to better use jQuery are most welcome.

Vote NO on 4

I am opposed to the $125M URI wants for a new engineering campus. It was only a few years ago that the university wanted to cease being a state school so they would not be under state imposed regulations and their concomitant costs. And yet now they want to be a state school so that they can get $125M from the taxpayers. When URI figures out what it wants its relationship with the people of RI to be then perhaps we can consider supporting this expenditure.

Digital layout comment

A comment on Video: Why eBook Text Layout is Terrible: The problem stems from using visual design features that were designed and refined for a fixed content, and a fixed size page and/or double page spread. There are examples today that are taking the steps needed to design a new visual + dynamic language for documents. When these become more broadly adopted I don't see us missing the widows and orphans.

Disable Chrome's print dialog box

Note to self ... For Mac Chrome users that don't want Chrome's print dialog box you can disable it from the command line using

defaults write com.google.Chrome DisablePrintPreview -boolean true

When the organization can consistently repeat the success ...

When I read headlines like "Building a Trading Platform in 6 Weeks in an Organization That Would Really Rather We Didn't" I think "So what? Anyone or any small team with sufficient domain knowledge, technical skills, and tools could can do that." A one time success is only that -- a one time success. When the organization, and not a specific person or specific team, can consistently repeat the success then tell me about it.

The Danes were victorious over the Normans this Wednesday

The Danes were victorious over the Normans this Wednesday. The Normans and Danes were slated for a final confrontation

The Dane's warlord (aka Cloudbeard, Kim, &, in spirit, Leo) directed a unit of hearthguard with all favorable dice on the battleboard to take down the Norman warlord. There were tense moments of rule reading by the Normans with intent on unhinging the Dane's psyche. When rules were read and positions measured the dice were gathered -- 12 dice for hearthguard and the 5 for the warlord -- and were rolled. The warlord was hit 5 times and now needed 4 saving throws to stay on the field of battle. Only one hit was countered. The Norman warlord, majestic on his white horse let go his shield, glowered at the unbelievers, and fell to ground dead.

An Observer pattern implementation and illiterate programming

This posting is an experiment in documenting Java code using (in my case) illiterate programming. The Java source code is at The Observer Pattern and the Perl code that converted the Java code is at Simpleminded Java + Javadoc to HTML Converter.

The Observer pattern is used to create a relationship between two objects. The relationship is usually unidirectional with the observer waiting for notices from the observed. The relationships is a loose one as the observed only needs to know of the interest of the observer and the observer only needs to know of the set of and ordering of notice the observed will send. A downside of this looseness is that all notices pass through a single observer method for further dispatching.

 10 package com.andrewgilmartin.common.observation;
 12 import java.util.Set;
 13 import java.util.concurrent.BlockingQueue;
 14 import java.util.concurrent.CopyOnWriteArraySet;
 15 import java.util.concurrent.LinkedBlockingQueue;

The Observation class is only used to group all the related interfaces and classes into one file. In a typical development environment each interface and class would be in its own file.

 22 public class Observation {

The Observable is the object that is being watched. As changes are prepared and then made the observable will send consent and information notices to the observers. The notices are normally specialized classes that hold some context about the change. For example, if the notice concerns the addition of new inventory to the warehouse then the notice's class could have a method for enumerating the new inventory.

 32     public interface Observable {

If it is necessary for the observable to have approval before making a change then a consent notification is sent to the observers. Each observer will be notified and if any observer opposes the change then it must return false. The current thread will be used to notify the observers and so all the observed must wait for all observers to consent.

 42         boolean consentNotification(Object notice);

An information notification is normally sent after a change. Since the change has already occurred the notices are typically sent asynchronously by a background thread. The order of the notices is preserved, however.

 50         void informationNotification(Object notice);
 51     }

The observer is the object that is notified by the observable. There is no typed relationship beyond the Observable and Observer classes. As mentioned earlier, the notices are usually of specialized classes where each notice instance holds data relevant to the change.

 59     public interface Observer {
 61         boolean notice(Observable observable, Object notice);
 62     }

A registry is the means of establishing the relationship between the observable and the observer. This interface is distinct from Observable as it is sometimes useful to indirectly register an observer via, for example, a registrar.

 70     public interface Registry {

The order of the observers is undefined.

 75         Set<Observer> getObservers();

Adds the observer to the set of observers. Returns true if the observer was added.

 81         boolean addObserver(Observer observer);

Removes the observer from the set of observers. Returns true if the observer was among the observers and was removed.

 87         boolean deleteObserver(Observer observer);
 88     }

There is often very little difference between implementations of Observable and Registry and so this base implementation can be widely employed by any class that wants to be observed.

When extending this class make sure to document the set of notices, their consent or information role, and what is their ordering.

 98     public static class ObservableBase implements Observable, Registry {

The management of the set of observers needs to be thread-safe. The set is expected to be mostly stable over the life of the observed and so copy-on-write semantics is appropriate here.

105         private final Set<Observer> observers = new CopyOnWriteArraySet<Observer>();

Information notification notices will be sent by a background thread. A blocking queue will be used to coordinate the passing of notices from the observed to this background thread.

111         private final BlockingQueue<Object> informationNotices = new LinkedBlockingQueue<Object>();
113         public ObservableBase() {

This implementation of the information notification background thread is quite simple and so uses an anonymous class for the implementation.

119             Thread informationEventsDispatcher = new Thread(new Runnable() {
120                 @Override
121                 public void run() {
122                     try {

Here the thread waits for a new notice on the queue and then sends it to each of the current observers.

127                         for (;;) {
128                             Object notice = informationNotices.take();
129                             for (Observer observer : observers) {
130                                 observer.notice(ObservableBase.this, notice);
131                             }
132                         }
133                     }
134                     catch (InterruptedException e) {
135                         // empty
136                     }
137                 }
138             });
139             informationEventsDispatcher.setDaemon(true);
140             informationEventsDispatcher.start();
141         }
143         @Override
144         public boolean consentNotification(Object notice) {

As mentioned earlier, consent notifications are performed by the observed's thread. In this way, as soon as any observer opposes the change the observed must reject the change.

150             for (Observer observer : observers) {
151                 if (!observer.notice(this, notice)) {
152                     return false;
153                 }
154             }
155             return true;
156         }
158         @Override
159         public void informationNotification(Object notice) {

Pass along the notice to the background thread.

163             informationNotices.add(notice);
164         }
166         @Override
167         public Set<Observer> getObservers() {
168             return observers;
169         }
171         @Override
172         public boolean addObserver(Observer observer) {
173             return observers.add(observer);
174         }
176         @Override
177         public boolean deleteObserver(Observer observer) {
178             return observers.remove(observer);
179         }
180     }

Here is a small example of using the observation interfaces and classes.

185     public static void main(String... args) throws Exception {
187         class Notice {
189             private int senderId;
190             private int sequenceNumber;
192             public Notice(int senderId, int sequenceNumber) {
193                 this.senderId = senderId;
194                 this.sequenceNumber = sequenceNumber;
195             }
197             public int getSenderId() {
198                 return senderId;
199             }
201             public int getSequenceNumber() {
202                 return sequenceNumber;
203             }
204         }

The Sender is an observed. All that it does it to send a stream of notices consisting of sender-id & sequence-number pairs.

210         class Sender extends ObservableBase implements Runnable {
212             private int senderId;
214             public Sender(int id) {
215                 this.senderId = id;
216             }
218             @Override
219             public void run() {
220                 for (int sequenceNumber = 0;; sequenceNumber++) {
221                     informationNotification(new Notice(senderId, sequenceNumber));
222                     sleep(); // add some randomness to the processing.
223                 }
224             }
225         }

The Receiver is an observer. All that it does is to print the notice's facts. In this example all notices are information notifications and so the notice() return value does not matter. However, as a matter of course, notice() should always return true unless it is well sure of the consequences of opposing the change.

234         class Receiver implements Observer {
236             private int receiverId;
238             public Receiver(int id) {
239                 this.receiverId = id;
240             }
242             @Override
243             public boolean notice(Observable observable, Object notice) {
244                 if (notice instanceof Notice) {
245                     Notice n = (Notice) notice;
246                     System.out.printf("notice %d %d %d\n", receiverId, n.getSenderId(), n.getSequenceNumber());
247                     sleep(); // add some randomness to the processing.
248                 }
249                 return true;
250             }
251         }

Create a few senders.

256         Sender[] senders = new Sender[5];
257         for (int i = 0; i < senders.length; i++) {
258             senders[i] = new Sender(i);
259         }

Create a few receivers.

264         Receiver[] receivers = new Receiver[3];
265         for (int i = 0; i < receivers.length; i++) {
266             receivers[i] = new Receiver(i);
267         }

Have each receiver observe each sender

272         for (Receiver r : receivers) {
273             for (Sender s : senders) {
274                 s.addObserver(r);
275             }
276         }

Startup the senders

281         for (Sender s : senders) {
282             Thread t = new Thread(s);
283             t.setDaemon(false);
284             t.start();
285         }
286     }

Add some sleep of random duration to the current thread.

291     static void sleep() {
292         try {
293             Thread.sleep(Math.round(Math.random() * 25));
294         }
295         catch (InterruptedException e) {
296             // empty
297         }
298     }
299 }

To build and run this from the command line, first compile using

303 javac -d /tmp ./src/com/andrewgilmartin/common/observation/Observation

And then run using

308 java -classpath /tmp com.andrewgilmartin.common.observation.Observation

You can show to yourself that the events are ordered by sorting the output on the receiver id and you will see that the events are in numeric order.

314 java -classpath /tmp com.andrewgilmartin.common.observation.Observation | head -20 | sort -k 2 -n -s

318 // END

Her Majesty's Rugged Constabulary in preparation

MySql load balancing with HAProxy

We use pair of HAProxy servers at work to route and balance all of our traffic. It is a highly reliable tool with little time or performance overhead. Yesterday I need to balance a load of MySql connections across several slave servers and so used HAProxy to do that. Since I did not find the exact recipe I need on the web here is my test configuration contribution to the MySql global distributed cookbook:

    mode http
    stats uri /haproxy-stats
    stats enable
    log global
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

listen admin
    bind *:8000
    mode http

listen mysql
    bind *:3306
    balance  leastconn
    mode     tcp
    option   tcpka
    option   srvtcpka
    option   mysql-check user haproxy
    server mysql1 weight 1 maxconn 200 check
    server mysql2 weight 1 maxconn 200 check
    server mysql3 weight 1 maxconn 200 check


Each MySql server used must have the haproxy user created using

create user 'haproxy'@'%';
flush privileges;

The wildcard can be replaced with the IP address of the HAProxy server.

I want to thank the folks at Homebrew for the haproxy formula.

Low tech needed

And how is this better than writing the inception and expiration dates on the container with a grease pencil?

Given the pace of ...

Where is the call from?

I wish my phone told me where the person was calling from and not where there phone number was registered. I would have been much more prepared to take a call from Matunuck, RI than from Long Beach, CA.

When the solution hides the problem.

A comment on How to Create Your Own 'Dynamic' Bean Definitions in Spring:

The solution hides the problem. I enjoyed reading about the details of the insides of Spring, but the solution was too complicated for the problem. A real value of Spring is that generally it does not get in the way of straightforward solutions. The problem here, picking a datasource based on key could have been handled with a simple DataSource delegate that can pick the actual datasource from an injected mapping of key to datasource. The management of the mapping would be done elsewhere -- JMX, webapp, etc.

For me, the red flag would have been when I thought the solution required a weekend of prototyping to understand the internals of Spring.

This is off topic, but related to picking solutions. You also need to think about the person maintaining your solution. A complex solution will require that the maintainer be at least as talented as you and that can be an unnecessary burden on the organization.


With all the Viking history and fiction I have been reading recently, I would that you now address me as Cloudbeard.

Problem solving sub-101

Is a whole book needed to tell you to solve problems by enumerating the subproblems, stop enumerating when you find one with few dependencies, visualize the dependencies, fix the subproblem, revert the fix when necessary, rinse and repeat. Oh, and give the method a catchy name like The Mikado Method. I don't think so.

Update: This comment was a bit too snarky. I sometimes forget that junior developers do need to be reminded of the basics. And being able to name this is important as the Gang of Four confirmed for us with Design Patterns: Elements of Reusable Object-Oriented Software.

I no longer have patience for certain things

"I no longer have patience for certain things, not because I've become arrogant, but simply because I reached a point in my life where I do not want to waste more time with what displeases me or hurts me. I have no patience for cynicism, excessive criticism and demands of any nature. I lost the will to please those who do not like me, to love those who do not love me and to smile at those who do not want to smile at me. I no longer spend a single minute on those who lie or want to manipulate. I decided not to coexist anymore with pretense, hypocrisy, dishonesty and cheap praise. I do not tolerate selective erudition nor academic arrogance. I do not adjust either to popular gossiping. I hate conflict and comparisons. I believe in a world of opposites and that's why I avoid people with rigid and inflexible personalities. In friendship I dislike the lack of loyalty and betrayal. I do not get along with those who do not know how to give a compliment or a word of encouragement. Exaggerations bore me and I have difficulty accepting those who do not like animals. And on top of everything I have no patience for anyone who does not deserve my patience." -- Meryl Streep

Re: Using exceptions when designing an API

A comment on Using exceptions when designing an API:

When designing an API I use the "get vs find rule." The API's user needs to know how to handle the absence of a result. A get is expected to always return a result while a find is not. And so when coding "getX()" it returns the result or throws an exception -- such as IllegalStateException -- if there is not one. Where as, when coding "findX()" it returns a result if available or a null, or an empty collection, if there not one.

Quick guide to making PDFs with text outlines from HTML

Create the HTML document.

<body style="margin: 0; padding: 0">
<div style="width: 2in; height: 2in; border: 1pt solid blue;”>
<span style="font-size: 0.5in">Hel</span>lo

Use the OS X command line tool wkhtmltopdf to convert the document to pdf

wkhtmltopdf -B 0 -T 0 -L 0 -R 0 --page-width 2in --page-height 2in box.html box.pdf

The fonts in this are embedded (or likely to be). To replace the fonts with text outlines use

gs -sDEVICE=ps2write -dNOCACHE -sOutputFile=- -q -dbatch -dNOPAUSE -dQUIET box.pdf -c quit | ps2pdf - box-nofont.pdf


Response to Tom Hoffman's "Peter Greene on Tenure"

Response to "The threat of firing is the great 'Do this or else...'" in Tom Hoffman's Peter Greene on Tenure:

On the whole I find that teachers take on too much accountability and the administration too little. To some degree this is self imposed. I don't know of any other profession that has such a shallow managerial hierarchy. The whole point of a manager is to make this kind of crap go away -- if not in actuality then at least from visibility. Tenure is not the solution and, understandably, sets up teachers for further criticism as being detached from appropriate accountability and economics of their employment. Teaching needs to add management and remove tenure.

Inner curmudgeon awoken

My inner curmudgeon was awoken this morning when I read of yet another OS X application for note taking with cloud storage and a corresponding web application. Doesn't anyone know how to use a text editor in conjunction with a remote file service like Google Drive, et al? And, for the vast majority of users, there is no purchase price or recurring fees.

I want a Markdown "during-view"

I like that Markdown and its kin have been adopted by more than just the geek community. The simple inline directives do not take away the focus of writing the text and the formatting available covers most of needs. However, the trend to provide an immediate, fully formatted view of the text is misguided. These "previews" take away from the goal of maintaining focus on the text and not it's presentation.

However, I too like the comfort of a correctness that comes with seeing a full formatted document and especially so with regards to sections and lists. What Markdown editors need is not preview but a kind of WYSIWYG presentation that keeps the primacy on the text and secondarily on the structure of the text. A means of doing this is to present the inline directives with formatting and the directives too. Thus, when I type *emphasize me* it is shown in the editor as *emphasize me*. If I use a heading directive

A short work
it presented for editing as
A short work

I did once see this kind of editor in a Java wiki application, but I have long since lost my reference too it. Perhaps it will resurface again as the Markdown tools authors rediscover this style of editing.

I am not going to create another account just to use your feature

Dear Marco,

I really like the audio tools included in Overcast, but I am not going to create another account just to use them. I read the FAQ and while I understand that in general saving battery life is great, but, really, how much battery is used to check a few feeds once a day? So, good luck and keep me informed of the non-account version of Overcast.

What would one use programming for if programming were easy?

I stopped by Slashdot today and found Normal Humans Effectively Excluded From Developing Software. I read it and many of the comments and started to think about this problem again. In my mind the problem is if programming were easy then to what purpose would someone put programming too? I am going to assume that what is meant by programming is of a general purpose kind so that, for example, using R is not programming.

2014-07-10 Update: People collect and organize things and while they do that they share the experience, the lessons learned, and the things found. Would you program that?

To be continued...

Logging and the utility of message patterns

I wrote a logging layer over log4j sometime ago. The layer was to encourage our developers to log at any point in the code where they thought some extra context would help resolve runtime errors. And so the layer had to have a familiar API, be effortless to code, and cheap to call. This posting is mostly about the cost to call the logger.

When a message is not going to be used you don't want to incur the cost of creating it. How often have we seen logging code that looks like this

logger.debug("short explanation: v1="+v1+"; v2="+v2+";");
Here the logged message is composed before the call to logger.debug() and it is composed even if the logging level is above DEBUG. If v1 or v2 have a complex toString() implementation, then you add this compositional time to the calling cost too.

The simple solution is to use java.text.MessageFormat with the debug() method, for example

logger.debug("short explanation: v1={0}; v2={1};", v1, v2 );
In this way, the time cost to calling debug() is the time taken to push three values on to the stack, call the method, and pop the three values off the stack. No composition time (or memory) costs are incurred at all. (I handle exception messages the same way, that is, all exception constructors accept a message pattern and message parameters and the message string is not composed until it is actually needed.)

I have since replaced Java's MessageFormat with a (mostly) compatible local implementation. This local implementation does simple composition tasks like formatting numbers without commas and Unicode escaping all non-ASCII, and non-visual characters. However, the primary reason to implement a replacement was to expand the available format types and format styles.

The first new format type added was json so that now when a parameter is so typed its value is transformed to a JSON representation before adding to the message. For example,

Map<String,String[]> v1 = ...;
logger.debug("short explanation: v1={0,json}", v1 );

will convert v1 to a JSON string only if the log level is DEBUG

short explanation: v1={ "k1": [ "e1", "e2", ... ], "k2": [ ... ] }
(In hindsight it should have been a format style.) Today I added the string format type and two format styles. One format style specifies a substring of the value using a start index & length and the other a start & an end index. The start and end indexes can be given as numbers or as searches. For example, the style /foo/:10 specifies a 5 character substring starting where "foo" is first found, and the style /foo/../bar/ specifiers a substring between (and including) the two searches. The using search is particularly useful if you know that somewhere in a very long string is an identifier that would be useful to have in the log.

Basic human concern for the welfare of others

I had a surreal moment this morning while walking Milo at our usual spot. A car was found in the nearby pond. (I later found out that two cars were stolen last night and this was one of them.) I happened to encounter a small group of acquaintances running with their dogs. I told them what I knew and their immediate response was 1) having a car in the pond is not healthy for the pond and 2) why were the police leaving their cars idling. WTF! Not one of them expressed interest or concern for a person or persons that might be in the car. I was shocked at their lack of the basic human concern for the welfare of others. I will resist extrapolating this one data point to the causes of America's problems.

A gnuplot example

If you searched for Gnuplot in this blog you know I am a fan of the tool. It is easy to install, somewhat easy to use, and very likely someone has already had and solved the exact same problem you are having now and wrote a blog entry about it. This is my contribution to the globally distributed Gnuplot cookbook.

I want on a single chart the lines graphs of count of all queries, count of matching queries, and mean duration of all queries. This chart gives me the temperature of the previous day's query load which is a useful qualitative factor for capacity planning. The data retrieval results in records representing a 10 minute interval with counts of all queries, counts of matching queries, and mean durations. This is then plotted to give a chart like the following:

The file of records contains values that looks like

2014-07-07T00:10:00     10449   3850    934
2014-07-07T00:20:00     18445   5676    407
2014-07-07T00:30:00     18497   6507    535
2014-07-07T00:40:00     11419   4463    734
2014-07-07T00:50:00     11634   4454    724
2014-07-07T01:00:00     11960   5077    808

The Gnuplot script is

set terminal png size 800, 400 small interlace
set output "/tmp/chart.png"
set size ratio 0.5

set xdata time
set timefmt "%Y-%m-%dT%H:%M:%S"

set xlabel "Hour"
set format x "%H:%M"

set ylabel "Count"
set ytics nomirror
set yrange [0:40000]

set y2label "Milliseconds"
set y2tics
set y2range [0:4000]

set title "MetaData matching search counts and average durations (10 min intervals) for 2014-07-07"

plot \
  "/tmp/chart.data" using 1:2 title "Query count" with lines, \
  "/tmp/chart.data" using 1:3 title "Matching count" with lines, \
  "/tmp/chart.data" using 1:4 title "Request duration" axes x1y2 with lines

The chart is produced daily and it is useful to visually align several days of charts to look for patterns. For comparable charts this requires that the charts all have the same y-axes ranges. To do this Gnuplot's range setting is used. If you do not want a fixed range then remove the set yrange ... and set y2range ... lines.

I hope this helps someone else with their Gnuplot use.

Atlassian has forgotten that Jira is a communication tool

Atlassian has forgotten that Jira is a communication tool. Comments need numbers so the team can communicate with specificity everywhere. See Skype and development teams as it applies to Jira also.

No more chickens

The last of our chickens were attacked last night. Two dead and one so badly mauled that it had to be put down. Our home is once again without the soothing sounds of chickens humming their songs as they explore and sun-bathe in the garden's beds.

Restic to the flame

I bought a copy of Dreadball earlier this year mostly to have a sports boardgame that Henry and I could play. (Owen is happy playing non-sports oriented games.) The material used for the Dreadball figures is, what has come to be called, "restic" -- some combination of resin and plastic. It has a reputation of being difficult to prepare for painting. (For a counter experience read How to clean restic.) One piece of advice I read in the comments section of Seeking advice on preparing the minis for play was to flash the flashing with a cigarette lighter's flame. After too many hours of trimming with a knife I decided the give the flame a go. The basic approach is to warm the material enough so that you can smooth out the heavier flashing with your thumb and for the lighter flashing to burn off. And, after a little trial and error, it does work. However, for detailed, thinly molded elements of the figure you still need to just use a knife. Using the flame often ends with stumpy ears and hands. Even with the few errors the figures look fine after priming.

Walter Dean Myers and Henry

I was very sad to hear that Walter Dean Myers died today. While he wrote for young adults I enjoyed reading them as did my son Henry. It was Walter Dean Myers' books that got Henry to keep reading fiction outside of school.

Skype and development teams

My employer extensively uses Skype to coordinate and communicate. (Email is almost unused.) Within a software development team there are some regular annoyances that come from Skype's current design. I don't blame Skype or Microsoft for this situation as I think we are using the wrong messaging tool. However, using Skype in my team has clarified what the messaging tool needs. The changes that would make Skype better for software development teams are
  1. Use a fixed format font for sender and receiver because we still manually align tabular data and draw ASCII diagrams.
  2. Don't interpret any of the message text as emoticons, links, telephone numbers, etc. Most of the time the interpretation is inappropriate.
  3. Identify every message in a conversation so they can be referenced. We use specific identifiers -- file paths, line numbers, revision numbers, etc -- because specific referencing means that all parties in the conversation are using the same data. Use a simple initialssequence number identifier for ease of typing. (No UUIDs, please.)
  4. Includes images in conversations. Images are only slightly less important than text to a successful conversation.
  5. Show more messages on the screen. Do this not by making the font smaller, but by reorienting the message presentation to take advantage of monitors having more width than height.
What do you want to change?

Update: I would add tabular data to images as another first class data type. For example, I like how I can copy a SQL select result from DBeaver or SQuirreLSQL and paste it into Jira.

Wanted: Portable worktop and toolbox

Leo and I were talking about our first-world troubles of 1) not having a permanent miniatures painting station and 2) the that the temporary one we do have takes us away from the family at night. I have tried multiple ​solutions but so far nothing has stuck as work​ing​. In general, what I think I want is a portable worktop and toolbox. This way I can quickly retrieve it & open it up for working and later close it & store it away. The following have been inspiring and all within my skill level and with tools I have available​


I really like how this has a proper place for each item and that the work surface is quite wide.​


This one reminds me of the old portable writing desk​s. I like that it has draw for storage but that this is under the work surface is going to be inconvenient too often.


While not strictly as portable a worktop as the others, it is f'n awesome! and has many great ideas.

​I did make the following as an experiment of a least complex solution -- a wide box with lid that acts as copyholder and support for built-in lighting.

But, in the end, I did not like it. I mostly did not like that when the lid is open it blocks my view of the room and family. I have not put any time into designing an alternative yet -- but I will.​

Using standard open dialog box in NetBeans

You can have NetBeans use OS X's standard open dialog instead of the poor Swing alternative. To do this, update your "netbeans.conf", mine is at /Applications/NetBeans/NetBeans\ 7.3.1.app/Contents/Resources/NetBeans/etc/netbeans.conf, to include the flag "-J-Dnb.native.filechooser=true" in the "netbeans_default_options" property.

iPhones and camera lens lint

My iPhone 5 has lint between the camera lens and the external housing. I had the same problem with my iPhone 3G. Is this a common problem for folks who do not put their iPhone in a case and keep the phone inside their pants front pocket?

Using greenstuff

I am about to convert a female fantasy figure into a dark age warrior. I have clipped off the fantasy weapon, modified a hand to hold a sword, and the other hand to hold a shield. Now I have to reduce the exposed cleavage and so will be using some "greenstuff" to cloth her. Since I have never done this before I looked on YouTube.com for tutorials. While there are many, I thought this one on making a cape was especially helpful

Dip 'n Spin

I have been playing with "dip" again to quickly apply shading to my minis. The Army Painter Dark Tone is, essentially, a black stain. The results are too black for my liking: everyone looks like they just emerged from a coal mine. Not wanting to spend another $30 on the Strong Tone I picked up a small can of Minwax Polyshade Antique Walnut. This I like much better. It might also be that for dark age Welsh it is just seems more appropriate. That is, the minis look grubby. There are many tutorials on how to apply these products so I won't go into that here. Instead, I just want to put another plug in for using soda bottle caps and necks.

When using stains you have to remove the excess. Most folks don't actually dip the mini in the stain but instead dab the stain on with a sacrificial brush. Then, as the stain pools, using the same brush to remove the excess. Well, I wanted to try dipping and so I needed a means of removing the excessive excess stain this leaves on the mini. Flicking was not in the cards. Instead, I hot glued a soda bottle neck to a stick, attached the stick to a drill, screwed the bottle cap attached mini on, and gave it a spin!

It does work. However, either my drill does not spin fast enough or I need a more random motion as too much stain remains. And so you need to go back to the mini with a brush and remove the remaining excess. All in all, the dabbing method is the most effective.

For related postings see wargames.

English Language & Usage Stack Exchange

I am clearly the last person to ask about English language usage, but I am very interested in its edge cases. I subscribe to the http://english.stackexchange.com/ weekly newsletter and find it fascinating. My guess is, you would too.

Want a simple, synchronized shared scrapbook

I have all these local, really high tech hardware, software, & networks on my desk and the only easy way for me to copy a URL from iPhone to Mac and vis versa is via a text message (I use Skype to SMS). All I want is a simple, synchronized shared scrapbook for text and images between all my devices. Can someone please make this happen?

Update: A friend suggested Pushbullet. It looks to be a useful service, but I really don't want another account just for this small need. From reading between the lines, Pushbullet looks to do nothing more than coordinate a Google Drive document (or folder of documents). Which I can also do with a URL bookmark. Which I did. This seems to work well.

SAGA Links

The "Wednesday Gamers" will be playing SAGA starting next week. (Even if our minis are only primed!). To help prepare the gamers I collected this list of SAGA links.

Meeples & Miniatures's Review
SAGA First Look
The Tapestry (dedicated to SAGA)
Battle Boards for Dummies
Board Game Geek's SAGA page
How to play SAGA
SAGA Dark Age Skirmish Game Tournament Report

If you have any good links please do add them in the comments.

Podcasts I listen to on a regular basis

Long Now Foundation's Seminars
Really great set of 1-1:30 hour lectures on many topics but mostly about long term thinking and experiences.

Science for the People
Topical science interviews

The British History Podcast
Great presentation of UK history from the beginning

The D6 Generation
Boardgames and more.

Meeples & Miniatures
Military, fantasy, and science fiction miniature wargames

The Memory Palace
Forgotten people doing big and small things

History of medicine

You are not so smart
The qualities of thinking and our flaws

Futility Closet
Trivia and oddities from the past

"There are, too, elves in Mirkwood!"

When walking Milo yesterday he and I passed several boys (16 ish) playing tennis. They were your usual generic white suburban kids talking tough to one up each other. We continued our walk. On the way back we pass them again and overheard one retelling a recent conversation:

Him: There are, too, elves in Mirkwood!

Other: No there arn't. Only Rivendale has elves.

Him: Well, of course Rivendale has Elves you dumb ass. We are discussing Mirkwood!

Luckily, they did not see me and Milo grinning.

Bruce Sterling at Webstock '13

We live in the time of "dark euphoria." "The Web had users. The Stacks have livestock." Other deep insights. And, if you are at all concerned about where LOLcats are taking us then keep listening after the 25 min mark.

Webstock '13: Bruce Sterling - What a feeling! from Webstock on Vimeo.

Update: A old friend says that what is being said are less deep insights and more genre's tropes. His presentation of these ideas was new to me, however.

A system for mounting my miniatures

I finally have a comfortable system for mounting my miniatures while painting them. I have tried mounting with sticky gums, but this leave a residue and/or can be a bugger to get off. I have tried glueing with PVA, but adhesion is too weak and ended with models flying off into the grass as I spray primed them. I have tried using hot glue, but adhesion is too strong and ended with several broken legs while detaching the models.

In the end I settled on using 3M's 1/2" Double Sided Mounting Tape Squares and soda bottle caps. The squares are right sized, precut, many (90 per pack), cheap, and hold the model firmly.

Here are my current steps to mounting and priming.

Awesome worktable

This portable worktable and instructions on building it are awesome. I don't need it, but want to build it anyway.

More at Maker Station.

Installing Java 6 on OS X Mavericks, again.

I needed to have Java 1.6 run on OS X 1.9, Mavericks. I had written about this before in Installing Java 6 on OS X Mavericks, but I was not confident with the solution. Today I decided to install Apple's Java 1.6 and see what happened. Would I have have to rebuild my whole machine? No. Nothing bad happened and so far so good. So, to install Java 1.6 do the following:

Download and install Java 1.6 from http://support.apple.com/kb/dl1572 and install.

Set Java 1.6 as your default using

/usr/libexec/java_home -v 1.6
For more information on java_home see superuser.com.

I need to use NetBeans 7.3.1 (newer versions require Java 1.7) which is downloaded from https://netbeans.org/downloads/7.3.1.

To ensure that NetBeans runs using Java 1.6 edit the configuration file /Applications/NetBeans/NetBeans 7.3.1.app/Contents/Resources/NetBeans/etc/netbeans.conf -- which is actually a bash script! -- and define the netbeans_jdkhome environment variable

netbeans_jdkhome=$(/usr/libexec/java_home -v 1.6)

And that is it. You now have Java 6 and Java 7 on your Mac. If you want Java 1.6 to be the default for you always then add the following to your rc script

export JAVA_HOME=$(/usr/libexec/java_home -v 1.6)

15,000 unorganized photos

I have some 15,000 photos that are unorganized. In part, this is because of the rapid changes in both camera and computers used. Thankfully, they are backed up. So, a second step is organizing them is to group them by year and month. I don't think I need day, but that might change. Most of the photos have encoded within them the date and time they were taken. To organize them I just need this data and a means to associate them. The following Perl script does this by using the Image::MetaData::JPEG module, dated directories, and symbolic links.


find ~/Dropbox -type f \( -iname '*.jpeg' -o -iname '*.jpg' \) \
| perl organize.pl ./PICTURES 2>/dev/null >./PICTURES.sh

Once the PICTURES.sh script has been made it can be run using

bash -xe PICTURES.sh 2>&1 >PICTURES.log

The Perl script organize.pl is

#!/usr/bin/perl -w

use strict;
use Image::MetaData::JPEG;

my $root = shift @ARGV;
die "root is not a directory" unless defined $root && -d $root;

my $count = 10000;

my %mkdirs = ();

while ( my $file = <> ) {
  chomp $file;

  my $dir = "unusable";

  my $image = new Image::MetaData::JPEG($file);
  if ( defined $image ) {
    my $metadata = $image->get_Exif_data('IMAGE_DATA', 'TEXTUAL');
    if ( exists  $metadata->{DateTimeOriginal} && $metadata->{DateTimeOriginal}->[0] =~ /^(\d\d\d\d):(\d\d)/ ) {
      $dir = "$1/$2";            
    else {
      $dir = "undated";

  unless ( exists $mkdirs{$dir} ) {
    print "mkdir -p $root/$dir\n";
    $mkdirs{$dir} = 1;

  my $efile = $file; $efile =~ s/([^a-zA-Z0-9_\.\/])/\\$1/g;
  print "ln -s $efile $root/$dir/$count.jpg\n";

  $count += 1;

And why is this the second step? Because removing duplicates is the first.

Update: I did use this to organize my photographs held in DropBox. I replaced the symbolic link command with a move command. DropBox just moved the files and not, as I was worried about, re-upload the whole collection. Thank you DropBox engineering.

Watching calligraphic theater and paint dry

Watching 1) calligraphic theater and 2) paint dry.

Street typography from Tom Williams on Vimeo.

Letter to the Editor: The current pilot project does not address the 1:1 issues

This week's South County Independent newspaper has an article on the school district's 1:1 initiative. Unfortunately, there is a gross misrepresentation of my thinking on the matter and one statement that is attributed to me might get me lynched by the teachers! Here is my response.

Letter to the Editor:

We should expect our high school students to have the means of engaging with their work, their peers, their teachers, and their administration at all times. It is significant that the school district is moving forward to supporting this. Where I am at odds with the school district is with the pilot's actual focus, the speed and approach of the process, and its entanglement with PARCC testing.

Let us first make clear what "one-to-one" (1:1) means. It is one device per student that is available all day and every day inside and outside of school. Preparing our students for college or career is to prepare them for continuous engagement and interaction. Working as needed, when needed, with current and relevant materials, with the appropriate people, and all without regard to location or time zone.

The current pilot project does not address the 1:1 issues. What the pilot does is to repeat the work done by hundreds of other school districts across the country and that is to provide laptops to teachers for student use for specific classroom instruction. In short, the laptops are lab equipment. $98,000 of lab equipment and one instructor (FTE).

The school district is heading quickly down the wrong road. The only public meeting on this was in November 2013 when BYOD ("bring your own device") plan was, rightly, abandoned and 1:1 became the new plan. Four months later the "devices", "professional development", and "finance" committees were created to plan the work. The teachers and students have yet to be involved in the planning and yet we expect everything needing to change to be ready by August 2014.

We don't need to rush. I suggest that there first needs to be a plan as to how the freshmen teachers (as a whole) will use 1:1. Let us use the 2014 summer and the 2014 fall to figure this out. Use a portion of the pilot's allocated money to contract for the help and buy some equipment and services to learn with. And please let us have the students engaged in this work too. Only then let us work out the specific devices, professional development, and finances needed in the 2014 winter and 2015 spring. Have everything in place for the 2015 fall.

Yours truly,
Andrew Gilmartin

For related postings see one-to-one.

James Burke and transitioning from a world designed to mitigate scarcity to one of controlling abundance

James Burke's TV series Connections made a significant impression on me when I was a teenager and has continued into my adulthood. My worldview of our past, present, and future situations is premised on it being brought about by a very long line of related and, and this is really important, seemingly unrelated changes. This is obvious to historians but not so to a 15 year old and, unfortunately, not so for far too many of my contemporaries -- especially here in the USA. This week I was happy to come across a recent interview with Burke at You are not so smart podcast. In the interview Burke discusses his current project of envisioning the transition of a world designed to mitigate scarcity to one of controlling abundance. Well worth a listen.

What if by the fall of 2015 the high school had a high bandwidth & low latency cell data service?

What if by the fall of 2015 South Kingstown, RI and the high school (in particular) had a high bandwidth & low latency cell data service? No matter where a student was in town he or she would have access to the school's and the world's resources? If this were so, would we want to invest in a campus wide wifi? Or would we instead provide 1:1 devices with a cellular modem and pay a monthly service fee to a carrier?

For related postings see one-to-one.

PARCC and the image of the assembly line worker.

When you visit the Partnership for Assessment of Readiness for College and Careers website and the first image you see is

When I see this image I think "assembly line worker." And I then wonder and worry about how much PARCC really understands "readiness for college and careers"?

For related postings see one-to-one.

Asked to continue to be involved with 1:1

I have been asked to continue to be involved with the South Kingstown School District's one-to-one initiative (1:1). I am not sure how to do that now. I kind of burned all my bridges on the way out. And I continue to believe we are also going about it in a rush and so the whole endeavor needs to be replanned.

I really think that there first needs to be a plan as to how the freshmen teachers will use 1:1. Let's take the 2014 summer and the 2014 fall to figure this out. Use a portion of the allocated money to contract for help and buy some equipment and services to learn with. And have the students engaged in this work too. Only then work out the specific devices and finances needed in the 2014 winter and 2015 spring. Have everything in place for the 2015 fall.

With regard to PARCC testing needs, buy as many cheap Chromebooks as needed and consider it a sunk cost. See New Device Costs per Year.

I see no need to rush 1:1 and no need to tie it to PARCC testing today.

What to do?

For related postings see one-to-one.

Prime with white and wash with black

I was watching 12 Different Ways to Prime Your Wargaming Miniatures for inspiration -- aka the continuation of my procrastination and my life generally getting in the way of my hobby -- and so tried a few of the painter's suggestions. The one I really liked was to prime with white and then wash with black.

I only washed where there was a transition and the larger areas that were intended to be dark. I also washed with acrylic and not oil paint. I think it worked well. And WAY better than Army Painter's expensive "dip".

If you find the knight's sword send me a note.

Testing for the presence of a value

Back to some geek content... How often have you seen code like the following?

if ( foo.getBar() != null ) { /* use the value */ }
The code is testing if the foo object has a bar value. This usage seems innocuous, but it is not. It both hinders readability and refactoring. Let's address readability first.

The test is asking that the user of the class infer the presence of a value. However, it does not test for a value, but, instead, for the absence of a value, the none value. For readability, don't make the user guess what is happening but, instead, make what is happening explicit. Now, on to refactoring.

The none value test actually exposes an internal implementation of the class to the user of the class. What if a refactoring requires that the internal implementation of the none value change? A common change, for example, is for a null to be replaced with a sentinel value [1]. Should this happen then all uses of the class will have to be changed because the none value test is ineffective. Moreover, the ineffective test will not break the running code, but instead send execution down the then conditional path. Let's hope that no life or treasure is affected.

When you have all the use code under your control then the change is manageable. You will end up with an excessively sized patch that will dwarf the purposeful change. When the use code is not under your control then a ramification is that the simple, internal change is now a global external change. So what is to be done?

To improved readability and facilitate refactoring simply include an explicit test for bar.

if ( foo.hasBar() ) { /* use the value * }
The purpose of the test is clear and use does not expose an internal value.

[1] http://en.wikipedia.org/wiki/Sentinel_value

The pilot does not address any significant issues raised by one-to-one

Well, I resigned from the South Kingstown school district's Technology Professional Development and Curriculum subcommittee after only two meetings. I am unsure if this was a good idea, but I am sure that I do not want to be associated with the subcommittee's outcome. The work ahead is little more than a backfilling of work that should have been completed before the one-to-one (device per high school student) pilot project was scheduled.

The pilot, as presented so far, and as I surmise from the already decided upon pilot factors -- the device choice, specialized staff, budgeting, and the need to finance PARCC testing -- does not prepare the SK school district for one-to-one in the 2015/2016 school year.

The pilot does not address any significant issues raised by one-to-one. The pilot will put laptops in the classroom on carts -- colloquially known as COWs, computers on wheels. Existing models and ramifications of doing this are readily available and well understood. There is 20 years of documented and reviewed research and practice. (I did this kind of work in the mid 1980s.) If you want something more contemporary then travel just up route 138 to the Green School and ask about their experiences.

Computers in the classroom does not differ from bunsen burners in the classroom. That is, they are both lab equipment that will be used to support subject specific lessons. One-to-one is about augmenting one's thinking and communication and has almost nothing to do with the tool itself. That is, while I might advocate for tablets and someone else for laptops, in the end either device will serve the same end. (I would like to address costs but that would take away from my focus of this email.) Has your intellectual life been vitally affected by a bunsen burner?

Here is a thought experiment. Some years ago you worked exclusively with a desktop computer. Today you work exclusively with a laptop. Some years ago content access was limited to in-house only. Today, not only is that not the case, but there is the expectation of equal access from anywhere. With these changes, how has your work life changed? Can you imagine working as you once did -- at a specific desktop and only when in the office?

For students learning is their work. They must have the same experience as you do today with your ever present device and the access to software tools and content it affords. That is one-to-one. That is what SK school district needs to pilot.

For related postings see one-to-one.

A vision of a near future high school classroom

One of my concerns coming out of Friday's meeting of the South Kingstown school district's Technology Professional Development and Curriculum subcommittee meeting was the lack of articulated visions. Some of this, I am sure, is due to my not being involved in previous discussions. To help myself, I took some time this weekend and wrote a vision of a near future classroom. This vision does not use any software or hardware that is not available today and available at modest costs. The working document is at


A vision of a near future classroom

Andrew Gilmartin, 2014-02-28, revision 7

I am not a teacher, so this view of a class is an outside view. The teacher is Joe Smith. On days with odd number dates he teaches chemistry and on even dates he teaches French.

The students enter the classroom for a long class. The classroom is much like any other classroom with student work and inspirational posters on the walls, shelves of books, and piles of ephemera. What is different is that there is no teacher’s desk and no students’ desks. Instead, the center of the room is taken up by a table with seating for all and against the walls is a continuous workbench.

The students take a seat at the table. They jostle and chat as happens before every meeting everywhere. Some students submit last minute “independent work” and “group work” to the document store. The work might no longer be literally handed in but it still needs to arrive on time.

The teacher sits with the students. He and they are always facing each other. He asks one student to call the class to order and initiate the status update. Each student succinctly says what they did since the last class, what obstacles hindered their work, and what is planned for the next class. Another student takes notes on the status updates and deposits them into the document store. The teacher will use the status updates to track progress and understand who needs help, who can help, and what the class needs to move forward.

The students were expected to prepare for today’s class beforehand. They usually have a few days to do this outside of school and in free time during the school day. The preparation includes reading source material (primary and secondary) and the class’s agenda. The teacher briefly reviews the preparatory material and initiates a discussion. The students are expected to participate back and forth. Some students are comfortable with free discussion. Other students will need some structure and aids. Some would rather not be there at all. In all cases the students have learned to be respectful of one another’s learning modes. The students are encouraged and aided in using verbal and visual modes, and physical models (no interpretive dance, however).

The semester’s syllabus, schedule, and preparatory material are available in the document store. Students wishing to work ahead can do so as readily as students wishing to revisit the past or already completed materials. Where source material is an advancement of previous source material it is cross-linked and further linked to the students’ existing notes and finished work.

There is very little difference between preparatory material now as when it was printed in books. That is, the vast majority of it is read. It is supplemented by videos of exemplary lectures from one or more institutions, interactive visual models, theatrical productions (student and professional), self diagnostics with results linked to relevant remedial materials, and offers of one-on-one in-person tutoring. In all cases, the students are expected to help themselves as much as being helped. (Self-management is a skill that is taught and emphasized throughout the school day.)

The tools used to review the materials allow for group and individual annotations. Note taking and other learning skills are under constant review, development, and coaching as the student and teacher discover what works best. The teacher reviews the student’s notes as frequently as the finished work. The student’s notes and class participation represent where the student is in understanding the materials and being able to apply them in novel situations. Learning happens not in discrete, fixed periods of the day and week. It is a continual experience with times of intensity, times of reflection, and times of rest. The student’s tools need to support this.

Each class agenda is presented multiple times at different times each day during the week. While each agenda presentation typically has the same students attend, any student can attend -- perhaps the student missed their usual time this week or perhaps they just need to be exposed to it again. (Other aspects of the “school day” may need to change too.)

The document store is the critical change in teacher and student tools. The store holds all the class’ content -- teacher’s, student’s, and administration’s. All content is owned, dated, secured, and shared. Content has its own life. Every revision of the content is available for review and comparison -- answering the questions, “What changed between versions?” and “Show me your work.” The content can be presented in many perspectives, for example, by date, student, class, teacher, curriculum, or subject.

The second critical change is the device employed to use and create the content. The device needs to be with the student and the teacher at all times. Learning is an all day, every day activity, and especially so for students and teachers who need to schedule active lives inside and outside of the school building. The first capability of the device is to allow access from anywhere to the document store even in low bandwidth situations. The second capability is adding written, and still and moving visual content to the store. (This is done in a direct manner with light editing.) The third capability is to act as a conduit between the document store and advanced and/or special purpose devices. For example, a student wants to record the images from a digital microscope to the document store, or the student wants to store the final edit of a stop-motion video.

The student’s device is expected to be expendable. These devices will have a rough life, living at the intersections of backpack and bedroom, living room, classroom, cafe table, and playing fields. The devices are inexpensive and supplemented with a ruggedized exoskeleton. Most interaction with the device is through the touch screen, but physical keyboards are available for temporary use throughout the school and for permanent use at home. This vision does not use any software or hardware that is not available today. And, it is available at modest costs.


Since I wrote this, I have been shown and discovered some supporting materials.

Exemplary device is a Nook HD+ with Cyanogen mod at $179

Harkness table

The Power of Collaborative Learning
Oakland, CA’s The College Preparatory School

Remake Your Class: Building a Collaborative Learning Environment


For related postings see one-to-one.

Rapid Hemostasis System for Gunshot Wounds

The mournful side of playing wargames is that in real life the toys we play with are real and people get hurt and killed. In my readings today I came across this interesting medical field aid, XStat Rapid Hemostasis System for Gunshot Wounds Works in 15 Seconds. Let's hope this helps save lives.

Funders should own failed Kickstarter project IP

It has long bothered me that established firms use Kickstarter to fund product development. Especially so in the boardgame and miniature games area. Established firms have other means of getting funding and getting it from funders that better understand the risks. Further, why would one want to support any established firm that is putting their own customers at risk? The recent failure of Torn Armor (of Torn Worlds [1]) is a good example of this.

In the venture capital world the funder at least gets the assets of the failed product. These assets have real value. Why don't Kickstarter funders ask for the same conditions? That is, when an established firm is looking to fund product development then the assets developed with the funding must be returned to the funders on failure. For a game product this would include the sculpts -- 3D models and "Greens" --, artwork, rules, and backstory, for example. The funders are then free to do what they want to do privately & individually with the assets or publicly & collectively.

[1] Torn Armor Kickstarter encounters a problem with Defiance Games

Benjamin Bratton: Why don't the bright futures promised in TED talks come true?

I really like this talk. It is not an anti-TED talk but more of a bitch-slap, wake the fuck up kind of a talk. The most poignant comment I have read is "It says that our complacency is unsustainable in the long run." Read the comments on (UK's) The Guardian's site too.

A Common Core study group

I have two boys going into public high school next year and I am concerned. When I first heard about the Common Core educational standards I was hopeful that they would establish an appropriate bar for both educating our children and, in part, evaluating their teachers. Since then I have heard, read, and seen far more opposition to the Common Core than support for it. I think it is time for me to understand the Common Core for high school. And for this I need to read and understand it. Doing so alone and without guidance and/or interpretation is mostly likely impractical. In the past I have benefited from using a study group to understand our state's budget. I think I need the same here.

If you are interested in creating a Common Core study group please contact me either via Facebook, email at andrew@andrewgilmartin.com, or telephone 401-441-2062.

Installing Java 6 on OS X Mavericks

I need to be able to build and run Java tools under Java 6. When I got my new MacBook Pro I also got an unexpected problem and that is that there is no Java 6 for OS X 10.9. Or perhaps I should say that I did not know enough to know if I could get Java 6 for OS X 10.9. And so the machine become used as a very fast web browser.

Today I decided to make some effort to get Java 6 running. If this machine were Linux or Windows I would not have this issue. The Java packages for these operating systems use the standard Java distribution and configuration. Not so with Apple's Java. It seems like a mess to me when I compare both the standard distribution's file and directory names to Apple's and even between Apple's OS X Java 6 and Oracle's OS X Java 7. Clearly, I am not an Apple developer.

Apple's Java 6 package can be downloaded from http://support.apple.com/kb/DL1572.

I don't really need Java 6 to run, I only need Java 7 to compile and run like Java 6. And for this I only need to configure the existing Java 7 javac and java commands correctly. I am glad of this as I have no confidence that Apple's Java 6 installer will leave my existing Java 7 installation working. I will need to cheery pick what I want from Apple's Java 6 installation package ... and hope for the best. And hoping for the best is acceptable as, after all, this MacBook Pro is a development machine and so it can be a little rough and idiosyncratic.

I used the shareware tool Pacifist to extract the JavaForOSX.pkg sub-package to my ~/lib/ directory. (Pacifist is very easy to use and so I could skip understanding pkgutil.) I renamed the installed root directory from "JavaForOSX Folder" to ~/lib/jdk1.6.0 and fixed the permissions.

My builds are handled by Ant and so I need to tell the javac task to use Java 6 for source and target, and to point the bootclass to the Java 6 jars.

<path id="java6.bootclasspath">
  <fileset dir="${env.HOME}/lib/jdk1.6.0/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes">
    <include name="**/*.jar"/>
  ... >

The compile now works. Have not yet tried to run, however. Running is for another day.