<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Software Agorist</title>
	<atom:link href="http://www.adhocalley.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.adhocalley.com</link>
	<description>Random thoughts on software dev ... and other opinions from an open mind</description>
	<lastBuildDate>Wed, 04 Apr 2012 04:51:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Technorati token</title>
		<link>http://www.adhocalley.com/?p=120</link>
		<comments>http://www.adhocalley.com/?p=120#comments</comments>
		<pubDate>Wed, 04 Apr 2012 04:51:02 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=120</guid>
		<description><![CDATA[J8YR7TDHJAWB]]></description>
			<content:encoded><![CDATA[<p>J8YR7TDHJAWB</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=120</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Notes on Parking Ordinance Changes in Houston</title>
		<link>http://www.adhocalley.com/?p=102</link>
		<comments>http://www.adhocalley.com/?p=102#comments</comments>
		<pubDate>Thu, 17 Nov 2011 03:34:22 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=102</guid>
		<description><![CDATA[The City of Houston Planning Committee is considering changes to our parking ordinances. Some notable changes include increasing the parking ratio for restaurants (from 8 to 10 spaces per 1000 square feet) and bars (from 10 to 14 spaces per 1000). These rules come on top of an already increasingly &#8220;suburbanized&#8221; parking and building rules. [...]]]></description>
			<content:encoded><![CDATA[<p><em>The City of Houston Planning Committee is considering changes to our parking ordinances.  Some notable changes include increasing the parking ratio for restaurants (from 8 to 10 spaces per 1000 square feet) and bars (from 10 to 14 spaces per 1000).  These rules come on top of an already increasingly &#8220;suburbanized&#8221; parking and building rules. In general, not good.   I&#8217;ll try to make it to the hearings on these changes, and below are some of my talking notes</em></p>
<p>I speak for myself, but some credentials:<br />
- Inside-the-Loop resident for many years<br />
- office in Rice Village<br />
- board of directors of a non-profit shop in Rice Village<br />
- married to a Montrose-area cafe owner</p>
<p>In summary, what I want to present here is <em>&#8220;one size does not fit all&#8221;</em>.  Houston is a very diverse city, don&#8217;t define a cookie-cutter ordinance to meet a very varied problem &#8211; instead, more local dialogue and collaboration required.<br />
<span id="more-102"></span></p>
<p>- As you know, most of Rice Village is non-compliant with our current parking ordinance, much less the increases proposed here.  Yet, the Village is an endearing, and enduring, part of Houston. Yes, folks complain about parking, but in all my years there, I&#8217;ve never had to walk more than 3 blocks.  The length of a typical Walmart parking lot is 2 blocks &#8211; count the interior of the store itself and a regular patron is walking 4 blocks or more.  Completely acceptable in the big box store, completely acceptable in the Village.  What if the Village had been forced to comply with current suburban-style parking ordinances? Would it be charming and viable today?  Likely not, it would have gone the way of Gulfgate, Meyerland or Town &#038; Country Malls &#8211; abandoned only to be redeveloped many years later.</p>
<p>- My wife&#8217;s shop has a popular dance on Saturday evenings. At such times, parking overflows beyond her small lot, customers take up street parking a half-block away.  A neighbor or two complains &#8220;you are taking away all our parking.&#8221;  One evening, I decided to do a parking count on one street &#8211; while we were open, 10 of our patrons.  Late night, after we&#8217;re closed &#8211; still 10 (but different) cars parked on the street. Who were these cars?!  Local residents and visitors, of course.  The cafe has no more impact on the street than the neighborhood itself.  Truth is, all of their bungalows and duplexes and quadplexes are not compliant with current ordinance either.  Do we complain?  No, it&#8217;s part of urban living.  For every neighbor that complains of us taking up street parking, there&#8217;s 4 other neighbors that thank us for providing a place they can walk too, a charming place, without a huge impersonal parking lot in front.</p>
<p>- street parking is a great, flexible solution that is a major characteristic of busy, thriving cities throughout the US.  Keep it going.  Don&#8217;t allow residential driveway cut ins that reduce the capacity for street parking. An ironic impact of the 2-spaces per single family residence rule is that in areas where town homes become popular, you&#8217;ll find a whole block of town homes in a row, eating up all street parking.  What was once single-driveway bungalows is now a surfeit of double-wide two-car garages, bye bye curb space (and curb appeal, for that matter!)  Residential visitors are left without a space to park, much less supporting neighborhood businesses.</p>
<p>- we should explore <em>mini</em> &#8220;parking management areas&#8221; [the Parking Ordinance defines the possibility of creating such areas, but with gross floor area of 3.5 million square feet.  At present, downtown, the Medical Center, and Greenway Plaza qualify].  Perhaps the city, through its super neighborhood network, should research this more and make proposals suitable to all within an area.  Who could benefit by a mini-parking management area?  Well, Rice Village, for one, Montrose generally, Washington Blvd., and in the future, Navigation/2nd Ward, Dowling/Lyons, etc.  Work on a combination of shared parking/mass transit to resolve parking and access broadly for all businesses.</p>
<p>- parking garages at transit hubs or transit cross points, at major urban inflection points.  I emphasis transit points because they resolve 2 problems: parking for transit riders to the Central Business District by day, parking for the local area by evening.  Yes, I&#8217;m proposing city- or Metro-owned parking garages, like many other cities.</p>
<p>- let&#8217;s look at alternatives for the Washington Corridor: perhaps best handled, instead of individual lots for each biz, a &#8220;dumbbell&#8221; arrangement with parking garages on either end of the corridor, served by private jitney routes in-between.</p>
<p>- tiered parking requirements; restaurant or bar establishments less than 2500 sq. ft. require less of a parking ratio [thanks to Bobby Heugel for this suggestion].</p>
<p>- special parking requirements for &#8220;night clubs&#8221;.  Yes, hard to define, but let&#8217;s take a crack at it.  Night clubs put a lot more demand on parking spaces than your neighborhood bar [again attributing Bobby Heugel]</p>
<p>- bicycle racks.  Yes, I think I&#8217;ve heard this solution before, so I&#8217;m just repeating a good idea &#8211; allow 1 parking space per 1000 sq. ft. be dedicated to bikes.  Maybe a super neighborhood  can arrange donations of bike racks to businesses. You think bikes aren&#8217;t used in this city?  Well, I can regularly count 2-3 bikes every time I visit my wife&#8217;s cafe.  That&#8217;s 3 cars off our streets, with all the benefits that entails.</p>
<p>That&#8217;s all I have for now.  Let&#8217;s not suburban cookie cutter this, but work out collaborative solutions that fits each area of our fine city.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=102</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cross-Platform CSS for Translucent DIVs</title>
		<link>http://www.adhocalley.com/?p=74</link>
		<comments>http://www.adhocalley.com/?p=74#comments</comments>
		<pubDate>Fri, 28 Oct 2011 05:24:52 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=74</guid>
		<description><![CDATA[Had a need recently to make some translucent (semi-opaque) elements on a Web page. CSS3 supports an &#8220;alpha&#8221; channel, the &#8220;a&#8221; in rgba, to provide color opaqueness, but IE 7 and 8 do not support this attribute.  So, most web developers resort to using a translucent background-image.  However, there is a pure CSS way that [...]]]></description>
			<content:encoded><![CDATA[<p>Had a need recently to make some translucent (semi-opaque) elements on a Web page. CSS3 supports an &#8220;alpha&#8221; channel, the &#8220;a&#8221; in rgba, to provide color opaqueness, but IE 7 and 8 do not support this attribute.  So, most web developers resort to using a translucent background-image.  However, there is a pure CSS way that is compatible with all modern browsers today (IE6 ignored, of course).  This takes advantage, though, of some CSS parsing bugs, so may not satisfy the CSS purists out there, but it works for me <img src='http://www.adhocalley.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div style="padding: 250px 40px 40px 40px; background-image: url('http://www.adhocalley.com/wp-content/uploads/2011/10/TangoThroughAnOpenDoor.jpg'); background-repeat: no-repeat; width: 560px; height: 340px;">
<div style="background-color: rgba(255,255,255,0.5); zoom: 1; *background-color: transparent; -ms-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#80FFFFFF, endColorstr=#80FFFFFF); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#80FFFFFF, endColorstr=#80FFFFFF); padding: 20px; margin-left: 20px;">
<div id="inner" style="background-color: white; padding: 20px; border: 1px solid #999; color: #6793c4; font-weight: bold;">Demo: solid background inner-box surrounded by a translucent box, overlaying a background-image.</div>
</div>
</div>
<p><span id="more-74"></span></p>
<h3>The markup:</h3>
<p><span style="color: #c80000; ; font-size: small;">background-color</span><span style="color: black; ; font-size: small;">: </span><span style="color: #07909a; font-size: small;">rgba</span><span style="color: black; font-size: small;">(</span><span style="color: #3200ff; font-size: small;">255</span><span style="color: black; font-size: small;">,</span><span style="color: #3200ff; font-size: small;">255</span><span style="color: black; font-size: small;">,</span><span style="color: #3200ff; font-size: small;">255</span><span style="color: black; font-size: small;">,</span><span style="color: #3200ff; font-size: small;">0.5</span><span style="color: black; font-size: small;">); </span><span style="color: #007400; font-size: small;">/* CSS3 */</span><span style="color: #c80000; font-size: small;">zoom</span><span style="color: black; font-size: small;">:</span><span style="color: #3200ff; font-size: small;">1</span><span style="color: black; font-size: small;">; </span><span style="color: #007400; font-size: small;">/* required for the filters */<br />
</span><span style="color: black; font-size: small;"> *</span><span style="color: #c80000; font-size: small;">background-color</span><span style="color: black; ; font-size: small;">: </span><span style="color: #07909a; font-size: small;">transparent</span><span style="color: black; font-size: small;"> ; </span><span style="color: #007400; ; font-size: small;">/* IE7 only */<br />
</span><span style="color: black; font-size: small;"> </span><span style="color: #c80000; ; font-size: small;">background-color</span><span style="color: black; font-size: small;">: </span><span style="color: #07909a; font-size: small;">transparent</span><span style="color: black; font-size: small;">\</span><span style="color: #3200ff; font-size: small;">9</span><span style="color: black; font-size: small;"> ; </span><span style="color: #007400; font-size: small;">/* IE8 only */<br />
</span><span style="color: black; font-size: small;">-ms-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#80FFFFFF, endColorstr=#80FFFFFF) ; </span><span style="color: #007400; ; font-size: small;">/* IE8 */<br />
</span><span style="color: #c80000; ; font-size: small;">filter</span><span style="color: black; ; font-size: small;">: progid:DXImageTransform.Microsoft.gradient(startColorstr=#80FFFFFF, endColorstr=#80FFFFFF); <span style="color: #339966;">/* IE7 */</span></span></p>
<p>To change the opaqueness of the div, edit both the alpha value in rgba() as well as the 1st hex value in the startColor and endColor filters. Convert to hex, of course: 0.7 alpha = B2 in hex (0.7 * 255); 0.5 = 80 hex, etc.</p>
<h3>How this Works</3></p>
<p><b>background-color rgba() is the correct way to specify opaqueness, for all browsers that recognize CSS3.  <b>filter</b> and <b>-ms-filter</b> are recognized by their respective IE browsers. The <b>Gradient</b> filter, with the same starting and end color, is used instead of the Alpha filter because the Alpha filter will also apply itself to children elements. <b>background-color transparent</b> is required for the MS filters to work. However, specifying it would override the rgba() value, thus messing with CSS3-compatible browsers, so we take advantage of a few CSS parsing hacks: keywords starting with <b>*</b> are only recognized by IE7, and keyword values ending with <b>\9</b> (go figure!) are only recognized by IE8.  Lastly, the MS filters only work on positioned elements; the <b>zoom</b> element satisfies this requirement.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=74</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Texas Employment Statistics</title>
		<link>http://www.adhocalley.com/?p=68</link>
		<comments>http://www.adhocalley.com/?p=68#comments</comments>
		<pubDate>Sun, 14 Aug 2011 21:35:01 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=68</guid>
		<description><![CDATA[As Rick Perry has joined the Republican Party presidential fray, there will be questions about his prowess at bringing jobs to Texas.  Of course, a governor can only directly &#8220;create&#8221; jobs by increasing payroll of government employment, but he does have a limited role in creating a more or less positive environment for businesses in [...]]]></description>
			<content:encoded><![CDATA[<p>As Rick Perry has joined the Republican Party presidential fray, there will be questions about his prowess at bringing jobs to Texas.  Of course, a governor can only directly &#8220;create&#8221; jobs by increasing payroll of government employment, but he does have a limited role in creating a more or less positive environment for businesses in the state, an that may have an impact on private employment as well.</p>
<p>The 2008-2011 recession has hit private employment in Texas just has it has in ogther ; however, it is worth noting that federal, state, and local employment figures have continued to rise through this same period.  Rise in state employment figures roughly matches the growth in the state government budget, and of course, the state budget deficit.  Some of these deficits have masked by federal ARRA &#8220;stimulus&#8221; funds, but that will be the subject of another post.</p>
<p>These stats drawn from the Texas Workforce Commission:</p>
<p>May 2008 – 8,857,500<br />
May 2011 – 8,704,800</p>
<p>2011, though, has seen some job growth &#8211; not to pre-recession figures, but growing nonetheless.  These stats may change, though, as often past month figures are re-adjusted:</p>
<p>Jan 2011 - 8,483,200<br />
Feb           &#8211; 8,514,400<br />
Mar          - 8,612,000<br />
Apr           &#8211; 8,674,200</p>
<p>State Government employment has gone up through the recession, which matches (approximately) the growth in our state budget through this same period:</p>
<p>May 2008 – 364,200<br />
May 2011 – 378,700</p>
<p>May 2011 reflects an interesting decrease, perhaps due to the current budget battles at the state level.  We&#8217;ll see if that drop remains:</p>
<p>Jan           - 374,500<br />
Feb           &#8211; 385,000<br />
Mar          - 385,300<br />
Apr          - 385,300</p>
<p>Local government employment has also been growing through this period – this is partially state budget-driven, so is worth reflecting:</p>
<p>May 2008 – 1,244,600<br />
May 2011 – 1,303,000</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=68</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test 2</title>
		<link>http://www.adhocalley.com/?p=57</link>
		<comments>http://www.adhocalley.com/?p=57#comments</comments>
		<pubDate>Mon, 14 Feb 2011 04:27:20 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=57</guid>
		<description><![CDATA[Test]]></description>
			<content:encoded><![CDATA[<p>Test</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=57</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django</title>
		<link>http://www.adhocalley.com/?p=52</link>
		<comments>http://www.adhocalley.com/?p=52#comments</comments>
		<pubDate>Tue, 25 Jan 2011 03:32:55 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=52</guid>
		<description><![CDATA[Egads, it&#8217;s been a long time since I&#8217;ve written a blog post. Yes, let&#8217;s blame Twitter for this!! Pithy, short, and easy, tweeting has become the easy way to share thoughts. Of course, not all can be written in just 140 characters, so I need to maintain a blog for deeper, yes, deeper thoughts. But [...]]]></description>
			<content:encoded><![CDATA[<p>Egads, it&#8217;s been a long time since I&#8217;ve written a blog post.  Yes, let&#8217;s blame Twitter for this!!  Pithy, short, and easy, tweeting has become the easy way to share thoughts.  Of course, not all can be written in just 140 characters, so I need to maintain a blog for deeper, yes, deeper thoughts.</p>
<p>But for now, let me just say one word: Django!  Yes, I&#8217;ve been doing a lot of Django development over the past year.  Enjoying it too.  Python is concise, is nice.  Not as nice as Smalltalk, of course, but nice enough.  And, as a framework, Django delivers a lot of excellent functionality right out of the box.  Been very pleased.  I&#8217;ll have to write up some of my Django apps &#8230; when I have time, of cours.e</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=52</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The 3 P&#8217;s of Social Media Marketing</title>
		<link>http://www.adhocalley.com/?p=48</link>
		<comments>http://www.adhocalley.com/?p=48#comments</comments>
		<pubDate>Mon, 14 Dec 2009 22:16:53 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Houston]]></category>
		<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=48</guid>
		<description><![CDATA[Introduction Over the past year or so, I have been helping a small cafe in Houston, a tea house, enter into the world of social media marketing, mostly employing Twitter, and recently making use of Facebook. In fact, we were perhaps the first retail establishment in Houston to enter the brave new world of Twitter, [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>Over the past year or so, I have been helping a small cafe in Houston, a tea house, enter into the world of social media marketing, mostly employing Twitter, and recently making use of Facebook.  In fact, we were perhaps the first retail establishment in Houston to enter the brave new world of Twitter, and now boast over 1500 followers, making it the 2nd largest restaurant following in Houston.  This cafe&#8217;s experience with  social media has been quite successful, with results far better than advertising in traditional newspapers or magazines, and will continue to be a major participant in social networking space.</p>
<p>Follower count was never the strategy when we entered the Twitter world. I did have a strategy in mind when I first participated, and it was been refined through customer feedback and a few lessons-learned.  I think our experiences can be useful to other retail stores,  so just wanted to take some time here to share my insights.  They can be organized as the 3 Ps of Social Media Marketing:</p>
<p style="text-align: center;"><span style="white-space: pre;"> </span><strong>Passion    <span style="white-space: pre;"> </span></strong><strong>Personality<span style="white-space: pre;"> </span></strong><strong>Place</strong></p>
<h4><span id="more-48"></span></h4>
<h4>Notes</h4>
<p>I am by no stretch a social media expert nor marketing professional; however, with my education in economics I have forayed into marketing on occasion, including one research study in the early 1990s into that very early social network called AOL Chat.</p>
<p>Also note the cafe in question is Te House of Tea, @tehouseoftea, run by my wife, Connie Lacobie <img src='http://www.adhocalley.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I am going to talk mostly about Twitter here.  Facebook is a relatively new effort, though it is growing well.  Te has had a Myspace account and a Flickr group, but neither has yet had much traction, so we won&#8217;t explore those avenues.There&#8217;s already a lot of basic advice about Twitter (keep it short, don&#8217;t spam, etc.); I&#8217;m not going to repeat those lessons.  Read other basic guidelines to &#8220;how to use Twitter&#8221; if you&#8217;re still new to this space.</p>
<h3>Passion</h3>
<p>You&#8217;re a mom-and-pop business, a solo entrepreneur, and you&#8217;ve opened a local business, be it a store, a service, or a place providing food &amp; drink.  I can already guess one thing about you: you are very likely passionate about the product you provide.  And, guess what, so are many of your customers!  This passion, this energy, is the first thing you should think of sharing online.  Talk about the love of your product, the love of the things you do.  Talk about facts, history, and trivia about your product.</p>
<p>Then, find others who share this same passion.  Follow them, and comment on their tweets.Yes, this is your first guideline on who to follow on Twitter: find people who are talking passionately about your product.  They&#8217;ll be happy to have you as a follower, and 9 times out of 10, if they&#8217;ve never heard of you, will be excited to have discovered you!  Search around for not only your direct product, but products related to it (look not only for tea lovers, but scone lovers too!).</p>
<p>In the Twitter world, folks are not at all shy about talking about how great your product and place is.  Thank them, and spread the word (retweet!). Your customers want to see you succeed, yes they do, and their own referrals and marketing is the simplest and greatest way to gain more customers.</p>
<p>Yes, you may want random people to discover you &#8211; that&#8217;s what advertising and signs and store frontage too, but you really want passionate people to discover you. Your business growth depends on that enthusiastic customer, that loyal customer, that repeat customer, and friend. Unless you&#8217;re a spammer or con-artist, you don&#8217;t want one-time hits, you want to find customers for life. A social media strategy that starts out with sharing passion is the best way to discover this kind of customer, and for them to discover you.</p>
<p>Plus, passion is easy to share.  Are you awkward or hesitant when writing online? You can&#8217;t go wrong if you think of your own interests and loves first.  Sharing that is the easiest way to overcome any writer&#8217;s block or shyness in the social network world.</p>
<p>To give you a great example of how connecting with Passion works online: one day I happened to notice writer/photographer and local beauty Karen Walrond, @chookooloonks, talk about some tea she was drinking, so I (through Te) replied to her and started following.  Additionally,  I said something like &#8220;oh, we have many mutual friends&#8221;, which is true, but interestingly, somehow she had never heard of Te House of Tea.</p>
<p>Well, this intrigued her.  Coincidently, she was coming into town for dinner that night (she&#8217;s a suburb gal, we gather), so she and her handsome husband, decided to swing by Te after their dinner &#8211; the very same night that we had tweeted! Also coincidently, this was tango night. When she arrived, she was absolutely floored of the scene (tea &#8230; and tango!), took some wonderful photos and the very next morning wrote a glowing blog about the shop! (see <a title="Tango and Tea" href="http://www.chookooloonks.com/blog/2009/3/14/tango-tea-te-house-of-tea.html">www.chookooloonks.com/blog</a>).  Within 24 hours of my first comment, not only had Te gained 2 new, lovely customers, but the word had been spread to thousands more.</p>
<h3>Personality</h3>
<p>Don&#8217;t adopt a personality when you&#8217;re online &#8211; show your own personality!  Gone are the days of dry press releases and canned statements.  Twitter is a very personal media, and you need to share your own personality online too. And don&#8217;t forget your employees&#8217; personalities too!  They are your frontline marketers, and can be a part of your online strategy too!  They love working at your place (see Passion, above), so let them share their experiences online as well.</p>
<p>Ok, maybe not ALL of your personality.  Just like when you groom and dress up before going out in public, you do need to take care of your public image online.  Be personable, but don&#8217;t talk about your tooth-brushing experiences.  If your employees participate, give them some guidelines about discretion (don&#8217;t tweet when some celebrity who values his privacy comes into your store!), decorum, other employee&#8217;s privacy, and trade secrets.</p>
<p>But, do share and display a personality.  Here in Houston, I especially like all the chefs who are on Twitter.  What personalities!  You see a picture of their faces, you know who they are, you know a bit of their personal travels and travails.  This is a great approach. At @tehouseoftea, we decided early on to speak as the store itself, in third person plural, and our logo is our avatar instead of a face; so our personality is a bit different, but every-once-in-a-while the person behind the screen peeks out <img src='http://www.adhocalley.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Your humor or wit is a great aspect of your personality, so share that if you&#8217;re comfortable. You have talent with poetry?  Drawing?  Use these in some of your tweets &#8211; take a picture of your drawing and share that along with your tweet, using twitpic or such.  Make yourself unique, make yourself you!</p>
<p>Even if you have to post some standard PR announcement, a new special, event, etc., toss it out with your own personal twist.  Don&#8217;t give it the monotonous &#8220;We are now open 7 days a week, 11 am to 10pm weeknights &#8230;&#8221; that you&#8217;d expect from the PR department. Give it something like &#8220;Gah, I love my mornings, so I&#8217;m happy to announce we now open at 11 am&#8230;&#8221;</p>
<h3>Place</h3>
<p>You&#8217;re a brick and mortar establishment: that means you&#8217;re someplace, right?!  Pay attention to what&#8217;s going on around you, comment on them, share (retweet!), participate.  And think of not only that physical Place you&#8217;re at, but the more abstract Places as well.  You have a lot of artists among your customers?  Then you have a place in the artistic community too.  Dancers?  Another place.  Writers, knitters, sci-fi movie lovers, they all have their own places, and will be happy for you to belong.</p>
<p>Back to physical Place &#8211; if you&#8217;re in a small city, keep an eye out for conversations in your city.  But if you&#8217;re in the big city, narrow it down to your neighborhood or nearby areas, sites, and streets.</p>
<p>A small example here: recently, I happened to notice someone tweet that their dog was lost, somewhere around  Richmond and Woodhead.  Well, Te is at the intersection of Woodhead and Fairview, just a mile north, so in the off-chance the dog might be wandering our way (and, we have a dog too, so we were very sympathetic!), I retweeted this person&#8217;s plea.  Had no idea she was a popular blogger with chron.com, so we were quite surprised to get a public thanks just a day later: &#8220;<a title="Kindness of Strangers" href="http://blogs.chron.com/memo/archives/2009/10/the_kindness_of.html">The Kindness of Strangers &#8230;</a>&#8220;. More exposure for Te, even though that wasn&#8217;t even our intent.</p>
<p>Te is a regular hangout for artists, and every month a different artist displays their works, so of course Te has a Place in the artist community.  We try to keep up and retweet, recommend, and promote our artist friends when they have events and showings at other places.  We comment on other art happenings, and stay involved both online and in place, donating food and time when we can.</p>
<p>We&#8217;re helping them, and they help us by having even more people, with like interests, discover us. So, find your Place, and make it an active part of your own social media strategy, both in what you search for and comment about, and you&#8217;ll be pleased with the results.</p>
<p>When to tweet, how to tweet, what to tweet?  Just think of Passion, Personality, and Place, and you&#8217;ll find plenty of ways to participate online, and become your guiding social media strategy.  Get out there!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=48</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>nGram Dictionary</title>
		<link>http://www.adhocalley.com/?p=47</link>
		<comments>http://www.adhocalley.com/?p=47#comments</comments>
		<pubDate>Tue, 24 Nov 2009 01:14:38 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=47</guid>
		<description><![CDATA[On a recent project, had to deal with searching of tens of thousands of product descriptions, with a need to find substring matches quickly.  The select: statement in Smalltalk works like a SQL table scan &#8211; okay for small collections, but becomes seconds+ response time with larger lists. An effective solution to this is an [...]]]></description>
			<content:encoded><![CDATA[<p>On a recent project, had to deal with searching of tens of thousands of product descriptions, with a need to find substring matches quickly.  The select: statement in Smalltalk works like a SQL table scan &#8211; okay for small collections, but becomes seconds+ response time with larger lists.</p>
<p>An effective solution to this is an <strong>nGram Dictionary</strong>.  Strings of words can be broken up into sets of tri-grams, quad-grams, quint-grams, and so on.</p>
<p>My approach to this is a Dictionary indexed by nGram length, each element containing dictionaries of nGram strings of collections of the string objects to be searched.  Thus, indexing results as such:</p>
<pre>3 -&gt; ana -&gt; ('banana')
ban -&gt; ('banana', 'band')
4 -&gt; bana -&gt; ('banana')
band -&gt; ('band')
anan -&gt; ('banana')
5 -&gt; banan -&gt; ('banana')
...</pre>
<p><span id="more-47"></span></p>
<p>To instantiate, just <strong>NGramDictionary new on: someCollectionofStrings from: 4 to: 10</strong>, for example.  To search, just <strong>foo</strong> <strong>search: &#8216;someString&#8217;</strong>.  If <em>someString <span style="font-style: normal;">can be larger than the NGramDictionary size; </span>search:</em> will handle longer string searches by doing a <em>select:</em> scan.</p>
<p>How large to make the nGram Dictionary is a matter of how large and non-unique the string collection may be.  I recommend starting at the low end at 3 or 4 &#8211; searches of 1 or 2 character strings will return way too many results with most string collections to be useful.</p>
<p>There&#8217;s a few other special cases I kept this in this example code, to meet my particular needs; for example, this is not a strict nGram splicing &#8211; spaces, numbers and punctuation marks are excluded and become &#8220;word&#8221; boundaries.  But, the results are super-fast, enabling, for example, type-ahead select lists on a web-based form.</p>
<p><code> </code></p>
<pre><code><strong>Object subclass: #NGramDictionary</strong>
instanceVariableNames: 'mySmallest myLargest myCollectionofStrings myNGrams'
classVariableNames: ''
poolDictionaries: ''
category: ''</code>

<strong>at: aString</strong>
<em>"returns strictly those strings that have an indexed nGram.  If the string is larger than
te largest nGram specified in this dictionary, return an empty collection"</em>
|nGram|
nGram := self nGrams at: aString size ifAbsent: [nil].
^nGram notNil
   ifTrue: [nGram at: aString ifAbsent: [OrderedCollection new]]
   ifFalse: [Bag new]

<strong>nGramed: aCollectionofStrings n: length</strong>
<em>"private.  Return a dictionary of all nGrams or order length for the given collection of strings, excluding nGrams with punctuation or numbers"</em>
|ngram e words |

ngram := Dictionary new.
aCollectionofStrings
do: [:each |
   e := each asLowercase.
   1 to: e size - length + 1 do: [:i |
        words := (e copyFrom: i to: i + length -1) subStrings: '., :;- ()[]!!''&amp;%/#+0123456789'.
        (words size &gt; 0 and: [words first size = length]) <em>"split it, save if still the same length"</em>
       ifTrue:
         [(ngram at: words first ifAbsentPut: [OrderedCollection new]) add: each]
       ]
 ].
^ngram

<strong>nGrams</strong>
<em>"Private. lazily initialized"
</em>    ^ myNGrams ifNil:
[myNGrams := Dictionary new.
mySmallest to: myLargest do: [ :i |
   myNGrams at: i put: (self nGramed: myCollectionofStrings n: i) ].
   myNGrams yourself ]

<strong>on: aCollectionofStrings from: start to: finish</strong>
<em>"initialization method"</em>
myCollectionofStrings := aCollectionofStrings.
mySmallest := start.
myLargest := finish

<strong>search: aString</strong>
<em>"returns a collection of strings that contain aString.  If there's not an nGram available, do a </em>select: , which is slower of course'"
|nGram searchstring|
searchstring := aString asLowercase.
searchstring size &lt;= myLargest
  ifTrue:
     [nGram := self nGrams at: searchstring size.
     ^nGram at: searchstring ifAbsent: [OrderedCollection new]]
  ifFalse:
     [nGram := self nGrams at: myLargest.
     ^(nGram at: (searchstring copyFrom: 1 to: myLargest) ifAbsent: [OrderedCollection new])
select: [: each | each asLowercase includesSubString: searchstring]
     ]</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=47</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Decorators as Guards</title>
		<link>http://www.adhocalley.com/?p=45</link>
		<comments>http://www.adhocalley.com/?p=45#comments</comments>
		<pubDate>Thu, 06 Aug 2009 17:56:16 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=45</guid>
		<description><![CDATA[I&#8217;m exploring a new pattern &#8211; I&#8217;m sure it&#8217;s been done before, but it&#8217;s new to me, and a useful exercise to get to the next stage with an application I&#8217;m envisioning.  The pattern is using Seaside Decorators as security guards. So, last night, finally squeezed in enough time to my decorator guards into action.  [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m exploring a new pattern &#8211; I&#8217;m sure it&#8217;s been done before, but it&#8217;s new to me, and a useful exercise to get to the next stage with an application I&#8217;m envisioning.  The pattern is using Seaside Decorators as security guards.</p>
<p>So, last night, finally squeezed in enough time to my decorator guards into action.  Happy to report they&#8217;re working fine.  You can review the demo app yourself at <a href="http://agoric.seasidehosting.st/seaside/ibis" title="IBIS">agoric.seasidehosting.st/seaside/ibis</a> .  Login as bob@test.com, password bob, or alice@test.com, password alice.<span id="more-45"></span></p>
<p>I&#8217;m not completely proud of this code &#8211; it&#8217;s a quick hack, needs some refactoring.  And, cosmetics are not pretty &#8211; will need to do some CSS prettifying soon.  The &#8220;guard&#8221; itself takes a traditional, ACL-lookup approach to security, and I&#8217;d like to refactor that to more of a capabilities approach, but ACLs work fine for now: straightforward, familiar and easy to understand.  Here&#8217;s what the Guard itself look like:</p>
<p><code></code></p>
<pre>
WADecoration subclass: <strong>#IBSecEditGuard</strong>
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'IBIS'

<strong>renderContentOn: html</strong>
<em>"if usr has access rights, render appropriate action buttons, then render object itself"</em>

	html div class: 'editframe';style: 'margin-left: ',(self owner level *3) asString, 'em';
	with: [
	self userIsEditor ifTrue: [
		html span class: 'cmd'; with: [
			html anchor callback: [ self edit]; with: 'edit'.]].
		html space.
	   self renderOwnerOn: html]

<strong>userIsEditor</strong>
	^(self editorsfordoc contains: self session user)
	  or: [self session user = self owner doc author]

<strong>canedit</strong>

	^(self allowededitors contains: self session user)

<strong>editorsfordoc
	</strong>^ IBSecGuard editorsfordoc: self owner doc

<strong>edit</strong>
	self owner edit</pre>
<p>To deploy the guard, add it as a decorator to an appropriate view, using addDecoration:.</p>
<p><code></code></p>
<pre>
<strong>IBISDocView&gt;&gt;initialize</strong>

	super initialize.
	myEditor := IBISDocumentEditor new.
	myLevel := 0.
	<strong><em>self addDecoration: IBSecEditGuard new.</em></strong>

<strong>IBISDocView&gt;&gt;renderContentOn: html</strong>
        html span class: 'cmd'; with: [html anchor callback: [self answer: true]; with: 'back'].
        html div class: 'doc';
           with:
              [html paragraph class: 'title';
                  with: [html text: myDoc type, ': ', myDoc title.
                           html span class: 'author'; with: ' (',myDoc author userName,')'].
               html paragraph class: 'text'; with: [html text: myDoc text].
].</pre>
<p>So, the view here is not at all concerned with security.  It renders the object (myDoc) visible, and has a pointer to the document&#8217;s editor view, but doesn&#8217;t involve itself in whether a user has edit access or not &#8211; that&#8217;s the Decorator&#8217;s job.  Security, like persistence and logging, are typical application needs, and it&#8217;s nice to provide an external framework to provide those services, instead of intermingling security with presentation with business logic code.  My demo here provides security with the one line addition of a Decorator object, and that object itself is just around 10 lines of code.</p>
<p>As I mentioned, this is still just a hack; there&#8217;s some refactoring that will be welcome, and I&#8217;ll likely abandon the ACL approach in favor of a more capabilities-oriented approach; and, I envision a more general way of visually adding &#8220;commands&#8221; (like the edit anchor link) to the Decorator view, in such a way that it can support multiple command links, in a chain of decorators &#8230; but this is a good start.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=45</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Health Care &#8211; costs vs. price</title>
		<link>http://www.adhocalley.com/?p=46</link>
		<comments>http://www.adhocalley.com/?p=46#comments</comments>
		<pubDate>Wed, 05 Aug 2009 22:11:52 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=46</guid>
		<description><![CDATA[It&#8217;s oft repeated that health care costs continue to rise at a crazy pace.  While most costs of most products and services have been decreasing, in terms of &#8220;real&#8221;, inflation-adjusted dollars, health care, like education, have been increasing at record paces.  And, unlike the housing/real estate &#8220;bubble&#8221;, there doesn&#8217;t seem to be an end in [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s oft repeated that health care costs continue to rise at a crazy pace.  While most costs of most products and services have been decreasing, in terms of &#8220;real&#8221;, inflation-adjusted dollars, health care, like education, have been increasing at record paces.  And, unlike the housing/real estate &#8220;bubble&#8221;, there doesn&#8217;t seem to be an end in sight.  What&#8217;s going on?</p>
<p>Most commentators talk about health care cost increases.  However, the evidence I see suggests something different.  Yes, we&#8217;re seeing health care <em>price</em> increases.  But <em>cost</em> increases? There&#8217;s a difference.</p>
<p><span id="more-46"></span><em>Caveat: I am not a professional economist.  I&#8217;m one of those infamous ABDs &#8211; All But Dissertation.  Finished all my PhD courses, passed my comprehensive exams, got my dissertation subject approved and committee formed, etc., but then business opportunities and disenchantment with the academic profession took me down another path.  My observations here are anecdotal; I&#8217;ll let me economist friends get into the more detailed facts and stats.<br />
</em></p>
<p>An industry with rapidly increasing costs exhibits widely different behavior that what we&#8217;re seeing in health care (higher education too, for that matter).  Firms in high cost environments are struggling to stay alive, raising prices only reluctantly to keep up with costs, being squeezed by the costs around them.  Capital expenditures are delayed, or addressed shabbily.  When capital money is spent, it is usually on cost improvement or efficiency projects, not expansion projects.  Corporate boards force austerity measures on upper management. Firms look toward lower cost environments.  Instead of locating offices in shiny office towers, you&#8217;ll find the administration located in warehouses, or going offshore. Etc., etc.</p>
<p>Industries facing increasing cost environments are typically &#8220;mature&#8221; industries, where their product has been commoditized, little room for innovation, plenty of uniform competition.  Price increases become difficult, as consumers can always buy at the next, cheaper, homogeneous producer; the company finds itself squeezed every time it sees increases in the costs of its inputs and supplies.  Companies making coat hangers, electrical wiring, and other commodities are such examples.</p>
<p>What do we, though, see in the health care industry?  Lot&#8217;s of shining towers, gold-plated board rooms, huge growth &#8211; that&#8217;s what I see.  I live just a mile and a half from the famed Texas Medical Center.  It has been growing at a crazy pace in the last 10 years I have lived here, gobbling up my former residence, the beloved Parkwood Apartments, filling in former parking lots with more buildings, and now even encroaching within a half mile of my house, buying up a former strip shopping center.  Construction cranes still dominate the TMC skyline to this day.  Is this a center struggling to keep with costs??</p>
<p>One interesting example: when Baylor University couldn&#8217;t come to terms with Methodist Hospital about becoming a joint teaching hospital (like the UT/Hermann Hospital arrangement), they said, &#8220;okay, we&#8217;ll build our own hospital&#8221;, tearing down the 50+ year old Parkwood Apartments.  It wasn&#8217;t an issue of not having enough room within Methodist, or overcrowded rooms, opatients overflowing into the hallways, or too much demand, it&#8217;s just that they couldn&#8217;t come to terms with their potential party.  And they had enough money to walk away from the partnership without consequence.</p>
<p>Then, we can talk about Big Pharm.  One of my long-term friends was enticed to move to New Jersey several years ago, with the promise of a 6-figure salary (first time for him), working as an environmental consultant for a big pharmaceutical firm.  He quit after a year?  &#8220;Why?&#8221;, I asked him.  His response: couldn&#8217;t stand the ethics of the pharmaceutical industry.  He described the lavish offices, the super-large expense accounts, the constant &#8220;entertainment&#8221; the companies would lavish on their potential customers &#8211; that is, doctors.  This is not an industry bitten by high costs, but one that is able to drive high prices, allowing them to afford all this lavishness.</p>
<p>This is symptomatic of an industry where customers are willing and able to pay for such high prices.  We see it with vacation resorts, high dollar clothing, jewelry, etc., where the customers have the money and are spending it.</p>
<p>What, you say?  I can barely afford health care now &#8211; how am I driving up prices??  Well, You&#8217;re not &#8211; in many cases, you are not the consumer.  The New Yorker ran recently ran a piece on rising health care costs, by examining the one of the highest Medicare cost per capital county in the nation, Hidalgo County, TX.  It is also has the  lowest household income in the nation &#8211; that is, it is very poor.  The author was looking for answers as to why, invoking cultural reasons (aggressively entrepreneurial Hispanics, lack of leadership-oriented &#8220;anchor tenants&#8221;, etc.), all of which  are very interesting.  But, as I read through the 8 page article, I couldn&#8217;t help but asking: &#8220;author, aren&#8217;t you seeing the connection between poorest county and highest cost?&#8221;  That is, it seemed obvious to me, that because Hidalgo County was the poorest in the nation, its citizens weren&#8217;t the real health care consumers &#8211; Medicare was.  And, Medicare, as a consumer, doesn&#8217;t really check up on things.  Sure, it puts a cap on prices paid for specific procedures, but it doesn&#8217;t really evaluate just how many procedures are necessary for a patient.  As a result, as the author documented, there&#8217;s a proliferation of procedures, a tendency toward procedure escalation too: choosing the higher-price, easier procedure over perhaps the prudent one.  With Medicare as the consumer, there&#8217;s really no control.</p>
<p>And that&#8217;s the way it is with you too.  You&#8217;re consume health care services, for sure, but the real &#8220;consumer&#8221; is Medicare and insurance companies.  (<em>an aside insurance, like banking, securities, etc., is one of the most highly regulated industries in this country</em>). And who are insurance companies biggest consumers?  Why, big corporations, of course.</p>
<p>Because of tax incentives, in a very bizarre twist of history, companies have become the biggest providers of health insurance to individuals.  It&#8217;s really kind of strange, finding yourself beholden to a employer because of its &#8220;benefits&#8221;.  In an otherwise individualist nation, we&#8217;ve come to expect corporations to provide health insurance, instead of us employees negotiating higher pay and paying for health insurance ourselves -  perhaps joining co-ops, mutual benefit societies, professional groups, neighborhood associations, etc. to get group rates.  As a nation that has supposedly become more &#8220;progressive&#8221; over the last century, this adulation of the corporation is weird.</p>
<p>But, look at the real result of corporate-oriented (oh, I shouldn&#8217;t forget unions also) health insurance policies: they&#8217;re more likely to be gold-plated, benefiting the decision-makers within corporations, that is upper-management, while of course passing some crumbs onto the rank-and-file.  So, we&#8217;ve got gold-plated, luxury health insurance plan dollars and Medicare dollars chasing our health care expenses.  No wonder it&#8217;s a high price, not high cost, environment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=46</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cash Drawer Counter in Seaside</title>
		<link>http://www.adhocalley.com/?p=44</link>
		<comments>http://www.adhocalley.com/?p=44#comments</comments>
		<pubDate>Thu, 23 Jul 2009 07:18:13 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=44</guid>
		<description><![CDATA[This is a simple application I wrote, just to learn more about Seaside, and specifically to figure out onChange: actions, which makes use of Scriptaculous to create an AJAXy web application without much effort. You can see the application at work at: agoric.seasidehosting.st/cashdrawer WAComponent subclass: #MoneyCounter instanceVariableNames: 'count myTotal mySlots' classVariableNames: '' poolDictionaries: '' category: [...]]]></description>
			<content:encoded><![CDATA[<p>This is a simple application I wrote, just to learn more about Seaside, and specifically to figure out <strong>onChange:</strong> actions, which makes use of Scriptaculous to create an AJAXy web application without much effort.</p>
<p>You can see the application at work at:</p>
<p><a href="http://agoric.seasidehosting.st/cashdrawer">agoric.seasidehosting.st/cashdrawer</a></p>
<p><code></code></p>
<pre><span id="more-44"></span>

<strong>WAComponent subclass: #MoneyCounter
instanceVariableNames: 'count myTotal mySlots'
classVariableNames: ''
poolDictionaries: ''
category: 'MoneyChanger'</strong>

<strong>total</strong>
| total |
  total := 0.0.
  mySlots do: [ :each | total := total + each total ].
^ total</pre>
<pre><strong>total: amount</strong>
<em>  "ignore"
</em>
<strong>initialize</strong>

  super initialize.
  myTotal := 0.
  count := 0.
  mySlots := OrderedCollection new.
  mySlots
  add: (MoneySlot new createNew: 'pennies' withValue: 0.01);
  add: (MoneySlot new createNew: 'nickles' withValue: 0.05);
  add: (MoneySlot new createNew: 'dimes' withValue: 0.1);
  add: (MoneySlot new createNew: 'quarters' withValue: 0.25);
  add: (MoneySlot new createNew: 'dollars' withValue: 1.0);
  add: (MoneySlot new createNew: 'fives' withValue: 5.0);
  add: (MoneySlot new createNew: 'tens' withValue: 10.0);
  add: (MoneySlot new createNew: 'twenties' withValue: 20.0);
  add: (MoneySlot new createNew: 'fifties' withValue: 50.0);
  add: (MoneySlot new createNew: 'hundreds' withValue: 100.0);
  add: (MoneySlot new createNew: 'penny rolls' withValue: 0.50);
  add: (MoneySlot new createNew: 'nickle rolls' withValue: 2.0);
  add: (MoneySlot new createNew: 'dime rolls' withValue: 5.0);
  add: (MoneySlot new createNew: 'quarter rolls' withValue: 10.0)</pre>
<pre><strong>updateRoot: anHtmlRoot</strong>

  super updateRoot: anHtmlRoot.
  anHtmlRoot title: 'MoneyCounter'.

<strong>updateTotal</strong>

  myTotal := self total</pre>
<pre><strong>renderContentOn: html</strong>

  html div class: 'main'; with: [
  html heading: 'Money Counter'.
  self renderFormOn: html]

<strong>renderFormOn: html
</strong>
html form id: 'f'; with: [
html table:
[mySlots do: [:each | self renderRow: html forSlot: each].
html tableRow:
[ html tableData:  [ html text: 'TOTAL'; space];
tableData:  [ html span id: 'total' ; with: self total ] ] ] ]</pre>
<pre><strong>renderRow: html for: type</strong>

  html tableRow:
  [ html tableData:  [ html text: type asString];
    tableData:
    [ html textInput
        id: type asString;
        on: type asSymbol of: self;
        onChange:
          (html updater id: 'total';
                triggerFormElement: type asString;
                callback: [ :r  |  self renderTotalOn: r])
   ] ]</pre>
<pre><strong>renderRow: html forSlot: aSlot</strong>
  html tableRow:
    [ html
      tableData: [ html text: aSlot name ];
      tableData:
        [ html textInput
          id: aSlot name asString;
          on: #quantity
          of: aSlot;
          onChange:
            (html updater
                  id: 'total';
                  triggerFormElement: aSlot name asString;
                  callback: [ :r | self renderTotalOn: r ]) ] ]

<strong>renderTotalOn: html</strong>
  html render: self total</pre>
<pre>
<strong>style</strong></pre>
<pre>^ 'span {font-weight: bold}
  body {margin-left: 5%}
  div.main {background-color: rgb(215,250,179);padding-left: 1em;width: 250px;border: 1px solid rgb(161,196,127)}
  input {width: 60px; text-align: center}
  table {margin-left: 1em; text-align: right}'</pre>
<pre><em>"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "</em></pre>
<pre>
<strong><em>MoneyCounter class
instanceVariableNames: ''</em></strong>

<strong>canBeRoot</strong>
^true</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=44</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Hottest Summer in Houston</title>
		<link>http://www.adhocalley.com/?p=43</link>
		<comments>http://www.adhocalley.com/?p=43#comments</comments>
		<pubDate>Tue, 23 Jun 2009 23:54:16 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=43</guid>
		<description><![CDATA[1980 remains the hottest summer in Houston: 14 consecutive 100+ degree days, a high of 107, and 32 days altogether at 100 or above. Yep, I remember that summer well: I was a lifeguard that year &#8211; and by the end of the summer, a coach, swim teacher, a pool cleaner, and a front-desk clerk [...]]]></description>
			<content:encoded><![CDATA[<p>1980 remains the hottest summer in Houston: 14 consecutive 100+ degree days, a high of 107, and 32 days altogether at 100 or above.</p>
<p>Yep, I remember that summer well: I was a lifeguard that year &#8211; and by the end of the summer, a coach, swim teacher, a pool cleaner, and a front-desk clerk as well.  I ended up with all the jobs at this local community pool, because workers were dropping like flies!  Seriously, by mid-summer every local kid had quit, and I kept picking up additional job duties; by the end of summer, I was working 12-14 hours a day.</p>
<p><span id="more-43"></span>It was a great boost for my college fund: even though I had won a scholarship for school the following year, it was nice to collect extra money like this for books, car, dating, etc.</p>
<p>There were lots of benefits of being able to tolerate the heat, including having nice calloused feet to walk on hot concrete. Beyond the money, my hair was sun-bleached blond, I built up a nice tan (of course, I lathered in SPF &#8211; didn&#8217;t want to get that skin cancer that plagued older colleagues that I saw the summer prior in Galveston), got plenty of attention from girls (well, uh, with an average age of say 11 &#8211; community pool lifeguarding is as much a babysitting job as serious life saving), and I never had to say &#8220;would you like fries with that?&#8221;</p>
<p>The summer of &#8217;81 didn&#8217;t break as many records, but was still plenty hot and dry.  That year, to stay in shape (I still ran track and cross country) I decided to pick up a job as a common laborer at a local chemical plant &#8211; shoveling sand and concrete for a new construction project.  And, heck, the money was good! Lifeguarding paid well above minimum wage, but this job paid double what a lifeguard could get.</p>
<p>This summer proved just as amusing on the co-worker job front.  The rest of the common labor pool was Mexican, and that year the INS decided to launch &#8220;Operation Jobs&#8221;.  Yeah, seriously, that&#8217;s the name they gave it.  First, they raided our construction site, rounding up all the undocumented workers.  Our crew went down from 26 to 1 &#8211; plus one asshole of a foreman, who was white.  Of course the company whined to the INS: &#8220;how can we complete our work?&#8221;.  The INS responded, &#8220;no problem, we&#8217;ll hire true-blue Americans for you&#8221;.  And sure enough, they did &#8211; setting up trailers near the plant entrance, sending out recruitment posters, processing and vetting all applications.  Within a week, our crew was back up to 25 (I should note that the skilled labor pool was already all American &#8211; carpenters, equipment operators, and such were union jobs, so were quite protected, and coveted,job positions).</p>
<p>This didn&#8217;t last last long. Within 2 weeks, most of the new hires had quit.  One hot afternoon there was a fellow shoveling sand beside me, when he suddenly threw his shovel down, saying &#8220;fuck this, I can make more on welfare&#8221;, and proceeded to walk toward the exit gate &#8211; he exemplified the bunch.  Other workers just didn&#8217;t show up the next day.  However, our labor pool didn&#8217;t shrink this time.  As the INS designees were quitting, little by little our original crew started to re-appear.  The ones that could speak English told me of their adventures: a free bus ride home, time to visit with family, and then back to Houston the same way they made it last time &#8211; by sneaking across the border again.</p>
<p>Within 3 weeks we had zero, yes zero, of the INS-hired pool.  Twenty of the original workers, though, were back on the job, and we picked up a few more, probably undocumented as well, that tagged along with these workers.  For sticking it out in the heat, I got promoted to driving a pick-up truck around the work site, delivering water and tools wherever needed, plus determining when to add ice or Gatorade to the water coolers &#8211; &#8220;Don&#8217;t waste the Gatorade when it&#8217;s below 100, asshole&#8221; the foreman would scream, and ice only when it hit 102.</p>
<p>Yeah, hot summer memories.  Now, when people ask me if it&#8217;s too hot in Houston, I say, &#8220;no, not really&#8221;, just like when they ask me if the food is spicy.  <img src='http://www.adhocalley.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=43</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Seaside &#8211; how to change a page&#8217;s title</title>
		<link>http://www.adhocalley.com/?p=41</link>
		<comments>http://www.adhocalley.com/?p=41#comments</comments>
		<pubDate>Fri, 22 May 2009 19:02:24 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=41</guid>
		<description><![CDATA[I know I&#8217;ve seen the answer to this before, but had a hard time tracking it down, so thought it worthwhile to post. To change the web page&#8217;s HTML title (or any other head information) for a web component, create a method updateRoot: .  This method will be called when the component is rendered on [...]]]></description>
			<content:encoded><![CDATA[<p>I know I&#8217;ve seen the answer to this before, but had a hard time tracking it down, so thought it worthwhile to post.</p>
<p>To change the web page&#8217;s HTML title (or any other head information) for a web component, create a method <strong>updateRoot:</strong> .  This method will be called when the component is rendered on the page &#8211; remember to always super the call too.</p>
<pre><strong>component&gt;&gt;updateRoot: anHtmlRoot</strong>
    super updateRoot: anHtmlRoot.
    anHtmlRoot title: 'fooTitle'.
   <em> "do anything else you'd like to Root here too"</em></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=41</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Updater examples with Scriptalicious &amp; Seaside</title>
		<link>http://www.adhocalley.com/?p=40</link>
		<comments>http://www.adhocalley.com/?p=40#comments</comments>
		<pubDate>Thu, 21 May 2009 04:16:20 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=40</guid>
		<description><![CDATA[The first of a series of coding vignettes in Seaside.  Context: a web app with a form containing multiple input fields.  Instead of waiting to submit the form, I want the page to update another element every time an input is changed.  In this example, a total field.  Solution was used for a simple MoneyCounter [...]]]></description>
			<content:encoded><![CDATA[<p><em>The first of a series of coding vignettes in Seaside.</em></p>
<p><strong> Context:</strong> a web app with a form containing multiple input fields.  Instead of waiting to submit the form, I want the page to update another element every time an input is changed.  In this example, a total field.  Solution was used for a simple MoneyCounter application:</p>
<pre>
<strong>MoneyCounter&gt;&gt;renderContentOn: html </strong>html form id: 'f'; with: [

html table: [
    html tableRow:
     [html tableData: [html text: 'pennies'];
           tableData:
         [html textInput
           id: 'pennies';
 	   "on: #pennies of: self;"
           callback: [:value | self pennies: value];
 	   onChange: (html updater
                       id: 'total';
		       triggerFormElement: 'pennies';
 		       callback: [ :r  |  self renderTotalOn: r])
       ] ]

<em>    etc.</em>

    html tableRow:
      [html tableData: [html text: 'TOTAL'; space];
            tableData: [html span id: 'total' ; with: self total]]]]</pre>
<pre></pre>
<pre>

<strong>MoneyCounter&gt;&gt;renderTotalOn: html</strong>

 html render: self total</pre>
<pre><strong>MoneyCounter&gt;&gt;pennies: value
</strong></pre>
<pre>   pennies := value

<strong>MoneyCounter&gt;&gt;total</strong>
	^((pennies asInteger * 0.01) +  <em>etc.   </em>)</pre>
<p><span id="more-40"></span>The real action demonstrated here is in <strong>onChange:</strong> . onChange will accept a Javascript function or an SUUpdater to automagically do the Javascript functioning.  <strong>html updater</strong> returns just such an SUUpdater, and the two important things this updater does is a define a callback block of code &#8211; this block will be called everytime onChange is triggered &#8211; in this case, to <strong>renderTotalOn</strong>.  Important, though, for this block to work correctly, is to also call <strong>triggerFormElement</strong>. This will trigger the callback block on the element itself, <strong>callback: [:value | self pennies: value]</strong>, then also do the  updater callback. Without the triggerFormElement, calling renderTotalOn will update the total with the &#8220;old&#8221; value of <em>pennies</em>, instead of what the user had currently entered.</p>
<p>In simple English, whenever the input field is changed, update the value that is bound to the field, then update the Total field.</p>
<p>For this to work appropriately, it&#8217;s also important to set element ids correctly.   The updater also seems to require an id &#8211; and seemingly that id must be the same as the element that it is updating, but I&#8217;m not exactly clear on this yet.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=40</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tax Savings for Software Companies in Texas</title>
		<link>http://www.adhocalley.com/?p=39</link>
		<comments>http://www.adhocalley.com/?p=39#comments</comments>
		<pubDate>Mon, 23 Feb 2009 16:34:00 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=39</guid>
		<description><![CDATA[For the past 6 years, one of the major specialties of my company is writing software applications dealing with corporate taxation.  This has usually been internal, custom apps for a corporate tax department, but recently we have entered a partnership with a local accounting firm to do some web service-based applications. The first of these [...]]]></description>
			<content:encoded><![CDATA[<p>For the past 6 years, one of the major specialties of my company is writing software applications dealing with corporate taxation.  This has usually been internal, custom apps for a corporate tax department, but recently we have entered a partnership with a local accounting firm to do some web service-based applications.</p>
<p>The first of these applications is now available for beta testing, so now I&#8217;m reaching out to all Texas-based software development companies to help with testing out this application, as well as potentially save money on your taxes.  You may qualify!</p>
<p><span id="more-39"></span>The tax savings is simple &#8211; Texas legislature has been nice to manufacturers here, making them exempt on Sales or Use taxes for equipment they purchase that is used directly for manufacturing (that car you bought for your best salesperson? Not exempt, it&#8217;s marketing.  That machine press you bought to make widgets &#8211; exempt).   <strong>This exemption also extends to the electricity or natural gas</strong> you use for manufacturing.  Large companies have taken advantage of this exemption for years, but smaller manufacturing often has not, either because they&#8217;re not aware or because of the hurdles and expense they have to go through to be declared exempt.  And, little known to many is that software development firms that make applications <strong>are also considered manufacturers</strong>.</p>
<p>We have written an application that reduces this expense and  lowers the hurdles. The application allows you to start your own <strong>Predominant Use Study</strong>, an engineer-certified study that is required for you to get your exemption.  The study is simply a database of all the electrical equipment (NG requires a separate study) in your facility, separating equipment used for manufacturing vs. other uses (administrative, marketing, etc.).  If more than 50% of your electrical consumption is manufacturing-related, you will be exempt for ALL your sales tax on utilities, and you may also be entitled a refund of 4 years back taxes.  That could be significant savings.</p>
<p>The surprise is that software development firms are also considered manufacturers, if they develop pre-packaged software product.  Consulting and services software firms don&#8217;t qualify.  I&#8217;m not a tax accountant, so I can&#8217;t describe all the situations where you may be a manufacturer or not, but in most cases when you develop software that is for sale (or licensed for sale), then you likely qualify.</p>
<p>But, do you directly pay electricity costs?  Many of us smaller firms do not &#8211; electricity may be part of our rent, but if you rent your own building, or otherwise pay your own utilities, this may be of interest to you.  Since there are still costs involved with certifying a study (an certified engineer in Texas must still sign off on it), I figured the tax savings are worth the costs if you have, say, 10 developers or so on staff and you pay your own utilities &#8211; smaller firms with a $500/month utility bill likely won&#8217;t see any savings.  However, with the use of our application the price point has dropped considerably (previously, Predominant Use Studies would cost on the order of $5 -$25 thousand dollars &#8211; that&#8217;s why only the big manufacturers took advantage of it), so more manufacturers can take advantage of this exemption.</p>
<p>If you are a manufacturer, including software product companies, and would like to help us test this application, please contact me via email, comment on this page, or DM via Twitter, and I can point you to the URL to set-up your own account and begin your electrical study.  Beta testing open now!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=39</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sqwitter &#8211; demonstrating a Seaside app</title>
		<link>http://www.adhocalley.com/?p=37</link>
		<comments>http://www.adhocalley.com/?p=37#comments</comments>
		<pubDate>Wed, 27 Aug 2008 08:25:38 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=37</guid>
		<description><![CDATA[Squser&#62;&#62;allSqweets &#8220;returns messages from self and friends&#8221; &#124; allsqweets &#124; allsqweets := SortedCollection sortBlock: [ :a :b &#124; a timestamp &#60; b timestamp ]. allsqweets addAll: self messages. myFriends do: [ :each &#124; allsqweets addAll: each messages ]. ^ allsqweets &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- allSqweets  is a simple 4 line method, but delivers the core feature of Twitter: [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Squser&gt;&gt;allSqweets</strong><br />
<span style="color: green">&#8220;returns messages from self and friends&#8221;</span><br />
| <em>allsqweets</em> |<br />
<em>allsqweets</em> := <strong>SortedCollection</strong> sortBlock: [ :a :b | a timestamp &lt; b timestamp ].<br />
<em>allsqweets</em> addAll: self<strong> messages</strong>.<br />
myFriends do: [ :<em>each</em> | <em>allsqweets</em> addAll: <em>each</em> messages ].<br />
^ <em>allsqweets</em></p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p><strong>allSqweets</strong>  is a simple 4 line method, but delivers the core feature of Twitter: displaying a timeline of all a user&#8217;s  and his friends&#8217; messages.  And thus started my exploration into Seaside, a Smalltalk framework for developing web applications.</p>
<p>I started<a href="http://www.adhocalley.com/?p=9"> playing around with Seaside</a> last year, but time constraints prevented me from getting too far.  But, I&#8217;m at it again.  This latest burst of energy was in part generated by the &#8220;fail whale&#8221; of Twitter.  Prompted by friends, I started using Twitter a lot from the early part of this year.  Pretty cool, simple application, yet, why does it keep crashing?  Hey, though, it&#8217;s got a million users, so give it a break.</p>
<p>A more perplexing problem, to me at least, was the linking of replies.  Or the lack of said linking.  I click &#8220;reply&#8221; to someone&#8217;s twitter, post my reply.  There&#8217;s even a link on my posting &#8220;in reply to &#8230;&#8221;.  Click on it, and more times than not, it would link back to some other message, not the message I was replying to.  What&#8217;s up with that?  It got me thinking: conceptually, Twitter is a really simple application: what would it look like in Smalltalk?  Not trying to solve performance problems or scalability or anything real like that, but simply as a pure object exercise, just what would Twitter look like in Smalltalk?</p>
<p>I&#8217;ve been looking around for other web frameworks to develop in.  That&#8217;s why I&#8217;ve given Seaside a serious look.  On the prompting of other friends, I recently gave Ruby on Rails a look, and earlier had glanced over at Django.  Both, surprisingly, kind of gave me the shudders: pop in some code for your initial objects, and they auto-generate lots of code for you.  All code broken down into a clean separation of concerns: model files here (class definitions), view files there (web templates), controllers over there.  Nice, but now I&#8217;ve got lot&#8217;s of files, and I&#8217;ve got to navigate my way around to figure out what to modify where.  I&#8217;m sure once you get used to it, it&#8217;s easy to remember what directory has what files, but I&#8217;m impatient you see, and don&#8217;t have much spare time (see above).</p>
<p>All these files reminded me of my C development days, with scores of header files (.h), code files (.c), and my own make files, etc.  I&#8217;m not knocking these frameworks on the Ruby or Python languages &#8211; long ago, I learned that language wars are useless.  But, maybe it&#8217;s just my aesthetic:  I&#8217;ve always found Smalltalk super clean and easy to read and navigate, and it remains my fastest development language.  So, yeah, maybe Ruby and Python are &#8220;Rapid-Enough&#8221; Application Development environments, compared to, say Java or Visual Basic, but I yearn for truly Rapid Application Development again.</p>
<p>Then came Barcamp Houston.  Kind of creeped up on me.  It wasn&#8217;t til the morning of the conference when I suddenly got inspired:  I should present something here!  But, a late start to the day, and an already depleted laptop battery proved challenges for preparing any kind of presentation, much less something that wouldn&#8217;t embarress me.  I would need to spend a little time relearning the Seaside environment (which has undergone a few point releases since last year), and thinking through an application.</p>
<p>Then my thoughts went back to the Twitter applicaiton.  Wouldn&#8217;t that be a simple application to demonstrate within Seaside?  And sure enough, it was been: in fact, too simple to demonstrate some of Seaside&#8217;s more powerful features (like tasks and workflow &#8211; the real meat of &#8220;continuations&#8221;).  Nevertheless, a good test case to begin.</p>
<p>So, I still don&#8217;t have much time in my busy schedule, what with my own projects, my business, family, assisting in the launching of my wife&#8217;s new restaurant, etc., but I have been able to squeeze in a few hours here and there to develop <strong>Sqwitter</strong>, an implementation of Twitter in Squeak and Seaside.  The next several blog postings will walk through my development of Sqwitter, and should serve as a useful tutorial for Seaside (there are already some excellent tutorials on the web, and a book too).  When I finish the code, I&#8217;ll also roll the application out to a demonstration website for readers to play.</p>
<p><strong>Next:</strong> Sqwitter objects and Seaside components.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=37</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to Cpk the SQL Way</title>
		<link>http://www.adhocalley.com/?p=35</link>
		<comments>http://www.adhocalley.com/?p=35#comments</comments>
		<pubDate>Sat, 05 Jul 2008 20:32:51 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=35</guid>
		<description><![CDATA[As mentioned earlier, I&#8217;ve been involved in client&#8217;s Production Reporting application project, when the subject of Cpk came up.  After a lot of inconsistent references to the statistic and lot&#8217;s of code that approximated but didn&#8217;t exactly calculate it, I finally discovered the proper formula for  Cpk.  Here it is: Cpk  =   min (  USL [...]]]></description>
			<content:encoded><![CDATA[<p>As mentioned <a href="http://www.adhocalley.com/?p=34" title="Cpk Introduction">earlier</a>, I&#8217;ve been involved in client&#8217;s Production Reporting application project, when the subject of C<span style="vertical-align: sub">pk</span> came up.  After a lot of inconsistent references to the statistic and lot&#8217;s of code that approximated but didn&#8217;t exactly calculate it, I finally discovered the proper formula for  C<span style="vertical-align: sub">pk</span>.  Here it is:<code><br />
C<span style="vertical-align: sub">pk</span>  =   min (  USL - μ / 3 * <img src="http://upload.wikimedia.org/math/a/9/8/a98791f05c03da82c1b05f361069b353.png" class="tex" alt="\hat{\sigma}" />, μ - LSL / 3 * <img src="http://upload.wikimedia.org/math/a/9/8/a98791f05c03da82c1b05f361069b353.png" class="tex" alt="\hat{\sigma}" />)<br />
</code><br />
Where <em>USL</em> is the Upper Specification Limit, <em>LSL</em> is the Lower Specification Limit,  μ is the <em>arithmetic mean</em> of the results and <img src="http://upload.wikimedia.org/math/a/9/8/a98791f05c03da82c1b05f361069b353.png" class="tex" alt="\hat{\sigma}" />, sigma hat, is the estimated standard deviation (sigma hat is going to turn out to be the kicker in this equation).</p>
<p>Let&#8217;s say you have a product you have to make that must be within some specifications: like, the length of a sub sandwich.  It should always be 12&#8243; long, but it&#8217;s acceptable if the final sandwich comes out between 11&#8243; (LSL) and 13&#8243; (USL).  Cpk is the minimum of either the average deviation from the upper limit divided by 3 times the estimated standard deviation, or the average deviation from the lower limit divided by 3 times the standard deviation.</p>
<p>All this would be easy to calculate using SQL if just plain ole standard deviation were involved.  However, using standard deviation instead of estimated standard deviation (sigma vs. sigma hat), and you have the equation for P<span style="vertical-align: sub">pk</span>, a  different statistic.   Always one to be lazy, I ask our client: &#8220;would it be okay to report just the Ppk statistic?&#8221;  Of course, the answer was no!<span id="more-35"></span></p>
<p>So, I had to figure out how to compute sigma hat.  And, I wanted to do this exclusively in SQL.  Surprisingly, in my many searches on the Internet, I wasn&#8217;t able to find any example code to accomplish this.  Hence my reason for writing this posting.  I&#8217;ve solved the problem in SQL (at least to my satisfaction), and want to share my results with the world.</p>
<p>Doing a little research, I discovered sigma hat, that is, estimated standard deviation, was created a little before computers were popular and the statistic had to be hand computed on the field.  It&#8217;s an interesting measure, though, as it measures the variation between <em>successive</em> measures of the process results, instead of the overall standard deviation.  In a nutshell, it tells  you how much a process is varying step by step.  If one sandwich were 12.5&#8243;, the next 11.5&#8243;, then back to 12.5&#8243;, the standard deviation would be rather low, but many manufacturers would agree that it&#8217;s not really a good process &#8211; it would be better if the maker were hitting consistently off target than skipping around so much.  For example, if it were making sandwiches 11.5&#8243; consistently, machine could be adjusted to get it closer to the target 12&#8243; value.  If it&#8217;s skipping around so much,  something unpredictable is happening.  Statistically, regular standard deviation would hide this situation, while estimated standard deviation would perhaps highlight a problem.</p>
<p>The formula for sigma hat is:</p>
<p><code><br />
<img src="http://upload.wikimedia.org/math/a/9/8/a98791f05c03da82c1b05f361069b353.png" class="tex" alt="\hat{\sigma}" /> = R-bar / d<span style="vertical-align: sub">2</span><br />
</code><br />
where <em>R-bar</em> is the average &#8216;moving range&#8217; of the results, and <em>d<span style="vertical-align: sub">2</span></em> is a constant, depending on the size of the data range chosen.  Many process control statistics books will publish a chart of d2 constants, in a table from range sizes (I like to say &#8220;bucket sizes&#8221;)  from 2 to 20.</p>
<p>So, for example, let&#8217;s say you have a sample of 20 sandwiches made in your sandwich machine, and you have all the lengths measured.  It&#8217;s important that you get these measures in the order of the sandwiches made.  To compute the moving range, break your 20 measures up into buckets of a fixed size; for example, if your bucket size were 10, you&#8217;d just have 2 buckets of data: the first 10 results, then the next 10 results; with a bucket size of 5, you&#8217;ll have 4 buckets, etc. The <em>moving range</em> is just the difference between the highest and lowest values in that bucket.  <em>R-bar</em> is the average of all your bucket&#8217;s &#8220;moving ranges&#8221;.  Divide that average by the <em>d2 </em>constant, and you have<em> sigma hat</em>.</p>
<p>Easy on paper &#8211; a wee bit of a challenge in SQL.  A single SELECT statement just won&#8217;t cut it. Since this involves looking at data in sequence, I had to violate my normal SQL-programming rule: &#8220;CURSORs considered Evil&#8221;.  This is a perfect example for the proper use of cursors (I&#8217;ll rant about the misuse of cursors later).</p>
<p>So, here&#8217;s how I did it.  First, I needed a stored procedure to compute sigma hat <em>(the code here is using Microsoft SQL Server; exact code may be a bit different in other SQL dialects)</em>.</p>
<p><code></code></p>
<pre>
<code>
CREATE PROCEDURE calculateSigmaHat
@testname varchar(50),
  @bucketsize tinyint
AS
BEGIN
  DECLARE
    @result as decimal(18,6),
    @range as decimal(18,6),
    @count as integer,
    @rangebucket as decimal(18,6),
    @bucketcount as integer,
    @sigmahat as decimal(18,6)  CREATE table #bucket (result decimal(18,6))
DECLARE Sigmarator cursor local for
  SELECT result
    from testresults
    where testname = @testname
    order by testdatetime
OPEN Sigmarator
FETCH next from Sigmarator
    into @result
SELECT @bucketcount = 1
SELECT @count = 0
SELECT @rangebucket = 0
WHILE @@fetch_status = 0
  BEGIN
    INSERT into #bucket values(@result)
    IF @bucketcount = @bucketsize
    BEGIN
      SELECT @range = MAX(result)-MIN(result)
        from #bucket
      SELECT @count = @count + 1
      SELECT @rangebucket = @rangebucket + @range
      SELECT @bucketcount = 0 --reset for the next group
      TRUNCATE TABLE #subgroup
    END
FETCH next from Sigmarator
      into @result
    SELECT @bucketcount = @bucketcount + 1
  END
  CLOSE Sigmarator
  SELECT  @sigmahat =
     CASE WHEN @count = 0 THEN 0
              ELSE (@rangebucket/@count) / d2
     END
    from statchart
    where n = @subgroupsize
  DROP table #bucket
  INSERT INTO #sigmahatresult VALUES(@sigmahat)
END</code></pre>
<p>This assumes that test results are in a table called <strong>testresults</strong>, with 3 columns: <strong>testname</strong>, <strong>testdatetime</strong>, and <strong>result</strong>. You&#8217;ll also need another table called <strong>statchart</strong>, with 2 columns, <strong>n</strong> and <strong>d2</strong>.  This table should be prefilled with the d2 constants:</p>
<table title="d2 chart">
<tr>
<th>n</th>
<th>d2</th>
</tr>
<tr>
<td>2</td>
<td>1.128</td>
</tr>
<tr>
<td>3</td>
<td>1.693</td>
</tr>
<tr>
<td>4</td>
<td>2.059</td>
</tr>
<tr>
<td>5</td>
<td>2.326</td>
</tr>
<tr>
<td><em>etc.</em></td>
</tr>
</table>
<p>Since this stored procedure uses a temp table, I couldn&#8217;t program this as a Function.  Thus, I had to resort to passing the result of this stored procedure via a temporary table, <strong>sigmahatresult</strong>   (note: I won&#8217;t vouch for this procedure being thread-safe.  I&#8217;ll let that be an exercise for the reader).</p>
<p>What&#8217;s the appropriate bucket size to use?  I don&#8217;t know: I think that requires some experimentation, or the specific factory process may dictate an appropriate bucket size.  My client used 2, so that&#8217;s what I went with; this stored procedure, though, works with any bucket size desired (<em>caveat</em>: I haven&#8217;t fully tested this code for certain limit conditions)</p>
<p><strong>CalculateSigmahat</strong> and <strong>sigmahatresult</strong> is used within the following stored procedure:</p>
<pre>
<code>
CREATE PROCEDURE calculateCpk</code></pre>
<pre><code>  @testname
  @bucketsize tinyint
AS
BEGIN
   declare @test varchar(50),
           @sigmahat decimal(18,6)

     CREATE TABLE #sigmahatresult (result decimal(18,6))
     DELETE FROM cpkresults
     EXEC calculateSigmaHat @testname,@bucketsize
     SELECT @sigmahat = result
        from #sigmahatresult

     TRUNCATE TABLE #sigmahatresult
     INSERT INTO CpkResults (testname,cpk,ppk)
            SELECT @plant,@grade,@test,
                 CASE WHEN (upper - avg(result)) / (3 * @sigmahat) &lt;  (avg(result) - lower) / (3 * @sigmahat)
                 THEN (upper - avg(result)) / (3 * @sigmahat)
                 ELSE (avg(result) - lower) / (3 * @sigmahat) END as 'cpk',
                 CASE WHEN (upper - avg(result)) / (3 * stdev(result)) &lt; (avg(result) - lower) / (3 * stdev(result))
                 THEN (upper - avg(result)) / (3 * stdev(result))
                 ELSE (avg(result) - lower) / (3 * stdev(result)) END as 'ppk'

             FROM testresults r
             JOIN testlimits l
               on r.testname = l.testname
            WHERE testname = @testname
              and @sigmahat != 0
            GROUP by upper,lower

       DROP TABLE #sigmahatresult

       SELECT r.testname,
              avg(cpk) as 'avgCpk',sum(cCount) as 'cCount'
       from CpkResults r

END
</code></pre>
<p>This depends on one more table, <strong>testlimits</strong>, with 3 columns, testname, upper, and lower, which stores the upper and lower control specifications for the given test.  There&#8217;s also a prexisting ckpresults table.  Again, the way I developed this is probably not thread-safe, but should give readers enough inspiration to develop their own sigmahat and cpk calculations with their specific database design.</p>
<p>So, here you go, the computation of Cpk in SQL, in less than 50 lines of code.  Considering the predominance of SQL and relational databases in corporations, I hope the reader will find this a handy solution to their problem if they&#8217;re ever involved in calculating six sigma statistics like the ever-popular Cpk.  Wear your quality belt proudly <img src='http://www.adhocalley.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=35</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Computing Cpk statistics using SQL</title>
		<link>http://www.adhocalley.com/?p=34</link>
		<comments>http://www.adhocalley.com/?p=34#comments</comments>
		<pubDate>Fri, 04 Jul 2008 05:06:54 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=34</guid>
		<description><![CDATA[Part 1 &#8211; Introduction For the past several years I have performed a myriad of projects for this favorite chemicals company client of mine.  Recently, I was called in to help design and develop a Production Reporting application for them, to meet new requirements from their new, German-based, owners.  The application reports on things like [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Part 1 &#8211; Introduction </strong></p>
<p>For the past several years I have performed a myriad of projects for this favorite chemicals company client of mine.  Recently, I was called in to help design and develop a Production Reporting application for them, to meet new requirements from their new, German-based, owners.  The application reports on things like how much product is produced, what was consumed to produce it, production yields, etc.  Several factories are involved, so we&#8217;re tieing all the data into one database.</p>
<p>The first challenge involved converting all the English-based measurements into metric.  Yes, I did say it was one of those metric-loving European countries, right?  So, we&#8217;ve been going over different conversion equations &#8211; some of them are interesting, because they&#8217;ve involved variable factors like the energy content of natural gas and the specific gravity of  oil.</p>
<p>Still, though, a piece of cake &#8211; just linear equations to convert from one unit of measure to another.  Had more problems with the quality of data (often missing from several plants) than the equations themselves.  So, we&#8217;re progressing fine on the application; then, one day I&#8217;m in a meeting with all the plant managers, and they start talking about CPK<span style="vertical-align: sub"></span> statistics. They talked like of course everyone knows what this statistic is.  I&#8217;m sitting there, though, going &#8220;huh?&#8221;  I have a computer science undergraduate degree, with oodles of calculus, differential equations and statistics, and a economics graduate degree with its own heavy mathematical load in correlation analysis and statistics.  Yet, I&#8217;ve never heard of C<span style="vertical-align: sub">pk</span> (<em>properly, that&#8217;s how the statisticians spell it, C sub pk.  I still don&#8217;t know what the initials mean</em>).</p>
<p><span id="more-34"></span> Never one to feel stupid in front of a client, I finally felt free to ask, &#8220;what is Cpk?&#8221; They knew me well enough to know I wasn&#8217;t really stupid.  &#8220;It&#8217;s one of the <em>six sigma</em> statistics; it measures the variability of a process.&#8221;  Oh, I&#8217;m thinking &#8230; Deming.  Yep, I used to work for a TQM (Total Quality Management) consulting company, so I&#8217;m quite familiar with Deming, kaizan, and such.  Still, with all that knowledge, hadn&#8217;t heard of C<span style="vertical-align: sub">pk</span> &#8211; but knowing it was related to variability, I was set on the right track.</p>
<p>I started googling for the equation used to compute C<span style="vertical-align: sub">pk</span>, and was surprised to find so many different answers!  It started making me think this must be some sort of pseudo-statistic &#8211; it hasn&#8217;t passed muster with real statisticians yet, with some sort of theorem proving it&#8217;s signifance or some such.</p>
<p>The problem became even worse when I started examining the client&#8217;s software that was already computing Cpk from all the lab data.  One was Javascript-code, built into a specialized document management application.  The other was just some spreadsheet equations.  Both used a different algorithm.  That, plus all the different equations floating around on the &#8216;Net had me really puzzled!</p>
<p>Turns out it appears both the Javascript code and the spreadsheets were using just approximations of C<span style="vertical-align: sub">pk</span>.  I finally tripped across a good &#8220;Six Sigma&#8221; book that gave me a concise equation and explanation of what&#8217;s going on.  The confusion involves whether you&#8217;re talking about C<span style="vertical-align: sub">pk</span>, C<span style="vertical-align: sub">p</span>, P<span style="vertical-align: sub">pk</span>, standard deviation (sigma), or estimated standard deviation (sigma hat), etc.  Ok, my head was ready to hurt &#8211; beyond all my years of math education, I hadn&#8217;t done much beyond basic accounting &#8211; i.e., addition and subtraction &#8211;  all these years in the business world.  Now, I was back in real statistics.</p>
<p><em>Next Chapter:</em>  <strong><a href="http://www.adhocalley.com/?p=35" title="part 2">Will the Real Cpk Please Stand Up &#8230; and &#8230; How to Cpk the SQL Way</a>.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=34</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cultural Recreation</title>
		<link>http://www.adhocalley.com/?p=33</link>
		<comments>http://www.adhocalley.com/?p=33#comments</comments>
		<pubDate>Thu, 17 Apr 2008 23:42:09 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Houston]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=33</guid>
		<description><![CDATA[The Houston International Festival has for a long time been one of our favorite family events to attend. Even before we had kids it was a great weekend of fun, food, and music. We&#8217;ve attended most every year that we&#8217;ve lived here in Houston. We even slugged it through the years it was held at [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.ifest.org" title="iFest">Houston International Festival</a> has for a long time been one of our favorite family events to attend.  Even before we had kids it was a great weekend of fun, food, and music.  We&#8217;ve attended most every year that we&#8217;ve lived here in Houston.  We even slugged it through the years it was held at Reliant Park.  Vast parking lots have absolutely no character, so we were very happy when it moved back to downtown!</p>
<p>2005 was an especially good year for iFest &#8211; that was the year we participated as a vendor!  Connie and Alyson started planning their business venture, Té House of Tea, in 2004, and by January 2005 started searching for a suitable location for the tea house.  This took longer than expected &#8211; so many locations just didn&#8217;t have the right amount of parking, the right rent, or just the right feel for a peaceful, contemporary tea house.  Then we noticed the featured country for iFest this was was India, and since Connie had developed an authentic Indian chai recipe (with the help of our dear friend Hema), we decided to throw up a booth at the festival.</p>
<p>Luckily, we got a booth in the <strong>India Food Court.</strong></p>
<p>These were the early days of our business planning, and we didn&#8217;t have a lot of extra cash for extracurricular adventures, so we made do with hand-painted signs and  logos.  We were very proud, though, of the final result for our sign, which was pitched above our booth.  I hand cut some graceful, Indian architecture-like curves with my trustworthy jigsaw, and Alyson and Hema laid on the paint and paisley patterns.  It was gorgeous!</p>
<p>We only had enough time and energy for one weekend, so a boba-tea shop took our booth location the  weekend.  The weekend we set up was sunny and humid.  The crowds were still there, though, and our teas were an instant hit &#8211; especially with all the Indian-Americans!   All the neighboring Indian restaurants were pitching our chai to their customers, as &#8220;fresh and authentic&#8221;.  Come 5 pm, and suddenly the Indian crowd was in line eight-deep at our booth &#8211; Tea Time! It may have been a hot day, but they still wanted hot chai &#8211; it&#8217;s only right.</p>
<p>We completely ran out of all that we had prepared in the morning, so Alyson and Connie stayed in the back to boil some fresh brew.  Mmmm, it was good, the aroma of boiling milk, black tea, and fresh spices filling the air around our little tent.</p>
<p>We completely ran out of our two days worth of tea supplies in just one day, so on Saturday midnight I was at Fiesta buying fresh spices &#8211; cardamon, cloves, ginger, etc. &#8211; so we could be prepared for the Sunday crowds.</p>
<p>Sunday was just as busy for us, but we are able to keep ahead of demand this time. 5 pm was still a rush, and we were ready.</p>
<p>We were very proud of our success, and our acceptance by the local Indian community.  We had <em>recreated</em> a bit of their own culture in the form of local food and afternoon tea traditions, and it fit the general atmosphere of Indian dance and music all around us.</p>
<p>Last weekend, I had the honor of being invited by iFest for a sneak peek of one of their own<em> cultural recreations</em>:  a model of a 13th century underground church in Ethiopia.  This in preparation for the coming International Festival&#8217;s focus on <strong>Africa</strong>.</p>
<p>I visited iFest art director&#8217;s  Kati Ozanic-Lemberger home and studio on a recent Saturday, along with a lot of other excited bloggers.  We got a see a bit of cultural recreation in action: the construction of the underground caves leading to the church (the church itself had already been carted away).  With paint and plaster, Kati and team are bringing a touch of this exotic African history right here to Houston, for visitors to see and touch.</p>
<p>It&#8217;s not the real thing, but that&#8217;s not the purpose.  Visitors get to see and read a bit about something they probably knew very little about before, learn a little history, and ponder.    That is, by crawling in a cave, they&#8217;ll get to leave their own little cave.  And that&#8217;s good.</p>
<p>Should be a good two weekends: everyone get out and enjoy iFest this year!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=33</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pseudoscience vs. Science</title>
		<link>http://www.adhocalley.com/?p=32</link>
		<comments>http://www.adhocalley.com/?p=32#comments</comments>
		<pubDate>Thu, 27 Mar 2008 18:39:03 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=32</guid>
		<description><![CDATA[Boiled down: Science = testable hypotheses Pseudoscience = exploiting anomalies in Science I had the misfortune of running into a 9-11 Truther last week, on a bridge in Houston. I was gracious enough to accept 4 DVDs from him, and was open minded enough to even start viewing one of these videos (along with my [...]]]></description>
			<content:encoded><![CDATA[<p>Boiled down:</p>
<ul>
<li>Science = testable hypotheses</li>
<li>Pseudoscience = exploiting anomalies in Science</li>
</ul>
<p>I had the misfortune of running into a 9-11 Truther last week, on a bridge in Houston.  I was gracious enough to accept 4 DVDs from him, and was open minded enough to even start viewing one of these videos (along with my son, who&#8217;s getting old enough now to actual be curious about politics).  30 minutes in, though, I just had to shout out &#8220;Arghh!&#8221; and throw my hands up.  These guys don&#8217;t engage in science, or even scientific dialogue.  If you chance to argue with them, to point out alternative, feasible, Occam&#8217;s Razor-limited hypotheses, along with the supporting evidence &#8211; or even dare to point out the anomalies in their own data and theories &#8211; then you&#8217;ll be immediately branded as a apologist, a shill for the State, or worse.</p>
<p>I mean, heck, I&#8217;m like any other guy: I like good conspiracy theories. It&#8217;s great entertainment!  And yeah, perhaps &#8220;we&#8221; have planted evidence or created events as excuses for going into wars before (USS Maine, anyone?).  But Controlled Demolition, Missiles, Remote-Controlled Planes, Holographic Plane Images, even UFOs?   This isn&#8217;t science, falls flat on so many fronts.   I&#8217;ve got better things to do than read up or view all this.   And, better things to blog about.  So, I&#8217;m off &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=32</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Social Media Drinking Game</title>
		<link>http://www.adhocalley.com/?p=31</link>
		<comments>http://www.adhocalley.com/?p=31#comments</comments>
		<pubDate>Wed, 19 Mar 2008 19:07:18 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=31</guid>
		<description><![CDATA[Here&#8217;s my random thought of the day: After reading this article: The web, the politician and the prostitute, I was inspired to imagine the following game: Get with a few of your friends at your favorite bar. One with wireless access; Start drinking; When everyone&#8217;s getting good and happy, pull out your special deck of [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s my random thought of the day:</p>
<p>After reading this article: <a href="http://news.bbc.co.uk/2/hi/technology/7302968.stm" title="BBC news article"> 					The web, the politician and the prostitute</a>, I was inspired to imagine the following game:</p>
<ol>
<li>Get with a few of your friends at your favorite bar.  One with wireless access;</li>
<li>Start drinking;</li>
<li>When everyone&#8217;s getting good and happy, pull out your special deck of cards.  You&#8217;ll be the first player, the Prosecutor;</li>
<li>The Prosecutor points out one person in the group.  He/she is the Accused (got to come up with cuter names, though);</li>
<li>The Prosecutor draws a random card from the deck.  These cards have a single crime written on them, stuff like Murder, Rape, Child Molester, Embezzlement, Prostitution, etc.  The more heinous, the better;</li>
<li>He shouts, &#8220;YOU NOW STAND ACCUSED OF _______ !&#8221;;</li>
<li>Everyone else in the group is a Journalist.  It is now their job to mine the accused&#8217;s social networks for all the juicy bits they can find: incriminating photos, random quotes etc.  The more they support the crime the better;  the most outlandish out-of-context statements that prove the accused&#8217;s proclivities gets the most points.  Digging into obscure connections and long-past history (archive.org is allowed) gets even more points;</li>
<li>Be prepared for a lot of teasing.</li>
</ol>
<p>This game is good for <em>sobering up</em> before you head home for the weekend.  It&#8217;s sobering to see how much privacy we&#8217;re willing to give up these days.  <img src='http://www.adhocalley.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=31</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bridges and Phones &#8211; Social Media Economics</title>
		<link>http://www.adhocalley.com/?p=30</link>
		<comments>http://www.adhocalley.com/?p=30#comments</comments>
		<pubDate>Tue, 18 Mar 2008 17:46:54 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Opinion]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=30</guid>
		<description><![CDATA[In microeconomics, economists like to talk about substitution goods and complementary goods. A classic complementary good to peanut butter is jelly: both are usually consumed together in that delectable sandwich known as PB &#38; J. Economists care about this, because when consumption goes up in peanut butter, you&#8217;ll likely see an increase in jelly too, [...]]]></description>
			<content:encoded><![CDATA[<p>In microeconomics, economists like to talk about <em>substitution</em> goods and <em>complementary</em> goods.  A classic complementary good to peanut butter is jelly: both are usually consumed together in that delectable sandwich known as PB &amp; J.  Economists care about this, because when consumption goes up in peanut butter, you&#8217;ll likely see an increase in jelly too, if the goods are tightly complementary.  Price changes in one will likely lead to price changes in the other.</p>
<p>A substitute good, well that&#8217;s kind of obvious, it&#8217;s a good that can easily substitute for another.  Soy drink is a substitute for milk &#8211; at least, if you&#8217;re in my household.  Natural gas is a substitute for electricity, when heating your house.  If the substitute is easy to switch, a price increase in one will lead to increased demand in another &#8211; a nice, easy economics predictive tool.<span id="more-30"></span></p>
<p>Early 20th century economists watching the rise of new technologies took an increasing interest in communications technologies, and tried to predict their impact.  Communications and transportation, they observed, are substitute goods, so increased use of communications, such as telegraphs or the newfangled phone, would lead to decreased use of transportation.  Since you can now call the store with a question, you don&#8217;t need to visit them as often.  With telecommuting and video conferencing, business travel will decrease as offices run more efficiently with new communications options.</p>
<p>However, the predictability of this substitution effect has often been way off, and it&#8217;s for a simple reason: <em>ceteris paribus</em>.  Everything else has to remain the same in order for predictions about increased supply of substitute goods to be accurate.  What&#8217;s missing is the <em>increased consumer options</em> that these new goods may supply.  Technological innovation has often been seen as an entrepreneurial/producer function, but consumers can also innovate, in how they consume/use new technologies.  This often leads to very unpredictable results.</p>
<p>I wish I could find this article, but it&#8217;s lost somewhere in my files (created in pre-browser bookmark days).  The article was about a study on the impact of a new bridge being built, back at the beginning of the 20th century.  I think it may have been Brooklyn, but I&#8217;m not sure &#8211; maybe it was a section of London instead.  Well, when the bridge opened, some economists predicted that telephone use would go down between the two connecting boroughs, as there&#8217;d be less need to call family and businesses across the river (mind you, not everyone had a phone, and it was a rare and expensive endeavor to have or use a phone then). Instead, telephone use went up &#8211; dramatically.  People made new friends, new business connections, and new uses for their increased connectivity, and demanded more phones to keep these connections going.</p>
<p>The USPS has for long been concerned about email, and how it&#8217;s cutting into their business.  Certainly email is a great substitute for regular postal mail: why have to haul a piece a paper around the country just to get a message across?  And indeed, first class mail volume has dropped in the U.S. over the last 20 years.  But, look what the web in general has done for the postal service:  Ebay, Netflix, Blurb &#8230; they have all greatly increased demand for shipping services, keeping the USPS (and competitors) very busy.</p>
<p>&#8220;Cyperspace&#8221; has introduced us to a nation of online users, many spending hours of every day online, stuck in front of a computer.  &#8220;Everyone&#8217;s becoming anti-social&#8221; has been a popular concern.  There&#8217;s been some interesting counter trends though.  Back in the early 1990s, I was part of a study of chat room use in AOL.  It was eyebrow raising: people were spending several hours every day inside these chat rooms, talking about &#8230; whatever.  However, here was something surprising: these chat room groups started organizing real parties, where they could meet face to face with their new online friends.  &#8216;Cept,  the friendship base was now nationwide, so the parties were organized some place central and easy to access, like Atlanta, and everyone would fly in for a weekend of meeting and partying.  Talk about increasing transportation demand!</p>
<p>You might be a stranger to your own neighbor, but know 100 people across the nation most intimately.  You might not share a table with a  stranger at a restaurant, but you&#8217;ll twitter your newfound online friends to come join you.  These tendencies may be due to part to something I&#8217;ll call &#8220;<em>the oppressiveness of neighbors</em>&#8220;, of which I need to expand up later.  In any case, &#8220;social media&#8221; will continue to throw economists for a loop when trying to predict consumption changes due to increased use of the Web.  Mashups and other <em>consumer innovations</em> will continue to surprise us and our predictions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=30</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>First thoughts on presentation at HTC</title>
		<link>http://www.adhocalley.com/?p=29</link>
		<comments>http://www.adhocalley.com/?p=29#comments</comments>
		<pubDate>Fri, 14 Mar 2008 16:06:05 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Houston]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=29</guid>
		<description><![CDATA[This Wednesday I did a short presentation at the Houston Technology Center&#8217;s &#8220;Starting a Web-Based Business&#8221; lunch series.  My presentation was on &#8220;Open Source Tools for Software Development&#8221;, and I highlighted several tools that my development team uses regularly. I&#8217;ll post that presentation shortly, but here I just wanted to jot down a few notes [...]]]></description>
			<content:encoded><![CDATA[<p>This Wednesday I did a short presentation at the Houston Technology Center&#8217;s &#8220;Starting a Web-Based Business&#8221; lunch series.  My presentation was on &#8220;Open Source Tools for Software Development&#8221;, and I highlighted several tools that my development team uses regularly.</p>
<p>I&#8217;ll post that presentation shortly, but here I just wanted to jot down a few notes from reactions to the presentation &#8211; feedback I got after the talk.</p>
<ul>
<li> One manager, owner of a well-established software firm here in Houston, liked the idea of wikis for organizing his team; but he&#8217;s still looking for a better project management tool, something &#8220;larger&#8221; than Poi, the issue-tracker I demonstrated.  Something that could track milestones, and keep the team on track.
<p>Yes, I&#8217;d like to see better tools for PM too.  Traditionally, we&#8217;ve used MS Project.  Problem is, it&#8217;s not easy to share &#8211; at Interliant, we tried the Lotus Notes-based <a href="http://www.marinres.com/pg.html" title="Project Gateway">Project Gateway</a>, but ultimately found it awkward to use.  <a href="http://www.basecamphq.com/" title="Basecamp">Basecamp</a>, an online service, looks attractive &#8211; not sure yet how well it scales, and compels your team to use it.</p>
<p>One thing we do, though, when a project gets hot and heavy, is that we fix the milestone dates at regular intervals: once a week or once every two weeks there&#8217;s going to be a build.  That stays fixed; what adjusts, though, are which features that make it into the build.  Our only rule is that the feature must be a tangible end-user benefit &#8211; we can&#8217;t &#8220;deliver&#8221; just background architecture or design in the next release, and expect that to be considered progress by our client.  Managing at this point becomes simpler, as the project schedule just shows a set of period milestones; ts in the status meetings we discuss which features will make it into the next build &#8211; the customer, of course, sets priorities, and there&#8217;s some give-and-take on features that may slip because of their complexity, or unexpected problems.</p>
<p>Still need a tool, though, to capture and display these milestones and feature deliverables!  Must search more &#8230;</li>
<li>One manager of IT at the Houston Chronicle mentioned they use <a href="http://www.capify.org/" title="Capify">Capistrano</a> for deployment, instead of Ant.  It&#8217;s Ruby-based, but you can use it for automating all sorts of things.  It looks very promising, so I&#8217;ll have to check it out.  Ant is cool, is built into Eclipse, and does the job, but it&#8217;s XML.  Rather a yicky way to write out deployment scripts!</li>
<li>Another fellow approached me after the talk and said his friend is involved in a large-scale application that uses, of all things, Smalltalk!  It does heuristics, and I think it was oil field-related.  I&#8217;m hoping I&#8217;ll get to meet this guy, and learn more.  I still love Smalltalk &#8230; just can&#8217;t find any projects where it&#8217;s a winner here in town  <img src='http://www.adhocalley.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=29</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cultural Awareness</title>
		<link>http://www.adhocalley.com/?p=27</link>
		<comments>http://www.adhocalley.com/?p=27#comments</comments>
		<pubDate>Tue, 05 Feb 2008 19:28:00 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Houston]]></category>
		<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=27</guid>
		<description><![CDATA[OK, I guess I won&#8217;t really fault the local tech community for sponsoring not one, but TWO events, both falling on the first day of Chinese New Years. Did anyone check their calendars?! Yeah, yeah, I know &#8230; you can&#8217;t pick any date without landing on some sort of holiday, be it National Pickle Day [...]]]></description>
			<content:encoded><![CDATA[<p>OK, I guess I won&#8217;t really fault the local tech community for sponsoring not one, but TWO events, both falling on the first day of Chinese New Years.  Did anyone check their calendars?!  Yeah, yeah, I know &#8230; you can&#8217;t pick any date without landing on some sort of holiday, be it National Pickle Day or International I-Miss-My-Mommy Month.  But, this one day is perhaps a bit more important than others &#8211; it&#8217;s at least a day where you can expect a lot of family commitments if you happen to be Asian.</p>
<p>So, I&#8217;ll be missing the <a href="http://www.theupexperience.com/" title="The Up Experience">Up Experience</a>, though I&#8217;ll likely make it for a short while to the <a href="http://entrepreneur.meetup.com/1578/calendar/7025677/" title="Houston Startup">Houston Startup Happy Hour</a> &#8211; the latter is always a great chance to catch up with my business friends, in our often very busy schedules.  After that though, it&#8217;s off to a grand ballroom for a big New Years feast with other friends and family.  I think we have booked 3 large tables so far.  Should be fun, and filling too!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=27</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Objective Journalism is a Myth</title>
		<link>http://www.adhocalley.com/?p=26</link>
		<comments>http://www.adhocalley.com/?p=26#comments</comments>
		<pubDate>Tue, 29 Jan 2008 22:09:18 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://www.adhocalley.com/?p=26</guid>
		<description><![CDATA[Forget what you were taught in school about journalistic ethics. There is no objectivity in the news. Journalists, editors and news corporations come to every story with their biases intact, and select and produce stories that reflect their leanings. OK &#8230; actually, the situation is more subtle and complex than that. I&#8217;m not talking about [...]]]></description>
			<content:encoded><![CDATA[<p>Forget what you were taught in school about journalistic ethics.  <strong>There is no objectivity in the news</strong>. Journalists, editors and news corporations come to every story with their biases intact, and select and produce stories that reflect their leanings.</p>
<p>OK &#8230; actually, the situation is more subtle and complex than that.  I&#8217;m not talking about the left-leaning media, or the &#8220;vast right-wing conspiracy&#8221;.  Sometimes the biases are more mundane than that: news stations, to keep their ratings up, must produce entertainment in their news, to keep the viewers watching.  And, we all know how this works: shock and gore, gossip and controversy are all grist in the entertainment mill, so stories with shock value will more likely get air time.  And, a journalist who can throw in a controversial twist will get more attention from the editors, etc., increasing chances an article will be run.</p>
<p>This &#8220;entertainment influence&#8221; on journalism seems to be more a factor of TV news than print.</p>
<p>Maybe journalists like to hide behind the cloak of objectivity, but we as savvy consumers of news information need to weigh in on all the influences &#8211; economic as well as ideological &#8212; <span id="more-26"></span>that drive a journalist and the whole news production process.  Especially if you&#8217;re on the subject end of a journalist, you need to be aware.  Of course, once you&#8217;re aware of journalism bias and such, and know that the real reason that journalist is interviewing you is to get a good story instead of uncovering &#8220;the truth&#8221;, you can use this to your advantage.</p>
<p><strong>I&#8217;ve been on the receiving end of a news story more than once</strong>, and I was very aware that of the 10+ minutes of verbiage I was speaking into the camera, likely just 30 seconds of sound bite would make it on air.  And that 30 second sampling may not be very flattering.   In my case, though, I knew the journalist was sympathetic to my cause (it helps to have a nice dialogue with her before the interview), and everything worked out well.  The 30 second sound bite she took from my rival (so to speak) was not so flattering &#8230; and I knew that was very intentionally so.  Re-read sentence 2 of this entry.</p>
<p>I bring this up because I was watching the news this evening. A very rare event for me.  I was watching because a friend emailed, and said &#8220;watch Channel 2&#8243;, because they were going to run a Ron Paul story.  I&#8217;ve been interested in Ron Paul&#8217;s campaign as he&#8217;s the only anti-war candidate from either major party to run. Anyway, what did I catch on this news story: one nice juicy tidbit of a sound bite: &#8220;Ron Paul tends to attract radical voters, like the KKK in Florida and prostitutes in Nevada&#8221;.</p>
<p>Holy cow, what a hack job!!  I guess the prostitute vote is what pushed Paul up to 2nd place in Nevada, right?! This particular sound bite was totally uncalled for, and clearly was intended to discredit Paul &#8211; I mean, you&#8217;re digging at the bottom of the slime barrel whenever the KKK is involved (I once knew a guy that tried to use a KKK affiliation to libel a fellow employee; it got an immediate and vile reaction from everyone involved &#8230; but that&#8217;s a different story); the quote was from an HBU political science professor, and I&#8217;m sure they had another 10 minutes or more of him on tape, so plenty of other quotes could have been used instead</p>
<p>Now, if Paul would alter his positions on abortion and immigration a bit &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocalley.com/?feed=rss2&#038;p=26</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

