True is true and false is false.

If you send me to code examples containing either of the following you are not going to be hired, ever.

test ? true : false

if ( test ) { return true; } return false;

Letter to SC about Blended Learning

My letter to the South Kingstown School Committee of my grave concerns about the administration's objective for Blended Learning in our schools. It is mostly a reworking of an earlier blog posting.


"programs you depend on are written by dicks and idiots"

Good programming rant Programming Sucks. Take way is "programs you depend on are written by dicks and idiots." Say it loud brother.

Blended Learning

Yesterday I had the opportunity to talk with the High School’s new Principal Robert Mezzanotte and the STEM Coordinator Simone Palmer. The purpose of the meeting was to provide fuller answers to my 10 questions to the Superintendent of a few weeks ago. The meeting went as one would expect. And, as in many meeting that includes people, it was the side comments made and comments missing that were significant.

The Principal said that the successful introduction of “Blended Learning“ was his first priority. Until a week or so ago I had not heard of Blended Learning. Or if I had, I had assumed the term was the new educational term for computers in the classroom. It is not. Blended Learning is an approach to achieving an end goal of personalized student education through the use of technology for instruction. Let me try to explain.

High Schools use the same method of instruction today that I had when I attended. A teacher presents the same instruction to all students sitting in formation facing her. In the Blended Learning community this is called Traditional Instruction learning.

Before I move on, keep this diagram handy.

From Traditional Instruction the instruction and learning will move to Macro Differentiated learning. Here the teacher teaches to groups of students in the classroom. Each group is composed of students at the same “content level,” that is, the  a group of kids that “get it”, a group of kids that “don’t get it” and groups of kids that “sorta get it.” The teacher made the decision as to the groupings. The teacher will rotate between the groups over the duration of the class period. The teacher continues to drive the instruction (short lectures to small groups) and the instructional materials are not expected or, rather, not required to be online. (The online part is an efficiency that becomes important later, so keep watch.)

From Macro Differentiation the instruction and learning will move to Micro Differentiated learning. Here the teacher works with more and smaller groups of students. Some groups contain just one student — the smartest and the dumbest. When a teacher is not attending to a group that group will be busy learning from instruction delivered online and assessed continuously online. Progress is a calculation without  allowance to character or circumstances.

From Micro Differentiation the instruction and learning will move to Individual Mastery learning. Here all students have individualized online instruction, tutoring, and assessment. The teachers are available for coaching as are their peers — that is student to student coaching. Each lesson is a step in a chain without variance. Only the speed that the student moves along it is different. To be fair, each link in the chain may contain different content richness for the kids that “get it” and the ones that “don’t get it.”

From Individual Mastery we come to Blended Learning’s final destination of Fully Personalized learning. Here the student is master and commander of their own education. Directed by their own interests. A classroom is now a selection from an online catalog of available syllabi. Assessment is automatic and continuous. Peer to peer coaching and evaluation is routine. Learning has become “teacher-proof”. If you still have the diagram open, the information visual for Fully Personalized has a teacher sitting outside the student's learning. There is no direct connection between the two.

I am quite unsure where the teachers are in the Fully Personalized form of learning. The obvious place is an educational utopia where instruction is undifferentially produced for a student ideal that is hermetically delivered without an atom harmed. I might be overthinking this.
I don’t want Blended Learning. How about you?

"Specializing in what I have not done before."

Paul Kahn, one of the two founders of Dynamic Diagrams, once described his design agency as "specializing in what they have not done before." As I work to understand how secondary education is using technology in the classroom in the light of Federal, State, and local obligations and expectations I am constantly reminded of Paul's maxim and of avoiding being little more than a dilettante.

A visual hack for organizing your notes

I am always advocating for keeping and carrying only one notebook for all projects. Maintaining a single notebook does have its own problems and so I watch for interesting solutions to them. One problem is how to quickly find project specific notes? This solution is a simple means to visually organize the notebook's content.

From Japan, a Brilliant Notebook Hack for Organizing Your Notes: A simple trick to easily index and find the information you need

I am reminded that it is time to revisit my Keeping Your Academic Shit Together document.

Small things matter

A method we have in our common library is a check that a string is null, empty, or contains only whitespace. I suspect everyone has this method somewhere in their code. Ours was written a decade ago and we have not had need to replace it -- it works and has no obvious downside to normal operations.

However, every now and then I am reminded of something I learned at Tazz Networks when one of the teams was reviewing performance bottlenecks. The code that lowercased unicode strings was contributing to well over 1% of the total running time. The only reason for this high overhead was that at no time did anyone -- senior or junior -- state what the standard letter case was for hash table keys. And so, for example, the key butter was found in the code as "Butter", "butter", "BUTTER", and my favorite k.upper() only to lowered soon after! None of theses uses came from outside of the system (that is, user data) and so the development organization had complete control over their representation.

So what about the empty string check? The code is

return s == null || s.trim().length() == 0;

The use of trim always bothered me because it allocates a new string containing the original string without the leading and trailing whitespace. I would have been less bothered, perhaps, if we used this check infrequently, but some of the core code needs to check for empty because the development organization never set the standard for an empty string. If all empty strings could to guaranteed to be of zero length or, better yet, a sentinel value then the check would then be

return string == EMPTY_STRING

which is going to be very fast.

So, for now, the empty check has to look at the content of the string. I replaced the original check code with

if (s != null) {
    for (int l = s.length(), i = 0; i < l; i++) {
        if (!Character.isWhitespace(s.charAt(i))) {
            return false;
        }
    }
}
return true;

In the case where the candidate string is the empty string or a string without leading whitespace this implementation is about 18% faster (100M iterations). When the candidate string contains just one leading whitespace it is 481% faster. The candidate string needs 34 leading whitespace characters before the two methods have similar run times.

I am going to keep the new code. Small things matter. Especially, when frequently used.

Update revision date with Google App Script

I was bitching about what Google Documents is missing for technical documents. Which, in all honestly, is not much, especially, in the light of the revision and collaboration tools it does have -- and had on its first day.
Since I like to have revision dates and numbers in my documents how hard could it be to script their automatic update. Not hard at all. The following script will add an "Update Revision" menu item to a "Scripts" menu and when invoked it will replace all occurances of "Revision YYYY-MM-DD HH:MM" in headers, footers, and the body with the current timestamp.
function onOpen() {
  DocumentApp.getUi().createMenu('Scripts')
      .addItem('Update Revision', 'updateRevisionTimestamp')
      .addToUi();
};

function updateRevisionTimestamp() {
  var doc = DocumentApp.getActiveDocument();
  var date = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy-MM-dd HH:mm");
  var revisionPattern = "Revision [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}";
  var revisionReplacement = "Revision " + date;
  var body = doc.getBody();
  if ( body ) {
    body.replaceText(revisionPattern, revisionReplacement);
  }
  var footer = doc.getFooter();
  if ( footer ) {
    footer.replaceText(revisionPattern, revisionReplacement);
  }
  var header = doc.getHeader();
  if ( header ) {
    header.replaceText(revisionPattern, revisionReplacement);
  }
  return doc;  
}

Jolokia is remote JMX with JSON over HTTP.

We use JMX a lot for low level, dynamic management of our systems. Even the most basic of MBean implementation that uses the "MBean" interface suffix and one concrete class implementation is far better than nothing. With our commitment to using JMX we have, over the years, developed a set of Java annotations and machinery to publish POJOs as MBeans.

We continue to use JConsole, over Java Visual VM, because of its utter simplicity. The tool does have some issues, but we know them well and they do not distract from the need to manage something quickly. The one area where this tool and other tools that I am aware of fall down is making the same change on several deployments.

For this we fall back to using the bash shell and Jolokia. Jolokia is remote JMX with JSON over HTTP. It is a servlet that is part of our standard Tomcat deployment. We have been using it for many years and it has not failed us yet. So, if I need to change some state on all our machines I run

for h in $HOST_DEPLOYMENTS
do
    curl "http://$h/jmx/write/object-name/attribute-name/new-value &
done

Where object name, etc are replaced as expected. (Curl is normally called with --silent and --fail command line options.)

Mistake-Proofing & software poka-yokes

Chase's & Stewart's Mistake-Proofing is a useful read about the theory and practice of avoiding mistakes in manufacturing and service. It is a short book and so just skims the surface of the field, but it gave me enough information to better understand some problems my software development organization has with its "manufacturing."

The problem we have is that we don't so much have a data pipeline with state change at the joints, ie fixed points in the flow, but more a leaky data pipe where the leaks are the state changes. (We inherited much of this code from a systems integrator hired before my time.) Changing the whole flow is not possible right now and so how can we mistake-proof the leaks?

Mistake-Proofing advocates poka-yokes as a means to avoiding mistakes. The term is from Japan, where all the quality focused manufacturing ideas have come from since Deming arrived after WWII! It means to avoid (yokeru) mistakes (poka). We see them all the time all around us. Some are actual devices -- the car engine won't start unless the clutch is depressed -- and some are conventions -- hot water is on the left. In software, a common poka-yoke is method argument checking. For example,

public void m( String v ) {
  if ( v == null ) throw new IllegalArgumentException("v must not be null");
  ...

Other, more complicated poka-yokes are based on the satisfaction of accumulated conditions. For example,

if ( ! ( x && y && z ) ) throw new IllegalStateException("...");

So, Mistake-Proofing has given me a renewed inducement to improve our system and a nomenclature to use.

Note: I find negating a single conjunction of conditions, ( ! ( x && y && z ) ), more readable than a disjunction of negated conditions, ( ! x || ! y || ! z ).  Code readability is itself mistake-proofing.

Developing post of my education about schools

This a developing post of my education about schools in the USA. It will be idiosyncratic. I tend to pick up anything and read it. In time it will become an annotated bibliography to a thesis that will not be needed.
Tough P. How Children Succeed, Grit, Curiosity, and the Hidden Power of Character. Mariner Books; 2013.
Good book with supporting evidence for putting as much emphasis on building character as inculcating academics in secondary education. Last chapters feel like filler. Worth reading.
Berger R. An Ethic of Excellence, Building a Culture of Craftsmanship with Students. Heinemann Educational Books; 2003.
Good book that articulates how a child needs to see and reach for excellence and from that milesone build a successful school life. Worth reading.
Christensen C. Is K–12 blended learning disruptive? An introduction to the theory of hybrids; 2013
A white paper that brings Christensen's Innovator's Dilemma to education. Unsettling vocabulary of business in the context of students & teachers. I have much to disagree with here. Overall, there is no evidence given of how hybrid (or fully disruptive) learning models are successful (vis a vis educating the student and strengthening the teacher) nor how they are cost effective. Much hand waving. Worth reading, if only for ammunition.
Laptop multitasking hinders classroom learning for both users and nearby peers
Useful data point that learning is hindered more for the observer of than for the user of the laptop. 17% more.
If I am going to be successful in lobbying for a high school education deserving of our children I will need to learn a whole new kind of politeness and patients, and expect progress and not perfection. Perhaps this was not the year to give up booze.

MacDown

Since I often write blog postings with embedded code I get frustrated with Blogger's editors. Neither the "Compose" nor the "HTML" variants work right when the code contains anything that looks like an HTML element or entity. My last posting lead to me looking for a Markdown editor and I discovered MacDown. I have used it once, to date, and it worked flawlessly!

Traversing, aka picking for scraping part 2

Extending the idea in the Picking for scraping posting is the traverse. A traverse safely traverses a (typically) hierarchical data structure where any of the intermediary traversal steps may encounter a missing node. For example, in an hypothetical application most data instances have a value at the end of the a traversal from A to B to C to D, however, this data instance is missing the B node. Traversing from A to B is safe, but traversing from B to C will result in an null pointer exception (NPE).
The common ways to avoid NPEs while traversing is to check each node for null before traversing it. And so you see code that looks like a ladder, eg

value = data
if ( value != null ) value = value.A
if ( value != null ) value = value.B
if ( value != null ) value = value.C
if ( value != null ) value = value.D

While this works it is very cumbersome and prone to copy-paste errors due to small variations found on some ladder rungs.

Some languages offer syntax support for traversing. This is called a null coalescing operator. Java, the language I mostly work in, does not have this operator and so a different solution is needed.
The solution I use allows for a safe traversing using data format specific classes. That is, XML has its own traverser, Json has its own traverser, etc. A fully general mechanism might be possible, but the technique is simple and so really does not warrant one. Here is the example of safely traversing some Json data

value = new Traverse(data).at('A').at('B').at('C').at('D').value()

Or, let's have B be an array and we want to traverse the first element

value = new Traverse(data).at('A').at('B').at(0).at('C').at('D').value()

The dictionary at() method is

public Traverse at( String key ) {
    if ( value != null ) {
        if ( value instanceof Map ) {
            value = ((Map)value).get(key);
            // data might be null indicating an unsuccessful, 
            // but safe from NPE, traversal
        }
        else {
            // an unsuccessful traversal always sets data to null
            value = null;
        }
    }
    return this;
}

While the array at() method is

public Traverse at( int index ) {
    if ( value != null ) {
        if ( value instanceof List ) {
            value = ((List)value).get(index);
            // data might be null indicating an unsuccessful, 
            // but safe from NPE, traversal
        }
        else {
            // an unsuccessful traversal always sets data to null
            value = null;
        }
    }
    return this;
}

As with the Builder pattern, the Traverse pattern always returns the traverse instance.

A common aspect is the check for type and this can be refactored out.

public Traverse at( int index ) {
    List l = cast(List.class);
    if ( l != null ) {
        data = l.get(index);
    }
    return this;
}

protected <T> T cast( Class expectedClass ) {
    if ( value != null &amp;&amp; ! expectedClass.isAssignableFrom(value.getClass()) {
        value = null;
    }
    return (T) value;
}

Expanded, working versions of XML traversal and Json traversal are at [TODO].

Oh, how do you get the traversed to value?

public <T> T value() {
    return (T) value;
}

END
My boss was a member and, later, chairman of the Lenox, MA school committee for over 10 years. I am glad for his explanations of the alien world known locally as the South Kingstown School District.

Re: 10 questions for the Superintendent and School Committee Chairwoman

I received a response to my letter with some questions about the 1:1 initiative. Note that the formatting is incorrect in some areas: I have asked for a clearer document.

I still need time to consider it. On the surface it says the right things and says them politely. (Very much Pauline Lisi's voice.) I am told that for more detail I need to meet with two other administrators. It has not been my experience that a meeting is more conducive to detail than a prepared document. The response is a step forward, but not the stride I was hoping for.