Process Buzzwords and Gemba Walks

Looking out the window where I work, my co-workers and I can see the steady progress on the construction of Amazon.com’s new buildings in the South Lake Union neighborhood. Today, safety-vested and hard-hatted troop of people came parading through in the rain, presumably on a tour to see the progress being made. Since we use Lean processes, it seemed analogous to a “gemba walk” that our managers are supposed to conduct regularly.

But why use a term like gemba walk when the Japanese word gemba has a literal meaning of “factory floor” and applies to an industrial process rather than the development of software? Further, for non-Japanese speakers, why use the specific Japanese word when there are plenty of English words that are more immediately understandable to outsiders (those not engaged in applying Lean methodology in the workplace)? It’s not even so much that using this word jars the ear of an English speaker, but that other words to refer to other parts of the process are not used or are, in fact, translated. In a workplace that also embraces kaizen (lit. “improvement”), why are terms like muda (waste) and seiketsu (standardization) not used? When Lean practitioners do recognize waste, they often fail to recognize the differentiation that would be captured by proper use of the Japanese terms (specifically, muda, muri, and mura, the latter two being distinct from more general waste that comes from an inexact translation of muda). To me, as an occasional speaker of Japanese, the reason to use the foreign word is so that the specific nuance of that word isn’t lost or because the translation is too inexact.

To my mind, using the term gemba smacks of putting a new coat of paint on the idea of management by walking around, albeit with a formally defined set of goals and methods. However, I think the formality of the process, typified by the use of ill-defined buzz words, becomes a waste all its own. The danger is that the process becomes a meaningless exercise: “It’s a ‘drive-by’ gemba. No matter how sincere, it is shallow.”

On a related note, the term kaizen rolls off the tongue easier than Kontinuierlicher Verbesserungspozess (such as that employed by Volkswagen), the latter being more in the nature of focussed improvement on a specific process and being more punctuated than the Japanese process.

Addendum: Regarding the use of Japanese terms, Mike Wroblewski has some excellent points and links to arguments both pro and con. In case it’s not clear, I agree with him and don’t think that the Japanese terms should be abolished, but rather that practitioners shouldn’t let the term obscure the intent. By all means use the appropriate terminology to effect the changes the organization wishes to see. If the changes aren’t occurring, then perhaps the managers performing their gemba walk has gotten bogged down in the terminology or process and need to spend more time listening to what is actually being said.

Comments off

Javascript Sorting

Not too long ago, I was asked, as a theoretical question, how I might take a string of random alphabetical characters and sort them in order using Javascript. Thus, given NFARAKDMSLSJDQKJKCXLK, find a simple way to turn it into AACDDFJJKKKKLLMNQRSSX. It’s a pretty basic question for anyone who uses Javascript and I immediately thought of splitting and joining the string as an array (a quick and easy way to tokenize the string). However, for some reason, I completely forgot about the Array.sort() function that’s pretty much a universal across languages.

Instead, the first thing that came to mind was the last time I had to sort a collection and started thinking of Java sorting. In the work I’ve done, such sorting usually requires the use of comparators because the default sort order is often not the one that’s desired. As a case in point, we have a set of JSP pages for rendering content including archive and list pages that display in posting date or sequence order derived from the content. For example, here’s some code to sort by a custom “sequence” attribute using the Vignette Content Management API (this particular snippet is the work of the inimitable Yong Chen):

Comparator aComparator = new Comparator(){
	public int compare(Object obj1, Object obj2) {
		int result=0;
		try {
			Integer s1 = (Integer) ((ContentInstance) obj1).getRelations(CT_RELATION_HEALTH_PLAN)[0].getAttribute("sequence").getValue();
			Integer s2 = (Integer) ((ContentInstance) obj2).getRelations(CT_RELATION_HEALTH_PLAN)[0].getAttribute("sequence").getValue();
			result=s1.compareTo(s2);
		} catch (com.vignette.as.client.exception.ApplicationException e) {
		}
		return result;
	}
};

For debugging, I might break it out a little differently to avoid the multiple casts in a single line. I think the Vignette API is fairly robust, but I would still split the ContentInstance cast apart from the Java native Integer cast in this case. But that might just be me.

In any event, while Javascript can also use comparators without much loss of speed, for a task like the one delineated initially, a simple sort will do the job and the whole can even be condensed to a single line function like this:

function order(unsortedString) {
	return unsortedString.split("").sort().join("");
}

Depending on the browser, the sort function will be some variation on a quick sort or a merge sort. It depends on whether the browser architects chose a stable algorithm or opted for some other version based on various considerations. Mozilla used to use a quicksort prior to Firefox 3.5, but they opted for a merge sort instead in more recent versions. In the course of reading about sort implementations, I came across notes on timsort, Python’s default sort implementation, that I found particularly intriguing.

As an aside the return value for a comparator that works in Firefox may fail with Webkit (Chrome and Safari) since you need to return -1 instead of zero (and a boolean false will also fail). You can read more about Webkit’s Array.sort() handling.

With Java, it looks like this:

String unsorted = "xzya";
char[] content = unsorted.toCharArray();
java.util.Arrays.sort(content);
String sorted = new String(content);

With Perl, you can do something like:

print (join “”, sort split //,$_)

In bash, this will do the same job:

echo “teststring” | grep -o . | sort -n |tr -d ‘\n’; echo

All in all, not only did I refresh my memory about good ways to sort strings and arrays in Javascript, I also learned some new things about sort algorithms and implementations of those algorithms.

Comments off

Computer Science Education Week (December 6-12)

Computer Science Education Week As a current computer science major, I’m glad to see the ACM in a joint effort to help organize Computer Science Education Week (CSEdWeek), which started December 7th. The week was chosen specifically in honor of Rear Admiral Dr. Grace Murray Hopper, also known as “Amazing Grace”, or “a little old lady who talks to computers,” who was born on December 9, 1906. She was a computer science pioneer and her work, spanning computer languages, compiler verification, software development concepts, and much more, has served to inspire a generation of computer scientists.

Comments off

Idioms and Economy of Language

I was talking with a co-worker about my limited facility with Japanese and my interest in improving my facility with that language. During the course of our conversation, she mentioned a fascinating aspect of Japanese for expressing certain idioms or proverbs. That’s were I learned about yoji-jukugo (四字熟語), which are idiomatic expressions made up of four kanji characters. These idioms are written only in kanji only and have no kana between them.

One such example would be the Japanese equivalent of the idiom, “two birds with one stone.” This is rendered as isseki nichou (一石二鳥) (literally, “one stone, two birds”). There are many more yoji-jukugo, many of which have similar versions in English (and many other languages besides).

The Chinese equivalent from which yoji-jukugo originate are called chengyu (成语). The same idiom above has a similar chengyu that translates as, “two birds, one arrow” (yī jiàn shuāng diāo, written 一箭双雕). Another one I like is sān rén chéng hǔ (三人成虎) (literally, “three men make a tiger“), which refers to how a repeated rumor may be erroneously accepted as truth.

There are lots of examples of these idioms including a chengyu of the day. You learn something new every day.

Comments off

Language Impressions

Today I read an interesting perspective on Dutch language, particularly the rather unique ‘ij’ sound in that language. But more than that, it’s a poetic take on the way language seems to feel. (via Snarkmarket)

“There’s something slightly disturbing about the visual scan of the language (I don’t even know what the term is for that: you know when you see a page, or a sign, written in a language and you have an immediate impression of the content of the text? This works also in your native language: look at a page from, like, Dickens, and you can sort of get the Shudder of the Text, or whatever, anyway, what I mean is that some languages, like French, always seem to bear a melismatic philosophy behind the page; German, an authority, Amharic, a crooked delight…) … with Dutch what I get is a sort of childlike pornography: hoog, sneeuwt, poesje, standplaats. But I’m obsessed with it: there’s nothing better than having an old school diagraph still kicking around like an appendix.”

I like the word melismatic in this context, as though the words on the page were the notes and the meaning of the page was the word or melisma. It’s a new one on me even though I subscribe to A.Word.A.Day and occasionally test my vocabulary at FreeRice.

Comments off

What’s the Definition of a Game?

A month ago, I updated my LinkedIn profile to say I was, “…playing and making some games.” I’ve had a few game ideas kicking around and the games I’ve been playing lately have gotten me a bit more motivated to work on my own ideas. My thought was that this small declaration would keep me moving forward and I would actually make some headway on at least one project. As others have noted, ideas are cheap, but seeing a project through to completion is considerably more difficult.

What I hadn’t anticipated was a co-worker asking me what kind of games I was working on. Since my day job is in web development for an HMO, my co-worker was unaware of my background in game design and my continuing interest in doing that kind of work. However, the reason I’m not employed full-time doing game design has more to do with the nature of industry, particularly the crazy hours and my daughter being of an age where she started to think daddy lived in the phone. At the time, people were beginning to take a hard look at some of practices and work environment that went with game development, the most visible being the story of EA Spouse. Just as a case in point, the agency I contracted through gave me vacation time that accrued at a rate of 2 weeks per year based on hours worked. In my first contract, between overtime and the occasional all-nighter, I accrued four weeks of vacation.

So, though I’m not working in the game industry as my day job, I’m still very much interested in games. But my co-worker’s question raised an interesting point: What is the definition of game? Her assumption was that, as a computer guy, I would be turning my energies toward some form of computer game. But even that’s a pretty broad range, given the proliferation of casual games, many of them web-based, alternative reality games, that incorporate many forms of technology including web pages and other technology, and console games, developed on computers despite the hardware being rather specialized.

However, I also play pen-and-paper roleplaying games (Dungeons and Dragons and Ars Magica, among myriad others), I am guilty of having played live-action roleplaying, and I play boardgames, given the opportunity. In fact, about the only thing I don’t play is fantasy football and its real-world team sports analogues.

So, while I’m not planning on creating something like BASEketball any time soon, I’m casting my net considerably wider than trying to develop the next version of Duke Nukem Forever (figuring whatever game I work on still probably has a better chance of seeing the light of day).

Comments off

Mapping Early Manhattan

The September 2009 issue of National Geographic Magazine had a fascinating article about Manhattan before it was settled. The article is based on the work of the Manahatta Project, an endeavor to match the current city to the terrain as it existed prior to settlement by Europeans and to then add the ecosystem that went with the land. The science of landscape ecology and the visualization of biosystem relations that the project has dubbed “Muir Webs” both appear to me to be narratives that go beyond single dimensions and instead look at the patterns formed.

For much the same reason, there is a similar narrative about the early settlers of New Amsterdam, among them is the story of my ancestor Jan Jansen van Flensburg. As a baker who came to the New Netherlands and raised his children in New Amsterdam, the records are far more extensive than for many other immigrants of that time and the maps well detailed (such as this 1656 map of the New Netherlands).

Seeing new ways of combining various data the way the Manahatta Project has done inspires me to look at new ways to bring together historical data and maps such that they tell a story that’s richer than the sum of their parts. A good start in this way of looking at information is the software from TimeGlider, which is useful in putting together historical events in sequence such as this history of World War I.

nieuwamsterdam

Comments off

It’s Not Easy Being Green

With the recent heatwave in Seattle, we discovered that one of the joys of working in a LEED-certified building is that there are controls on how long the air-conditioning can be run (or rather, I suppose, the usage of energy to run the building). That means it wouldn’t kick on until after the sun had already come up, making for some warm mornings in any areas with east-facing windows. For me, I always thought LEED Certification was one of those one-time things, not an ongoing set of practices. Obviously, that would defeat the whole point of sustainability, though the biggest issue seems to be planning intelligently for the future for the life of the building along with developing practices to that purpose. It’s not just as simple as following a checklist.

Beyond LEED-certified buildings, my company has taken other steps to be more environmentally-friendly. It’s not an easy thing to accomplish and an Environmental Design and Construction magazine report pointed out that not only is it hard to do, it’s also hard to measure:

“The hope is that people are not intentionally misrepresenting themselves; they just don’t understand how challenging it is to be “green.” The important lesson we wanted people to take away from our presentation was that you have to ask questions — lots of questions.”

“Determining whether Group Health was doing a good job wasn’t as easy to decide as those involved thought it would be. The questions to be reviewed turned out to be more difficult than anticipated; in many cases, figuring out the answers wasn’t simple.”

Other companies struggle to implement green policies too. Over at Timberland, they’ve introduced a number of measures to make their business more environmentally friendly including only buying leather that doesn’t deplete the Amazon biome and painting their roof white. But it’s not as easy as it might seem, particularly when it comes to banning bottled water.

In the Bootmaker’s blog (formerly, the Earthkeeper’s Blog), Jeff Swartz, the President & CEO of Timberland, noted, “It’s really exhilarating to want to run a more sustainable business… but to actually do it is really freaking hard.”

Comments off

Creating an RSS Feed in JHTML

Because we use an older version of ATG Dynamo (6.2.0) at my place of employment, we’re sometimes constrained in what we can do and aren’t able to take advantage of features in newer versions of Dynamo. One of those features is the ability to generate an RSS feed from a content repository (which I believe is available now as part of the suite of personalization features ATG offers). If you have the ability to deploy droplet code, there’s certainly an RSSFeed module. But if all you need is a basic RSS feed for a particular collection, the following is what I came up with.

<?xml version="1.0" encoding="UTF-8" ?>
<importbean bean="/atg/targeting/TargetingForEach">
<importbean bean="/atg/dynamo/droplet/Switch">
 
<%-- import files --%> 
<%@ page import="java.util.*, java.text.*" %>
 
<%-- Generate the RSS XML --%>
 
<%-- Set the rss type --%>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
   <channel>
      <title>News</title>
      <link>http://www.foobar.com/</link>
      <description>News and information.</description>
   <textInput>
      <title>News</title>
         <link>http://www.foobar.com/</link>
         <description>News and information.</description>
   </textInput>
   <skipHours>
      <hour>0</hour>
   </skipHours>
      <language>en-us</language>
      <webMaster>webmaster@foobar.com</webMaster>
 
      <droplet bean="/atg/targeting/TargetingForEach">
         <param name="targeter" value="bean:/atg/registry/RepositoryTargeters/News/archiveNews">
         <param name="fireContentEvent" value="false">
         <param name="firecontentTypeEvent" value="false">
         <param name="sortProperties" value="-postingDate">
         <oparam name="output">
            <droplet bean="/atg/dynamo/droplet/Switch">
               <param name="value" value="param:element.linkURL">
               <oparam name="unset">
                  <item> 
                     <title><valueof param="element.title"/></title>
                     <description><valueof param="element.description"/></description>
                     <link>http://www.foobar.com/news/news.jhtml?reposid=<valueof param="element.repositoryId"/></link>
                     <pubDate><valueof param="element.postingDate" converter="Date" date="EEE, dd MMM yyyy HH:mm:ss Z"/></pubDate>
                  </item>
               </oparam>
               <oparam name="default">
                  <item> 
                     <title><valueof param="element.title"/></title>
                     <description><valueof param="element.description"/></description>
                     <link><valueof param="element.linkURL"/></link>
                     <pubDate><valueof param="element.postingDate" converter="Date" date="EEE, dd MMM yyyy HH:mm:ss Z"/></pubDate>
                  </item>
               </oparam>
            </droplet>
         </oparam>
         <oparam name="empty">
            <p>No archived news</p>
         </oparam>
      </droplet>
   </channel>
</rss>

A couple of the important things with an RSS feed is to have a properly formatted date and to properly include the various elements and the like. Some readers are more forgiving than others. The date version here is the RSS 2.0-compatible RFC822 and not the older ISO8601, though you can read all about the ins and outs of RSS dates. Many elements are optional but the output may display strangely depending on the reader and are included here primarily for consistent display with the built-in readers on IE and Firefox.

Comments off

A Breadcrumb Story

Where I work, one of the site features is a breadcrumb trail on all pages allowing linking through the content hierarchy. All of the breadcrumbs in the breadcrumb trail was generated using a rather lengthy Javascript file. The main reason for the length was due how the folders were named and the number of exceptions or special cases. As a note, for this to work all directory names were CamelCase (lowerCamelCase, to be precise) except where they were legacy items or inconsistently named (increasing the number of special cases that needed handling).

But it worked better than much breadcrumb code I’ve seen, so all was well and good until two things happened. The first was that mysterious 404 errors began to crop up in our logs. I finally traced them back to bots crawling the site, coming across the pieces of the Javascript that constructed the links in the breadcrumbs and indexing them as valid (not processed) links. So our logs were littered with failures to find pages like about_gh/.*/badministrator/b.*)/i, or /health_plans/+howmany[i+2]+. The second thing that occurred was we began developing a new version of one of our sites and it didn’t make sense to use the existing Javascript since the majority of it’s special cases were for our main site. Further, we would just be perpetuating the log errors caused by misbehaving seach engine bots.

So, for the new site, I rewrote the Javascript as a JHTML include. Since we’re using Dynamo and haven’t migrated any of our dynamic pages to be JSP pages (and encountered some problems with that due to the older version we’re running on), I learned some interesting things about using Java inline on a single page like this.

The first part of the page requires declaring any imports, like so:

<java type="import">
	java.util.regex.*;
</java>

The second part of the page is the main Java code that gets the URL and performs some operations on it:

<java>
	String originalURL = request.getRequestURL().toString();
 
	if (originalURL.indexOf("somejavaAppPathID") != -1) {
		if (originalURL.indexOf("javaApp") != -1) {
			breadcrumbPathString += divider + "<a href=\"/somespecialidentifierParent/index.jhtml\">JavaAppParent</a>" + divider + "<a href=\"/somejavaAppPathID/javaApp/JavaAppMethod?forwardUrl_success=/someAppResultLocation/javaApp/index.jhtml\">JavaApp</a>";
		}
	} else if (originalURL.indexOf("pageNameWithParam.jhtml") != -1) {
			//itemKey is the parameter that has the path to the content
			String paramKey = "paramname";
			breadcrumbPathString = makeTrail(request.getParameter( paramKey ), baseLoc, divider);
	} else {
		breadcrumbPathString = makeTrail(request.getRequestURI(), baseLoc, divider);
	}
 
	breadcrumbPathString = fixDirectories(breadcrumbPathString);
 
	out.print(breadcrumbPathString);
</java>

Originally, my thought was to use the Request Scheme like this:

String thisRequestScheme = request.getScheme();
if (thisRequestScheme.startsWith("https") == true) {
	baseLoc ="https://"+ request.getServerName() ;
} else{
	baseLoc ="http://"+ request.getServerName() ;
}
if (request.getServerPort() != 0) {
	baseLoc += ":"+request.getServerPort();
}

But since our server configuration includes F5 load balancers, that was incorrect and the request object contains different information than the URL we’re looking for. I’d prefer to use this implementation, but the previous one starting with request.getRequestURL() will work.

Lastly, I created some methods for handling special cases and doing some other work on the URLs:

<java type="class">
	public String makeTrail(String breadCrumb, String urlPath, String thisDivider) throws IOException {
		urlPath += "/";
		String outputString =  "<a href=\""+urlPath+"index.jhtml\">Home</a>";
		String linkName = "";
		String linkString = breadCrumb;
		breadCrumb = removeDirectories(breadCrumb);
		if (breadCrumb != null) {
			String[] breadCrumbArr = breadCrumb.split("/");
			String[] linkStringArr = linkString.split("/");
			if(breadCrumbArr.length!=0) {
				for(int i=1; i<linkStringArr.length-1; i++) {
					urlPath += linkStringArr[i]+"/";
					if (breadCrumbArr[i] != null && breadCrumbArr[i].length() > 0) {
						linkName = makeProper(breadCrumbArr[i]);
						outputString +=  thisDivider+"<a href=\""+urlPath+"index.jhtml\">"+linkName+"</a>" ;
					}
				}
			}
		}
		return outputString;
	}
 
	public String makeProper(String theString) throws IOException {
		StringReader in = new StringReader(theString);
		boolean precededBySpace = true;
		boolean precededByCap = true;
		StringBuffer properCase = new StringBuffer();
		while(true) {
			int i = in.read();
			if (i == -1)  break;
			char c = (char)i;
			if (Character.isSpaceChar(c)) {
				properCase.append(c);
				precededBySpace = true;
			} else if (Character.isUpperCase(c)) {
				if (precededByCap) {
					properCase.append(c);
				} else {
					properCase.append(' ');
					properCase.append(c);
				}
				precededByCap = true;
			} else if (c == '-'||c == '_') {
				properCase.append(' ');
				precededBySpace = true;
			} else {
				if (precededBySpace) {
					properCase.append(Character.toUpperCase(c));
				} else {
					properCase.append(Character.toLowerCase(c));
				}
				precededBySpace = false;
				precededByCap = false;
			}
		}
		return properCase.toString();
	}
 
	public String removeDirectories(String theString) {
		//completely remove these directories from the breadcrumbs
		theString = replaceWith(theString,"ignore/","/");
		theString = replaceWith(theString,"anotherDirectoryToSkip/","/");
		return theString;
	}
	public String fixDirectories(String theString) {
		//replace these nonsense names with real words
		//    theString.replaceWith("(?i)\\babout[ _]us\\b","About Us"); //A weird special case since the directory name is not CamelCase
		theString = replaceWith(theString,"(?i)\\bpeople\\splaces\\b","People &amp; Places");
		theString = replaceWith(theString,"(?i)\\babbr\\b","Full Unabbreviated Directory Name");
		return theString;
	}
 
	private static String replaceWith(String aPath, String aPattern, String aReplacement ){
		Pattern pattern = Pattern.compile(aPattern, Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(aPath);
		return matcher.replaceAll(aReplacement);
	}
</java>

In reviewing this code, one thing I was unsure about was whether using

String originalURL = request.getRequestURL().toString();

was the correct way to go or if I should have used

String path = request.getPathTranslated();
path = replaceBacklash(path);

I realized that, for the way the site functions, we may pass an item parameter and we want to properly build the path to that item, not the page rendering the item. Using getRequestURL handles both situations.

Comments off