<?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>O&#039;Reilly Radar &#187; Jon Udell</title>
	<atom:link href="http://radar.oreilly.com/jonu/feed" rel="self" type="application/rss+xml" />
	<link>http://radar.oreilly.com</link>
	<description>Insight, analysis, and research about emerging technologies</description>
	<lastBuildDate>Tue, 21 May 2013 12:00:03 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Visualizing structural change</title>
		<link>http://radar.oreilly.com/2011/07/structural-change-json-elmcity.html</link>
		<comments>http://radar.oreilly.com/2011/07/structural-change-json-elmcity.html#comments</comments>
		<pubDate>Thu, 28 Jul 2011 20:30:00 +0000</pubDate>
		<dc:creator>Jon Udell</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[@home]]></category>
		<category><![CDATA[elmcity]]></category>
		<category><![CDATA[information]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[records]]></category>

		<guid isPermaLink="false">http://blogs.oreilly.com/radar/2011/07/structural-change-json-elmcity.html</guid>
		<description><![CDATA[Think about the records that describe the status of your health, finances, insurance policies, vehicles, and computers. If the systems that manage these records could produce timestamped JSON snapshots when indicators change, it would be much easier to find out what changed, and when.
 ]]></description>
				<content:encoded><![CDATA[<p>
My <a href="http://radar.oreilly.com/tag/elmcity">ongoing series</a> about <a href="http://elmcity.cloudapp.net">the elmcity project</a> has shown a number of ways in which I invite participants to <a href="http://blog.jonudell.net/2011/01/24/seven-ways-to-think-like-the-web/">think like the web</a>. One of the principles I try to illustrate by example is:
</p>
<blockquote>
<p>3. Know the difference between structured and unstructured data</p>
</blockquote>
<p>
Participants learn that calendars on web pages and in PDF files don&#8217;t syndicate around the web, but calendars in the structured iCalendar format do. They also learn a subtler lesson about structured data. Curators of elmcity hubs manage the settings for their hubs, and for their feeds, by tagging Delicious bookmarks using a name=value syntax that enables those bookmarks to work as associative arrays (also known as dictionaries, hashtables, and mappings). For example, here&#8217;s a picture of the bookmark that defines the settings for the Honolulu hub:
</p>
<div align="center">
<p class="image-box-500">
<img src="http://jonudell.net/images/alohavibe_metadata.png" border="0" width="500" /></p>
</div>
<p>The bookmark&#8217;s tags represent these attributes:</p>
<pre>
contact: elmcity@alohavibe.com
facebook: yes
header_image: no
radius: 300
title: Hawaii Events courtesy of AlohaVIBE.com
twitter: alohavibe
tz: hawaiian
where: honolulu,hi
</pre>
<p>
Curators use Delicious to declare these sets of attributes, but the elmcity service doesn&#8217;t always retrieve them from Delicious. Instead it syncs the data to Azure tables and blobs. When it needs to use one of these associative arrays it fetches an XML chunk from an Azure table or a JSON blob from the Azure blob store. Both arguably qualify as NoSQL mechanisms but I prefer to define things according to what they are instead of what they&#8217;re not. To me these are just ways to store and retrieve associative arrays.
</p>
<h2>Visualizing change history for elmcity metadata</h2>
<p>
Recently I&#8217;ve added a feature that enables curators to review the changes they&#8217;ve made to the metadata for their hubs and feeds. The other day, for example, I made two changes to the Keene hub&#8217;s registry. I added a new feed, and I added a tag to an existing feed. You can see both changes highlighted in green on this <a href="http://elmcity.cloudapp.net/services/elmcity/meta_history?id=elmcity&amp;flavor=feeds&amp;a_name=elmcity.2011.07.25.00.59.feeds.json&amp;b_name=elmcity.2011.07.25.11.09.feeds.json">change history page</a>. A few hours later I renamed the tag I&#8217;d added. That change shows up in yellow <a href="http://elmcity.cloudapp.net/services/elmcity/meta_history?id=elmcity&amp;flavor=feeds&amp;a_name=elmcity.2011.07.25.11.09.feeds.json&amp;b_name=elmcity.2011.07.26.16.28.feeds.json">here</a>. On the following day I deleted three obsolete feeds. That change shows up in yellow <a href="http://elmcity.cloudapp.net/services/elmcity/meta_history?id=elmcity&amp;flavor=metadata&amp;a_name=elmcity.2011.07.26.16.28.metadata.json&amp;b_name=elmcity.2011.07.26.17.38.metadata.json">here</a> and in red <a href="http://elmcity.cloudapp.net/services/elmcity/meta_history?id=elmcity&amp;flavor=feeds&amp;a_name=elmcity.2011.07.26.16.28.feeds.json&amp;b_name=elmcity.2011.07.26.17.38.feeds.json">here</a>.</p>
<p>
These look a lot like Wikipedia change histories, or the &#8220;diffs&#8221; that programmers use to compare versions of source files. But Wikipedia histories and version control diffs compare unstructured texts. When you change structured data you can, at least in theory, visualize your changes in more focused ways.
</p>
<p>
One of the great ironies of software development is that although computer programs are highly structured texts, we treat them just like Wikipedia articles when we compare versions. I&#8217;ve had many discussions about this over the years with my friend <a href="http://third-bit.com/">Greg Wilson</a>, proprietor of the <a href="http://software-carpentry.org/">Software Carpentry</a> project. We&#8217;ve always hoped that mainstream version control systems would become aware of the structure of computer programs. So far we&#8217;ve been disappointed, and I guess I can understand why. Old habits run deep. I am, after all, writing these words in a text editor that emulates emacs.
</p>
<div style="float: left;border-top: thin gray solid;border-bottom: thin gray solid;padding: 20px;margin: 20px 2px"><a href="https://en.oreilly.com/stratany2011/public/regwith/stn11rad?cmp=il-radar-st11-elmcity-udell-structural-change"><img style="float: left;border: none;padding-right: 10px" src="http://s.radar.oreilly.com/strata-ny-stn11rad.png" /></a><a href="https://en.oreilly.com/stratany2011/public/regwith/stn11rad?cmp=il-radar-st11-elmcity-udell-structural-change"><strong>Strata Conference New York 2011</strong></a>, being held Sept. 22-23, covers the latest and best tools and technologies for data science &#8212; from gathering, cleaning, analyzing, and storing data to communicating data intelligence effectively.</p>
<p><a href="https://en.oreilly.com/stratany2011/public/regwith/stn11rad?cmp=il-radar-st11-elmcity-udell-structural-change"><strong>Save 30% on registration with the code STN11RAD</strong></a></div>
<p>
Maybe, though, we can make a fresh start as the web of data emerges. The lingua franca of the data web was going to be XML, now the torch has passed to JSON (JavaScript Object Notation), both are used widely to represent all kinds of data structures whose changes we might want to visualize in structured ways.</p>
<p>
The component at the heart of the elmcity&#8217;s new change visualizer is a sweet little all-in-one-page web app by <a href="http://tlrobinson.net/">Tom Robinson</a>. It&#8217;s called <a href="http://tlrobinson.net/projects/javascript-fun/jsondiff">JSON Diff</a>. To try it out in a simple way, let&#8217;s use this JSON construct:</p>
<pre>
{
  "Evernote" :
   {
   "InstalledOn":"3/19/2008",
   "Version": "3.0.0.539"
   },
  "Ghostery IE Plugin" :
   {
   "InstalledOn":"7/9/2011",
   "Version": "2.5.2.0"
   }
}
</pre>
<p><img src="http://jonudell.net/images/jsondiff-installed-program-changes.png" border="0" width="339" style="float: right;margin: 3px 0 10px 10px" />These are a couple of entries from the Programs and Features applet in my Windows Control Panel. If my system were taking JSON snapshots of those entries whenever they changed, and if I were later to upgrade the Ghostery plugin to (fictitious future version) 2.6.1.0, I could see this JSON Diff report:
</p>
<p>
You can try it yourself at <a href="http://tlrobinson.net/projects/javascript-fun/jsondiff/#{%22d%22%3A{%22a%22%3A%22{u000a%22Evernote%22%3A%20u000a%20{u000a%20%22InstalledOn%22%3A%223%2F19%2F2008%22%2Cu000a%20%22Version%22%3A%20%223.0.0.358%22u000a%20}%2Cu000a%22Ghostery%20IE%20Plugin%22%3Au000a{u000a%20%20%20%22InstalledOn%22%3A%227%2F9%2F2011%22%2Cu000a%20%20%20%22Version%22%3A%20%222.5.2.0%22u000a}u000a}u000a%22%2C%22b%22%3A%22{u000a%22Evernote%22%3A%20u000a%20{u000a%20%22InstalledOn%22%3A%223%2F19%2F2008%22%2Cu000a%20%22Version%22%3A%20%223.0.0.358%22u000a%20}%2Cu000a%22Ghostery%20IE%20Plugin%22%3Au000a{u000a%20%20%20%22InstalledOn%22%3A%227%2F9%2F2011%22%2Cu000a%20%20%20%22Version%22%3A%20%222.5.2.0%22u000a}u000a}%22}}">this JSON Diff URL</a>. Or if you&#8217;re running Internet Explorer, which the original JSON Diff doesn&#8217;t support, you can copy that JSON chunk and paste it into one of the <a href="http://elmcity.cloudapp.net/services/elmcity/meta_history?id=elmcity&amp;flavor=feeds&amp;a_name=elmcity.2011.07.26.16.28.feeds.json&amp;b_name=elmcity.2011.07.26.17.38.feeds.json">earlier examples</a>. The elmcity adaptation of JSON Diff, which uses JQuery to abstract browser differences, does work with IE.
</p>
<p>
It&#8217;s worth noting that the original JSON Diff has the remarkable ability to remember any changes you make by dynamically tweaking its URL. It does so by tacking your JSON fragments onto the end of the URL after the hash symbol (#) as one long fragment identifier! The elmcity version sacrifices that feature in order to avoid running into browser-specific URL-length limits, and because it works with a server-side companion that can feed it data. But it&#8217;s cool to see how a self-contained single-page web app can deliver what is, in effect, a web service.
</p>
<h2>What changed, and when?</h2>
<p>A key question, in many contexts, is: &#8220;What changed, and when?&#8221; In the <a href="http://jonudell.net/udell/gems/umlaut/umlaut.html">Heavy Metal Umlaut screencast</a> I animated the version history of a Wikipedia page. It was a fascinating exercise that sparked <a href="http://waxy.org/2005/06/automating_wiki/">ideas</a> about tools that would automate the process. Those tools haven&#8217;t arrived yet. We could really use them, and not just for Wikipedia. In <a href="http://www.dailykos.com/story/2006/12/12/280327/-Wanted:-Legislative-Version-Control">law</a> and in <a href="http://www.wordyard.com/2010/07/21/politico-slate-and-story-versioning/">journalism</a> the version control discipline practiced by many (but not all!) programmers is tragically unknown. In these and in other fields we should expect at least what Wikipedia provides &#8212; and ideally better ways to visualize textual change histories.
</p>
<p>
But we can also expect more. Think about the records that describe the status of your health, finances, insurance policies, vehicles, and computers. Or the products and personnel of companies you work for or transact with. Or the policies of governments you elect. All these records can be summarized by key status indicators that are conceptually just sets of name/value pairs. If the systems that manage these records could produce timestamped JSON snapshots when indicators change, it would be much easier to find out what changed, and when.
</p>
<p></p>
<p><strong>Related:</strong></p>
<ul>
<li> <a href="http://radar.oreilly.com/tag/elmcity">See all Radar elmcity stories</a></li>
<li> <a href="http://answers.oreilly.com/tag/elmcity">See all Answers elmcity stories</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://radar.oreilly.com/2011/07/structural-change-json-elmcity.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why Facebook isn&apos;t the best home for your public events</title>
		<link>http://radar.oreilly.com/2011/06/facebook-events-syndication.html</link>
		<comments>http://radar.oreilly.com/2011/06/facebook-events-syndication.html#comments</comments>
		<pubDate>Thu, 09 Jun 2011 14:00:00 +0000</pubDate>
		<dc:creator>Jon Udell</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[@home]]></category>
		<category><![CDATA[elmcity]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[syndication]]></category>

		<guid isPermaLink="false">http://blogs.oreilly.com/radar/2011/06/facebook-events-syndication.html</guid>
		<description><![CDATA[Organizations should strive to own and control their
online identities (and associated data) to the extent they can. ]]></description>
				<content:encoded><![CDATA[<p>
In an <a href="http://radar.oreilly.com/2010/11/heds-deks-and-ledes.html">earlier<br />
episode</a> of <a href="http://radar.oreilly.com/tag/elmcity">this series</a> I discussed how Facebook events can flow through <a href="http://elmcity.cloudapp.net">elmcity</a> hubs by way of<br />
Facebook&#8217;s search API. Last week I added another, and more direct,<br />
method. Now you can use a Facebook iCalendar URL (the export<br />
link at the bottom of Facebook&#8217;s Events page) to route your public<br />
events through an elmcity hub.</p>
<p>
The benefit, of course, is convenience. If you&#8217;re promoting a public<br />
community event, Facebook is a great way to get the word out and keep<br />
track of who&#8217;s coming. Ideally you should only have to write down the event<br />
data once. If you can enter the data in Facebook and then syndicate it<br />
elsewhere, that seems like a win.
</p>
<p>
In <a href="http://blog.jonudell.net/2011/06/02/syndicating-facebook-events/">Syndicating<br />
Facebook events</a> I explain how this can work. But I also<br />
suggest that your Facebook account might not be the best<br />
authoritative home for your public event data. Let&#8217;s consider why not.
</p>
<p>
Here&#8217;s a public event that I&#8217;m promoting:
</p>
<div align="center">
<p style="width: 439px;height: auto;padding: 10px;margin: 15px 0 15px 0;border: 1px solid #ddd;font-style: italic;text-align: left" /><img src="http://jonudell.net/images/end-of-world-12-21-12.png" width="400" alt="Facebook public event" /></p>
</div>
<p>
Here&#8217;s how it looks in a rendering of the Keene elmcity hub:
</p>
<div align="center">
<p style="width: 288px;height: auto;padding: 10px;margin: 15px 0 15px 0;border: 1px solid #ddd;font-style: italic;text-align: left" /><img src="http://jonudell.net/images/end-of-world-in-elmcity-hub.png" width="288" alt="Rendering of the Keene elmcity hub" /></p>
</div>
<p>
And here&#8217;s the link to the <em>End of the world (again)</em> event:
</p>
<p>
<a href="https://www.facebook.com/event.php?eid=207438602626457">https://www.facebook.com/event.php?eid=207438602626457</a>
</p>
<p>
Did you click it? If so, one of two things happened. If you were<br />
logged into Facebook you saw the event. If not you saw this:
</p>
<div align="center">
<p style="width: 477px;height: auto;padding: 10px;margin: 15px 0 15px 0;border: 1px solid #ddd;font-style: italic;text-align: left" /><img src="http://jonudell.net/images/facebook-login.png" width="477" alt="Facebook login page" /></p>
</div>
<p>
Is this a public event or not? It depends on what you mean by public.<br />
In this case the event is public within Facebook but not available on the<br />
open web. The restriction is problematic. Elmcity hubs are transparent<br />
conduits, they reveal their sources, curators do their work out in the<br />
open, and communities served by elmcity hubs can see how those hubs<br />
are constituted. Quasi-public URLs like this one  aren&#8217;t in the spirit<br />
of the project.
</p>
<p>
My end-of-the-world event is obviously an illustrative joke. But<br />
consider two other organizations whose events appear in that elmcity<br />
screenshot: the Gilsum Church and the City of Keene. These<br />
organizations are currently using Google Calendar to manage their<br />
public events. They use Google Calendar&#8217;s widget to display events on<br />
their websites, and they route Google Calendar&#8217;s iCalendar feeds<br />
through the elmcity hub.
</p>
<p>
Now that elmcity can receive iCalendar feeds from Facebook, the church<br />
and the city could use their Facebook accounts, instead of Google<br />
Calendar, to manage their public events. Should they? I think not.<br />
Public information should be really public, not just quasi-public.
</p>
<p>
What&#8217;s more, organizations should strive to own and control their<br />
online identities (and associated data) to the extent they can. From<br />
that perspective, using services like Google Calendar or Hotmail<br />
Calendar are also problematic. But you have choices.<br />
While it&#8217;s convenient to use the free services of Google Calendar or<br />
Hotmail Calendar, and I recommend both, I regard them as training<br />
wheels. An organization that cares about owning its identity and data,<br />
as all ultimately should, can use any standard calendar system to<br />
publish a feed to a URL served by a host that it pays and trusts,<br />
using an Internet domain name that it paid for and owns.
</p>
<p>
Either way, how could an organization manage its public event stream<br />
using standard calendar software while still tapping into Facebook&#8217;s<br />
excellent social dynamics? Here&#8217;s what I&#8217;d like to see:
</p>
<div align="center">
<p style="width: 476px;height: auto;padding: 10px;margin: 15px 0 15px 0;border: 1px solid #ddd;font-style: italic;text-align: left" /><img src="http://jonudell.net/images/tell-facebook-once.png" width="476" alt="Example Facebook login page" /></p>
</div>
<p>
It&#8217;s great that Facebook offers outbound iCalendar feeds. I&#8217;d also<br />
like to see it accept <em>inbound</em> feeds. And that should work everywhere,<br />
by the way, not just for Facebook and not just for calendar events.<br />
Consider photos. I should be able to pay a service to archive and<br />
manage my complete photo stream. If I choose to share some of those<br />
photos on Facebook and others on Flickr, both should syndicate the<br />
photos from my online archive using a standard feed protocol &#8212; say<br />
Atom, or if richer type information is needed, <a href="http://odata.org">OData</a>.</p>
<p>
The elmcity project is, above all, an invitation to explore what it<br />
means to <a href="http://blog.jonudell.net/2011/01/24/seven-ways-to-think-like-the-web/">be<br />
the authoritative source of your own data</a>. Among other<br />
things, it means that we should expect services to be able to use our data<br />
without owning our data. And that services should be able to acquire<br />
our data not only by capturing our keystrokes, but also by syndicating<br />
from URLs that we claim as our authoritative sources.
</p>
<div style="height: 160px;border-top: thin gray solid;border-bottom: thin gray solid;padding: 20px;margin: 20px 2px"><a href="https://en.oreilly.com/oscon2011/public/regwith/os11rad?cmp=il-radar-os11-udell-facebook"><img style="float: left;border: none;padding-right: 10px" src="http://s.radar.oreilly.com/oscon-data-code-os11rad.png" /></a><a href="https://en.oreilly.com/oscon2011/public/regwith/os11rad?cmp=il-radar-os11-udell-facebook"><strong>OSCON Data 2011</strong></a>, being held July 25-27 in Portland, Ore., is a gathering for developers who are hands-on, doing the systems work and evolving architectures and tools to manage data. (This event is co-located with <a href="http://www.oscon.com/oscon2011?cmp=il-radar-os11-okcupid">OSCON</a>.)</p>
<p><a href="https://en.oreilly.com/oscon2011/public/regwith/os11rad?cmp=il-radar-os11-udell-facebook"><strong>Save 20% on registration with the code OS11RAD</strong></a></div>
<p></p>
<p><strong>Related:</strong></p>
<ul>
<li> <a href="http://radar.oreilly.com/2011/02/singly-locker-project-telehash.html">The Locker Project: data for the people</a></li>
<li> <a href="http://radar.oreilly.com/tag/elmcity">See all Radar elmcity stories</a></li>
<li> <a href="http://answers.oreilly.com/tag/elmcity">See all Answers elmcity stories</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://radar.oreilly.com/2011/06/facebook-events-syndication.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Uniform APIs for the data web</title>
		<link>http://radar.oreilly.com/2011/04/uniform-apis-odata.html</link>
		<comments>http://radar.oreilly.com/2011/04/uniform-apis-odata.html#comments</comments>
		<pubDate>Wed, 20 Apr 2011 16:00:00 +0000</pubDate>
		<dc:creator>Jon Udell</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[@home]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[elmcity]]></category>
		<category><![CDATA[odata]]></category>

		<guid isPermaLink="false">http://blogs.oreilly.com/radar/2011/04/uniform-apis-odata.html</guid>
		<description><![CDATA[What if blogs had come of age in an era when a uniform kind of API was expected? We could then ask questions of blogs in the same way we could ask questions of event services. ]]></description>
				<content:encoded><![CDATA[<p>
The <a href="http://elmcity.cloudapp.net">elmcity service</a> connects to a half-dozen other services, including Eventful, Upcoming, EventBrite, Facebook, Delicious, and Yahoo. It&#8217;s nice that each of these services provides an API that enables elmcity to read their data. It would be even nicer, though, if elmcity didn&#8217;t have to query, navigate, and interpret the results of each of these APIs in different ways.
</p>
<p>
For example, the elmcity service asks the same question of Eventful, Upcoming, and EventBrite: &#8220;What are the titles, dates, times, locations, and URLs of recent events within radius R of location L?&#8221; It has to ask that question three different ways, and then interpret the answers three different ways. Can we imagine a more frictionless approach?
</p>
<p>
I can. Here&#8217;s how the question might be asked in a general way using the <a href="http://www.odata.org">Open Data Protocol (OData)</a>:
</p>
<pre>
http://odata.[eventful|upcoming|eventbrite].com/events?$filter=type eq 'recent' and radius lt 5
</pre>
<p>
An OData reply is a feed of Atom entries, optionally annotated with types. Here&#8217;s a sketch of how one of those entries might look as part of a general OData answer to the question:
</p>
<pre>
&lt;entry&gt;
  &lt;id&gt;http://odata.hypothetical.com/events/ids('1428475')&lt;/id&gt;
  &lt;<span style="font-weight:bold;color:blue">title</span> type="text"&gt;<span style="font-weight:bold;color:green">Carola Zertuche presents traditional flamenco</span>&lt;/title&gt;
  &lt;updated&gt;2011-04-18T23:00:00Z&lt;/updated&gt;
  &lt;author&gt;&lt;name /&gt;&lt;/author&gt;
  &lt;m:properties
       xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
       xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"&gt;
    &lt;d:Id&gt;1428475&lt;/d:Id&gt;
    &lt;d:<span style="font-weight:bold;color:blue">start</span> m:type="Edm.DateTime"&gt;<span style="font-weight:bold;color:green">2011-05-12T12:00</span>&lt;/d:start&gt;
    &lt;d:<span style="font-weight:bold;color:blue">latitude</span> m:type="Edm.Double"&gt;<span style="font-weight:bold;color:green">37.809600000000003</span>&lt;/d:latitude&gt;
    &lt;d:<span style="font-weight:bold;color:blue">longitude</span> m:type="Edm.Double"&gt;<span style="font-weight:bold;color:green">-122.4106</span>&lt;/d:longitude&gt;
    &lt;d:<span style="font-weight:bold;color:blue">url</span>&gt;<span style="font-weight:bold;color:green">http://hypothetical.com/events/1428475</span>&lt;/d:Url&gt;
    &lt;d:venue_id&gt;83329&lt;/d:venue_id&gt;
  &lt;/m:properties&gt;
&lt;/entry&gt;
</pre>
<p>
(With the addition of $format=json to the query URL, the same information arrives as a JSON payload.)
</p>
<p>
Of course there would still be differences among these APIs. Each of the three services in this example has its own naming conventions and its own way of modeling events and venues. It would still take some work to abstract away those differences. But you&#8217;d be using a common query mechanism, a common set of data representations, a common way of linking them together, and a common set of helper libraries for many programming environments.
</p>
</p>
<h2>A WordPress thought experiment</h2>
</p>
<p>
Blog publishing systems have long implemented APIs that enable client applications to fetch and post blog entries. For historical reasons there are a variety of these APIs. Because they&#8217;re widely adopted in the blog domain, it&#8217;s pretty likely that an application that works with one blog system&#8217;s implementation of one of the APIs will work with another blog system&#8217;s implementation of the same API. But these APIs are specific to the blog domain.
</p>
<p>
What if blogs had come of age in an era when a uniform kind of API was expected? We could then ask questions of blogs in the same way we could ask questions of event services in the hypothetical example shown above, or of any other kind of service. And we could interpret the answers in the same way too.
</p>
<p>
Suppose we want to ask a blog service: &#8220;What are the published entries since April 10, 2011?&#8221; Here&#8217;s an OData version of the question:
</p>
<pre>
http://odata.hypothetical.com/wp_posts?$filter=post_date gt datetime'2011-04-10' and post_status eq 'publish'
</pre>
<p>
And here&#8217;s an answer, in JSON format, from a hypothetical WordPress OData service:
</p>
<pre>
{"d" : { "results": [
  { "__metadata": {
    "uri": "https://odata.sqlazurelabs.com/OData.svc/v0.1/goyot8lwrc/wordpress/wp_posts(7L)",
    "type": "wordpress.wp_posts" },
    "comment_count": "0",
    "comment_status": "open",
    "guid": "http://elmcity-companion.cloudapp.net/wordpress/?p=7",
    "ID": "7",
    "post_author": "1",
    "post_content": "OData as universal API?",
    "post_date": "/Date(1303216978000)/",
    "post_name": "a-wordpress-thought-experiment",
    "post_status": "publish",
    "post_title": "A WordPress thought experiment"
    }
  ]
}}
</pre>
<p>
Except it&#8217;s not hypothetical! The guid shown in this example points to a <a href="http://elmcity-companion.cloudapp.net/wordpress/?p=7">real WordPress post</a>. And the uri in the example points to a <a href="https://odata.sqlazurelabs.com/OData.svc/v0.1/goyot8lwrc/wordpress/wp_posts(7L)?$format=json">live OData service</a> that emits the chunk of JSON we see here. If you&#8217;re so inclined, you can start at the <a href="https://odata.sqlazurelabs.com/OData.svc/v0.1/goyot8lwrc/wordpress/">root</a> of the service and explore all the tables used in that WordPress blog.
</p>
<p>
How is this possible? I&#8217;m running WordPress on Azure; this instance of WordPress uses the SQL Azure database; the database is <a href="https://www.sqlazurelabs.com/">OData-enabled</a>. In this case I&#8217;m allowing only read access. But if the database were writable a blog client could add new entries by sending HTTP POST requests with Atom payloads.
</p>
</p>
<h2>OData for MySQL</h2>
</p>
<p>
Of course WordPress more typically runs on MySQL. Can we do the same kind of thing there? Sort of. Here&#8217;s a query that fetches posts from a Linux/MySQL instance of WordPress and returns them as an Atom feed with OData annotations:
</p>
<p>
<a href="http://www.elmcity.info/mysqlodata/?wp_posts">http://www.elmcity.info/mysqlodata/?wp_posts</a>
</p>
<p>
In this case the OData view of the underlying MySQL database is provided by <a href="http://sourceforge.net/projects/mysqlodata/">MySQLOData</a>, a &#8220;PHP-based MySQL OData Server library which exposes all data within a MySQL database to the world in OData ATOM or JSON format.&#8221;
</p>
<p>
There are two issues here. One is my fault. I&#8217;m not fluent in PHP and I haven&#8217;t been able to get MySQLOData working to its full capability. Do you know of a live instance of MySQLOData that is properly installed and configured? If so please show me the URL, I&#8217;d like to try it out.
</p>
<p>
The second issue is more fundamental. Suppose MySQLOData becomes a full implementation of OData. In any environment where there is PHP and MySQL, any application built on MySQL could automatically expose an API based on a common query mechanism, a common set of data representations, a common way of linking them together, and a common set of helper libraries. Great! But what if there&#8217;s no PHP in the environment? What if there&#8217;s only Python? Or only Ruby? A Django- or Rails-based service shouldn&#8217;t have to add PHP to the mix in order to provide a uniform API.
</p>
<p>
If MySQL itself could present an OData interface, then layered services written in any language could automatically provide APIs in a standard way. Here&#8217;s a description of how that might work:
</p>
<blockquote>
<p>
If we provide access to existing databases as though they were in hypertext form, the system will get off the ground quicker &#8230; What is required is a gateway program which will map an existing structure onto the hypertext model, and allow limited (perhaps read-only) access to it.
</p>
</blockquote>
<p>
If you know your web history that may sound familiar. It&#8217;s from Tim Berners-Lee&#8217;s <a href="http://www.w3.org/History/1989/proposal.html">1989 proposal</a> for the World Wide Web</a>.
</p>
</p>
<h2>There&#8217;s more than one way to do it</h2>
</p>
<p>
Of course OData isn&#8217;t the only way services could automatically provide uniform APIs. Such things typically come in several flavors. In the blog domain there have always been a few of them: the Blogger API, the metaWeblog API, etc. I think it&#8217;s unlikely that we&#8217;ll end up with a single flavor of uniform API. But right now we don&#8217;t have any uniform flavor! Every service that provides an API has to invent its own query mechanism, data representations, and helper libraries. If you want to mash up services &mdash; as we increasingly do &mdash; the differences among these APIs create a lot of friction.
</p>
<p>
OData looks to me like one good way to overcome that friction. I&#8217;d love to see OData gateways co-located with every popular database. With such gateways in place, the web of data we&#8217;re collectively trying to build would get off the ground quicker.
</p>
<p></p>
<p><strong>Related:</strong></p>
<ul>
<li> <a href="http://radar.oreilly.com/tag/elmcity">See all Radar elmcity stories</a></li>
<li> <a href="http://answers.oreilly.com/tag/elmcity">See all Answers elmcity stories</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://radar.oreilly.com/2011/04/uniform-apis-odata.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>How will the elmcity service scale? Like the web!</title>
		<link>http://radar.oreilly.com/2010/12/how-will-the-elmcity-service-s.html</link>
		<comments>http://radar.oreilly.com/2010/12/how-will-the-elmcity-service-s.html#comments</comments>
		<pubDate>Wed, 22 Dec 2010 16:00:00 +0000</pubDate>
		<dc:creator>Jon Udell</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[@home]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[calendar]]></category>
		<category><![CDATA[elmcity]]></category>
		<category><![CDATA[feed]]></category>
		<category><![CDATA[syndication]]></category>

		<guid isPermaLink="false">http://blogs.oreilly.com/radar/2010/12/how-will-the-elmcity-service-s.html</guid>
		<description><![CDATA[A blog feed is just a special kind of web page. Anybody can create a blog and publish its feed at some URL. Why not calendars too? ]]></description>
				<content:encoded><![CDATA[<p>
During a <a href="http://cyber.law.harvard.edu/events/luncheon/2010/12/udell">recent talk</a> at Harvard&#8217;s Berkman Center, <a href="http://scottmacleod.com">Scott MacLeod</a> asked (via the IRC backchannel): &#8220;How does the <a href="http://elmcity.cloudapp.net/">elmcity</a> service scale?&#8221; He wondered, in particular, whether the service could support an online university like the <a href="http://worlduniversity.wikia.com/wiki/World_University">World University and School</a> that might produce an unlimited number of class schedules.
</p>
<p>
My short answer was that the elmcity service scales like the web. But what does that really mean? I promised Scott that I&#8217;d spell it out here. We&#8217;ll start with an analogy. As I mentioned in <a href="http://radar.oreilly.com/2010/08/the-power-of-informal-contract.html">The power of informal contracts</a>, the elmcity project envisions a web of calendar feeds that&#8217;s analogous to the blogosphere&#8217;s web of RSS and Atom feeds. We take for granted that the blogosphere scales like the web. A blog feed is just a special kind of web page. Anybody can create a blog and publish its feed at some URL. Why not calendars too? We haven&#8217;t thought about them in the same way, but the ICS (iCalendar) files that our calendar programs export are the moral equivalents of the RSS and Atom feeds that our blog publishing tools export. Anybody can create a calendar and publish its feed at some URL.
</p>
<p>
These webs &#8212; of HTML pages, of blog feeds, of calendar feeds &#8212; are notionally webs of peers. We can all publish, and we can all read, without relying on a central authority or privileged hub. There are, to be sure, powerful centralized services. <a href="http://blog.jonudell.net/">My blog</a>, for example, is one of millions hosted at <a href="http://www.wordpress.com">wordpress.com</a>, aggregated by Bloglines and Google Reader, and indexed by Google and Bing. But these services, while convenient, are optional. So long as we can publish our blogs somewhere online, advertise their URLs, and get the DNS to resolve their domain names, we can have a working blogosphere. The necessary and sufficient condition is that we can all publish resources (e.g., pages and feeds), and that we can all access those resources.
</p>
<p>
For the calendarsphere that I envision, a service like elmcity is likewise optional. Let&#8217;s suppose that the World University and School succeeds wildly. At any given moment there are tens of thousands of courses on offer, each with its own course page and also with its own calendar. Instructors publish course pages using any web publishing tool, and also publish calendars using any calendar publishing tool &#8212; Google Calendar, or Outlook, or Apple iCal, or another calendar program. Students pick schedules of courses, bookmark the course pages, and load the course calendars into any of these same calendar programs. The calendar software merges the separate course calendars and combines them with the students&#8217; personal calendars. These calendar programs are thus aggregators of calendar feeds in the same way that feedreaders like NetNewsWire or Google Reader are aggregators of blog feeds.
</p>
<p>
Given a baseline web of peers, it&#8217;s useful to be able to merge our individual views of them into pooled spaces. NetNewsWire is a personal feedreader, but Google Reader is social. In the pool created by Google Reader, <a href="http://blog.jonudell.net/2007/07/02/data-finds-data-then-people-find-people/">data finds data and people find people</a>. The elmcity service aims to create that same kind of effect in the realm of public calendar events. When we pool our separate calendars, we publicize the events that we are promoting, we discover events that others are promoting, and we see all our public events on common timelines.
</p>
<p>
What constrains our ability to scale out pools of calendars? Let&#8217;s continue the analogy to the blogosphere. Google Reader constitutes one pooled space for blog feeds, Bloglines another. Because the data aggregated by these services conforms to open standards (i.e., RSS and Atom), other services can create blog pools too. Likewise in the calendarsphere, Google Calendar is one way to pool calendars, the elmcity service is another, <a href="http://code.google.com/p/calagator/">Calagator</a> is a third. Others can play too.
</p>
<p>
How can we scale these providers of calendar pools? Along one axis, each provider needs to be able to grow its computing power. Google Calendar scales on this axis by using Google&#8217;s cloud platform. The elmcity service uses Azure, the Microsoft cloud platform. Note that elmcity, unlike Google Calendar, is an <a href="https://github.com/judell/elmcity/">open source service</a>. That means you could run your own instance of it, using your own Azure account, but you&#8217;d still be relying on the Azure compute fabric.
</p>
<p>
Calagator, based on Ruby on Rails, could be deployed either to a conventional hosting environment or to a cloud platform. It would thus scale, along the compute axis, as either environment allows. The elmcity service could be used in this way too. The service is written for Azure, but the core aggregation engine is independent of Azure and could be deployed to a conventional hosting environment.
</p>
<p>
For feed aggregators, another axis of scale is the number of feeds that can be processed. When that number grows, the time required to connect to many feeds and ingest their contents becomes a constraint. The elmcity service currently supports 50 calendar hubs. Thrice daily, each hub pulls data from Eventful, Upcoming, Eventbrite, Facebook, and a list of iCalendar feeds. So far a single Azure worker role can easily do all this work. I&#8217;ll dial up the number of workers if needed, but first I want to squeeze as much parallelism as I can out of each worker. To that end, I recently upgraded to the 4.0 version of the .NET Framework in order to exploit its dramatically simplified parallel processing. In this week&#8217;s <a href="http://answers.oreilly.com/tag/elmcity">companion article</a> I show how the elmcity service uses that new capability to optimize the time required to gather feeds from many sources.
</p>
<p>
Pub/sub networks can also scale by coalescing feeds. Consider a calendar hub operated, for some city, by the online arm of that city&#8217;s newspaper. One model is flat. The newspaper runs a hub whose registry lists all the calendar feeds in town. But another model is hierarchical. In that model, there&#8217;s a hub for arts and culture, a hub for sports and recreation, a hub for city government, and so on. Each hub gathers events from many feeds, and publishes the merged result on its own website for its own constituency. If the newspaper wants to include all those feeds, it can list them individually in its own registry. But why aggregate arts, sports, or recreation feeds more than once? The newspaper&#8217;s uber-hub can, instead, reuse the arts, sports, and recreation feeds curated by those respective hubs, adding their merged outputs to its own set of curated feeds. Such reuse can cut down the computational time and effort required to propagate feeds throughout the network.
</p>
<p>
None of these mechanisms will matter, though, until a vibrant ecosystem of calendar feeds requires them. That&#8217;s the ultimate constraint. Scaling the calendarsphere isn&#8217;t a problem yet, but it would be a good problem to have. First, though, we&#8217;ve got to light up a whole bunch of feeds.
</p>
<p></p>
<p><strong>Related:</strong></p>
<ul>
<li> <a href="http://radar.oreilly.com/2010/11/the-icalendar-chicken-and-egg.html">The iCalendar chicken-and-egg conundrum</a></li>
<li> <a href="http://radar.oreilly.com/2010/10/developing-intuitions-about-da.html">Developing intuitions about data</a></li>
<li> <a href="http://radar.oreilly.com/2010/09/personal-data-stores-and-pubsu.html">Personal data stores and pub/sub networks</a></li>
<li> <a href="http://radar.oreilly.com/2010/09/the-principle-of-indirection.html">The principle of indirection</a></li>
<li> <a href="http://radar.oreilly.com/tag/elmcity">See all Radar elmcity stories</a></li>
<li><a href="http://answers.oreilly.com/tag/elmcity">See all Answers elmcity stories</a></li>
</ul>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://radar.oreilly.com/2010/12/how-will-the-elmcity-service-s.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The iCalendar chicken-and-egg conundrum</title>
		<link>http://radar.oreilly.com/2010/11/the-icalendar-chicken-and-egg.html</link>
		<comments>http://radar.oreilly.com/2010/11/the-icalendar-chicken-and-egg.html#comments</comments>
		<pubDate>Fri, 12 Nov 2010 17:00:00 +0000</pubDate>
		<dc:creator>Jon Udell</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[@home]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[elmcity]]></category>
		<category><![CDATA[icalendar]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://blogs.oreilly.com/radar/2010/11/the-icalendar-chicken-and-egg.html</guid>
		<description><![CDATA[If you're a school or a business or a band or a club whose website sports an <em>Events</em> tab that doesn't offer a companion iCalendar feed, I hope you'll ask your CMS vendor why not. ]]></description>
				<content:encoded><![CDATA[<p>
If you&#8217;re running a website for a school, or a business, or a band, or a club, there&#8217;s probably a tab on your site&#8217;s home page labeled <em>Events</em>. The calendar that shows up on that page is most likely driven by some kind of content management system that collects your events using a form, stores them in a database, and renders them through an HTML template to produce your events page.</p>
<p>One of the premises of <a href="http://radar.oreilly.com/tag/elmcity">this series</a> is that publishing calendars as HTML, for people to read on your events page, is necessary but not sufficient. You should also want to publish events as data for computers to process and for networks to syndicate. And you should expect your content management system, which already has the data in a machine-friendly format, to do that for you. But this almost never happens, and so we have a classic chicken-and-egg conundrum. Nobody expects that a website&#8217;s events page should offer a parallel data feed, so nobody demands that CMS vendors provide one, and as a result hardly any do.</p>
<p>
<a href="http://www.hannahgrimes.com/"><img src="http://s.radar.oreilly.com/2010/11/12/111210-elmcity.png" width="300" border="0" alt="Hannah Grimes calendar" style="float: right;margin: 3px 0 12px 12px"></a>Consider the case of the <a href="http://www.hannahgrimes.com/">Hannah Grimes Center</a> in Keene, NH. Its <a href="http://events.constantcontact.com/calendar/monthview?eso=001TPLYMzXMR5LiqAuNDSWezw==">events page</a> is provided by the <a href="http://www.constantcontact.com/">Constant Contact</a> service as part of a package of <a href="http://www.constantcontact.com/event-marketing/features/index.jsp">event marketing features</a> that include registration and social media promotion. But there&#8217;s only an HTML page; no companion iCalendar feed is available. That means the Hannah Grimes Center&#8217;s events aren&#8217;t available as a stream of data that can syndicate through networks and merge with other calendars. </p>
<p>
The irony here is that a previous version of the Hannah Grimes site did provide an iCalendar feed. In that version, the events page was served by Drupal. It has a calendar module that publishes event data two ways: as HTML, and as iCalendar. Last week I happened to meet the site&#8217;s coordinator; she wondered why their event stream had dropped out of syndication. I explained, and she wrote back the other day saying: &#8220;We&#8217;re in the process of converting back to Drupal for events!&#8221;
</p>
<p>
Drupal is a great system, and that&#8217;s fine, but it shouldn&#8217;t be necessary. Every CMS that produces an events page should also produce an iCalendar feed. When I talk to CMS vendors they confirm what I&#8217;ve said here: Customers don&#8217;t ask, so vendors don&#8217;t provide. What I also hear from them, though, is that producing an iCalendar feed seems like a lot of work. It isn&#8217;t. Libraries are available to simplify the translation from programming-language data structures to iCalendar feeds. And even without such libraries, it&#8217;s not hard to whip up a simple iCalendar feed.
</p>
<p>
My vision for a network of iCalendar feeds is inspired by the early blogosphere&#8217;s network of RSS feeds. Content management systems, like <a href="http://radio.userland.com/">Radio UserLand</a>, produced those feeds automatically. But many of us also produced our own feeds without the aid of kits. We did it &#8220;by hand&#8221; &#8212; that is, by interpolating variables into XML templates. It was easy to do, and it worked well enough to enable our homegrown feeds to participate in the emerging RSS ecosystem. In this week&#8217;s companion article (&#8220;<a href="http://answers.oreilly.com/topic/2215-how-to-translate-an-odata-feed-into-an-icalendar-feed/">How to translate an OData feed into an iCalendar feed</a>&#8220;) I show how the elmcity service uses a library to produce iCalendar feeds. But if you look at the sample feed at the end of that article, you&#8217;ll see that &#8212; like the RSS 0.9 many of us created by hand &#8212; it isn&#8217;t really rocket science.
</p>
<p>
There was, of course, another reason why the homegrown approach worked as well as it did. It&#8217;s true that we didn&#8217;t have tools to help us write RSS feeds, but we did have a tool to validate them. The <a href="http://feedvalidator.org/">Feed Validator</a>, originally created by <a href="http://diveintomark.org/">Mark Pilgrim</a> and <a href="http://www.intertwingly.net/blog/">Sam Ruby</a>, was &#8212; and remains &#8212; a pillar supporting the RSS (and now, RSS/Atom) ecosystem.
</p>
<p>
When I set out to bootstrap an iCalendar network, I realized that there was no analogous service to validate iCalendar feeds. So I reached out to <a href="http://ddaysoftware.com/Pages/About.aspx">Doug Day</a>. He&#8217;s the author of <a href="http://ddaysoftware.com/Pages/Projects/DDay.iCal/">DDay.iCal</a>, which is the open source library that the elmcity service uses to parse the iCalendar feeds it gathers into each hub, and also write iCalendar feeds that merge all of the inputs to each hub. Doug thought there should be a validator for iCalendar feeds, so he stepped up to the plate and <a href="http://blog.jonudell.net/2010/01/05/talking-with-doug-day-about-the-icalendar-validator/">created one</a> at <a href="http://icalvalid.cloudapp.net">icalvalid.cloudapp.net</a>.
</p>
<p>
If you&#8217;re a school or a business or a band or a club whose website sports an <em>Events</em> tab that doesn&#8217;t offer a companion iCalendar feed, I hope you&#8217;ll ask your CMS vendor why not. If you&#8217;re one of the vast majority of CMS vendors whose systems create events pages but don&#8217;t produce iCalendar feeds, I hope you won&#8217;t wait to be asked. With or without tool support, it&#8217;s not hard to make them. (See this week&#8217;s <a href="http://answers.oreilly.com/tag/elmcity">companion article</a> for a C# example based on Doug Day&#8217;s DDay.iCal library.) And, thanks to Doug, there&#8217;s now a validation service to help you make them right.
</p>
<p></p>
<p><strong>Related:</strong></p>
<ul>
<li> <a href="http://radar.oreilly.com/2010/09/personal-data-stores-and-pubsu.html">Personal data stores and pub/sub networks</a></li>
<li> <a href="http://radar.oreilly.com/2010/08/the-laws-of-information-chemis.html">The laws of information chemistry</a></li>
<li> <a href="http://radar.oreilly.com/2010/08/lessons-learned-building-the-e.html">Lessons learned building the elmcity service</a></li>
<li><a href="http://radar.oreilly.com/tag/elmcity">See all Radar elmcity stories</a></li>
<li><a href="http://answers.oreilly.com/tag/elmcity">See all Answers elmcity stories</a></li>
</ul>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://radar.oreilly.com/2010/11/the-icalendar-chicken-and-egg.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Heds, deks, and ledes</title>
		<link>http://radar.oreilly.com/2010/11/heds-deks-and-ledes.html</link>
		<comments>http://radar.oreilly.com/2010/11/heds-deks-and-ledes.html#comments</comments>
		<pubDate>Thu, 04 Nov 2010 15:00:00 +0000</pubDate>
		<dc:creator>Jon Udell</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[@home]]></category>
		<category><![CDATA[elmcity]]></category>
		<category><![CDATA[information]]></category>
		<category><![CDATA[information architecture]]></category>

		<guid isPermaLink="false">http://blogs.oreilly.com/radar/2010/11/heds-deks-and-ledes.html</guid>
		<description><![CDATA[Headlines matter. They&apos;re always visible to a scan or a search, while other information -- like decks and leads -- are active in far fewer contexts.  ]]></description>
				<content:encoded><![CDATA[<p>When a copy editor applies a real or virtual red pencil to a piece of journalistic prose, he or she is likely to use weird spellings: hed for head (headline), dek for deck (subhead), lede for lead (first paragraph). The idea is that these intentional misspellings will help distinguish an editor&#8217;s commentary from a writer&#8217;s prose.</p>
<p>Whether this is a useful convention or just an antiquated habit I really can&#8217;t say. But the principle of heads, decks, and leads matters more than ever, and not just in journalism. We&#8217;re all publishers now in one way or another. None of us can predict the contexts in which what we publish will be found. But if we&#8217;re careful about writing heads, decks, and leads, we&#8217;ll improve the odds that it will be found.</p>
<p>You can apply this principle to any package of information: an email message, a blog post, an event listing. In an email message the head is clearly the Subject: line; in a blog posting it&#8217;s the title. What about the deck? Here&#8217;s where <a href="http://blog.jonudell.net/2009/04/23/what-is-the-rss-of-calendars/">creative analogies</a> come into play. In these cases, only the head will be seen when readers scan their inboxes or RSS feeds. So you might want to collapse the idea of head and deck into a single robust head. As for the lead, well, it&#8217;s always best to begin an email message or a blog post with a compelling first paragraph.</p>
<p>Event listings are trickier. Here are some possible mappings for two examples from Facebook:</p>
<h2>Example 1</h2>
<div style="padding: 6px; border-style: solid; border-width: thin; margin-bottom: 12px;">
<p><img style="border-style: solid; border-width: thin; margin-bottom: 12px;" src="http://jonudell.net/images/facebook-create-event-starving-artist.png" alt="" /></p>
<p><strong>Head</strong>: <a href="http://www.facebook.com/event.php?eid=100599506662874">World History @ Starving Artist (Keene NH)</a></p>
<p><strong>Deck</strong>: Sunday, November 14 · 8:00pm &#8211; 11:30pm, The Starving Artist, 10 West St, Keene, NH</p>
<p><strong>Lead</strong>:<br />
Music by: WORLD HISTORY, www.worldhistoryband.com, YOUNG MOUNTAIN, www.myspace.com/youngmountainnh,<br />
ALL AGES are welcome, $5, http://www.thestarvingartistcollective.com/</p>
</div>
<p>Here the best analog for head (or title, or subject) is the <em>What are you planning?</em> field. A reasonable analog for deck combines the <em>When?</em> and <em>Where?</em> fields. And the <em>More info?</em> field maps neatly to the lead.</p>
<h2>Example 2</h2>
<div style="padding: 6px; border-style: solid; border-width: thin; margin-bottom: 12px;">
<p><img style="border-style: solid; border-width: thin; margin-bottom: 12px;" src="http://jonudell.net/images/facebook-create-event-armadillos.png" alt="" /></p>
<p><strong>Head</strong>: <a href="http://www.facebook.com/#!/event.php?eid=159369477427506">Cold River Ranters at Armadillo&#8217;s Burritos</a></p>
<p><strong>Deck</strong>: Friday, November 5 · 7:00pm &#8211; 9:00pm, 82 Main Street</p>
<p><strong>Lead</strong>: None</p>
</div>
<p>Following the same pattern, we can map the head and the deck and omit the lead. Now, compare the two mappings. Example 2 lacks some critical information. And that missing information makes it less discoverable than Example 1. Can you spot what&#8217;s missing? Here&#8217;s a hint: It&#8217;s not the absence of the lead. Another hint: It&#8217;s not even the absence of a full street address including the city and state. The critical difference is that Example 1 includes the city and state <em>in the head</em> and Example 2 doesn&#8217;t.</p>
<p>I only realized this when I added Facebook to the set of <a href="http://blog.jonudell.net/2010/05/07/facebook-is-now-an-elmcity-event-source/">elmcity event sources</a>. The elmcity service uses the Facebook graph API to search for events using search terms like &#8220;Keene, NH&#8221; or &#8220;Santa Rosa, CA.&#8221; If you run that search <a href="http://elmcity.info/fb_events?location=keene,nh">for Keene</a> you&#8217;ll see that Example 1 shows up but Example 2 is missing in action.</p>
<p>Here&#8217;s a version that would have worked for the Cold River Ranters:</p>
<h2>Example 2a</h2>
<div style="padding: 6px; border-style: solid; border-width: thin; margin-bottom: 12px;">
<p><strong>Head</strong>: Cold River Ranters at Armadillo&#8217;s Burritos, <span style="font-size: larger; font-style: italic;">Keene, NH</span></p>
<p><strong>Deck</strong>: Friday, November 5 · 7:00pm &#8211; 9:00pm, 82 Main Street</p>
</div>
<p>But here&#8217;s a version that wouldn&#8217;t have worked:</p>
<h2>Example 2b</h2>
<div style="padding: 6px; border-style: solid; border-width: thin; margin-bottom: 12px;">
<p><strong>Head</strong>: Cold River Ranters at Armadillo&#8217;s Burritos</p>
<p><strong>Deck</strong>: Friday, November 5 · 7:00pm &#8211; 9:00pm, 82 Main Street, The Starving Artist, 10 West St, , <span style="font-size: larger; font-style: italic;">Keene, NH</span></p>
</div>
<p>It seems that when you use Facebook&#8217;s API to search for events, it only looks for your phrase in the heads. So, for example, if you searched Facebook events for <a href="http://elmcity.info/fb_events?location=starving+artist">Starving Artist</a> the results would include:</p>
<pre>      {
         "name": "Starving Artist Ent. Presents: This Is Hip Hop",
         "start_time": "2010-11-28T04:00:00+0000",
         "end_time": "2010-11-28T09:00:00+0000",
         "location": "My House Bar &amp; Lounge",
         "id": "157463474273974"
      },
      {
         "name": "Starving Artist Project",
         "start_time": "2010-11-19T03:30:00+0000",
         "end_time": "2010-11-19T06:00:00+0000",
         "location": "Mary's Attic Chicago",
         "id": "137831546269077"
      },
      {
         "name": "World History @ Starving Artist (Keene NH)",
         "start_time": "2010-11-15T04:00:00+0000",
         "end_time": "2010-11-15T07:30:00+0000",
         "location": "The Starving Artist",
         "id": "100599506662874"
      }</pre>
<p>The last of these is the same event that&#8217;s included in a <a href="http://elmcity.info/fb_events?location=keene,nh">search for Keene, NH</a>. By writing a head that includes the location, the Starving Artist Collective succeeded in making its event discoverable by Keene&#8217;s event hub. By failing to include the location, the Cold River Ranters missed out on that opportunity. (So did Mary&#8217;s Attic: A hub tuned to Facebook&#8217;s virtual channel for Chicago events would have missed that one.)</p>
<p>I&#8217;m sure that neither the Starving Artist Collective nor the Cold River Ranters knows anything about the workings of the Facebook search API. But the Starving Artist Collective has intuited an crucial principle: Headlines matter. Always pack as much distinguishing data into them as available space allows. Heads will always be visible to a scan or a search; decks and leads are active in far fewer contexts. If your headline doesn&#8217;t create access to those supporting contexts, it will be much harder for people to reach them serendipitously.</p>
<p>In this week&#8217;s <a href="http://answers.oreilly.com/tag/elmcity">companion article</a> I show how the elmcity service uses the Facebook API. If you&#8217;re not a developer you won&#8217;t care about that. But everybody should care about the principle of heads, decks, and leads. We&#8217;re all publishers. We publish in order to be found, to be read, to connect, to have influence. When we&#8217;re careful about how we package and layer our information, we become more effective publishers.</p>
<p>&nbsp;</p>
<p><strong>Related:</strong></p>
<ul>
<li><a href="http://radar.oreilly.com/2010/10/developing-intuitions-about-da.html">Developing intuitions about data</a></li>
<li><a href="http://radar.oreilly.com/2010/08/the-laws-of-information-chemis.html">The laws of information chemistry</a></li>
<li><a href="http://radar.oreilly.com/tag/elmcity">See all Radar elmcity stories</a></li>
<li><a href="http://answers.oreilly.com/tag/elmcity">See all Answers elmcity stories</a></li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://radar.oreilly.com/2010/11/heds-deks-and-ledes.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A lesson in civics, public data, and computational principles</title>
		<link>http://radar.oreilly.com/2010/10/a-lesson-in-civics-public-data.html</link>
		<comments>http://radar.oreilly.com/2010/10/a-lesson-in-civics-public-data.html#comments</comments>
		<pubDate>Tue, 26 Oct 2010 16:00:00 +0000</pubDate>
		<dc:creator>Jon Udell</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[@home]]></category>
		<category><![CDATA[calendar]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[elmcity]]></category>

		<guid isPermaLink="false">http://blogs.oreilly.com/radar/2010/10/a-lesson-in-civics-public-data.html</guid>
		<description><![CDATA[An efficient model of collective information management relies on principles like pub/sub, indirection and syndication. Translating these principles beyond computational thinkers is the tricky part. To pull it off we need to educate the kids we assume to be digital natives. ]]></description>
				<content:encoded><![CDATA[<p>
Among the elmcity hubs that started up last week were <a href="http://elmcity.cloudapp.net/services/insantarosa">Santa Rosa, Calif.</a> and <a href="http://elmcity.cloudapp.net/services/bhamstateofmind">Bellingham, Wash.</a>. Both towns&#8217; local newspapers, the <a href="http://www.pressdemocrat.com/">Press Democrat</a> and the <a href="http://www.bellinghamherald.com/">Bellingham Herald</a>, use a service called <a href="http://www.zvents.com/">Zvents</a> to manage their online calendars. The curators who started the Santa Rosa and Bellingham hubs, Sean Boisen and Tim Sawtell, wondered if they could subscribe these hubs to iCalendar feeds from Zvents.</p>
<p>
At first glance the answer was yes. On the Press Democrat&#8217;s site, for example, if you view the <a href="http://events.pressdemocrat.com/search?cat=1&amp;st=event">Arts &amp; Crafts</a> category, you&#8217;ll find this encouraging cluster of icons and links:
</p>
<p align="center">
<img src="http://jonudell.net/images/press-democrat-save-search.png" />
</p>
<p>
An iCalendar feed? Sweet! But alas, while that &#8220;Save as iCal&#8221; does yield an iCalendar response, it&#8217;s an empty shell:
</p>
<pre>
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
PRODID:Zvents Ical
END:VCALENDAR
</pre>
<p>
Why? Beats me, if someone knows I&#8217;d love to hear the explanation. Meanwhile, what about the corresponding RSS feed? I wasn&#8217;t hopeful. In my work on the elmcity project I often see an error of the sort I discussed in &#8220;<a href="http://radar.oreilly.com/2010/10/developing-intuitions-about-da.html">Developing intuitions about data</a>.&#8221; People tend to conflate the purposes of an RSS feed, which typically conveys headlines and links to people, and an iCalendar feed, which conveys dates and times to computers. This category error is so common that I&#8217;ve enshrined it in a <a href="http://www.slideshare.net/judell/the-elmcity-project/8">slide</a> I&#8217;ve used in several recent talks.
</p>
<p>
But I opened up the Press Democrat&#8217;s RSS feed anyway, and here is what I found:
</p>
<div style="padding:6px;border-style:solid;border-width:thin">
<p>
<strong>&lt;item&gt;</strong><br />
<strong>&lt;title&gt;</strong>Event: JLNS Holiday Home Tour &amp; Winter Market at Friedman Event Center, Sat, Nov 20 10:00a<strong>&lt;/title&gt;</strong><br />
<strong>&lt;description&gt;</strong>The Junior League of Napa-Sonoma presents a tour of prestigious homes in Bennett Valley, all festively decorated, with all proceeds to benefit local charities<strong>&lt;/description&gt;</strong><br />
<strong>&lt;link&gt;</strong>http://events.pressdemocrat.com/santa-rosa-ca/events/show/139081965-jlns-holiday-home-tour-winter-market<strong>&lt;/link&gt;</strong><br />
<strong>&lt;xCal:dtstart&gt;</strong><span style="color:red">2010-11-20 10:00:00 +0000</span><strong>&lt;/xCal:dtstart&gt;</strong><br />
<strong>&lt;xCal:dtend&gt;</strong>2010-11-20 16:00:00 +0000<strong>&lt;/xCal:dtend&gt;</strong><br />
<strong>&lt;xCal:location&gt;</strong>http://events.pressdemocrat.com/santa-rosa-ca/venues/show/672937-friedman-event-center<strong>&lt;/xCal:location&gt;</strong><br />
<strong>&lt;/item&gt;</strong>
</p>
</div>
<div style="font-style:italic;margin-bottom:20px">Fig. 1: An event in the Press Democrat&#8217;s RSS events feed</div>
<p>
Even if you know about such things as XML, RSS, and xCal, pretend for a moment that you don&#8217;t. Anyone can see that there is structure here: <strong>&lt;xCal:dtstart&gt;</strong><span style="color: red">2010-11-20 10:00:00 +0000</span><strong>&lt;/xCal:dtstart&gt;</strong>. That makes this feed very different from most RSS feeds that purport to represent calendar events, which typically look like this:
</p>
<div style="padding:6px;border-style:solid;border-width:thin">
<p>
<strong>&lt;item&gt;</strong><br />
<strong>&lt;title&gt;</strong>Event: JLNS Holiday Home Tour &amp; Winter Market at Friedman Event Center, <span style="color:red">Sat, Nov 20 10:00a</span><strong>&lt;/title&gt;</strong><br />
<strong>&lt;description&gt;</strong>The Junior League of Napa-Sonoma presents a tour of prestigious homes in Bennett Valley, all festively decorated, with all proceeds to benefit local charities<strong>&lt;/description&gt;</strong><br />
<strong>&lt;link&gt;</strong>http://events.pressdemocrat.com/santa-rosa-ca/events/show/139081965-jlns-holiday-home-tour-winter-market<strong>&lt;/link&gt;</strong><br />
<strong>&lt;/item&gt;</strong>
</p>
</div>
<div style="font-style:italic;margin-bottom:20px">Fig. 2: Same event in a typical RSS events feed</div>
<p>
We humans have no trouble understanding <span style="color:red">Sat, Nov 20 10:00a</span>. The year is omitted but we know what&#8217;s meant. Likewise we can parse a wide range of alternatives, such as <span style="color:red">Saturday, November 20, at 10:00</span>. Does that mean AM or PM? We just know that it&#8217;s AM; a home tour wouldn&#8217;t start on Saturday at 10PM. Conversely we just know that a blues band wouldn&#8217;t start playing on Saturday at 10AM.
</p>
<p>
Since we aren&#8217;t aware that we hold this tacit knowledge, it doesn&#8217;t occur to us that computers lack it, or that as a result they require explicit rules and structure. But if you want your data to syndicate around the web, you&#8217;ve got to provide rule-based structure. Since iCalendar is the most ubiquitous format for event data, that&#8217;s currently the best way to do it. Here&#8217;s that same event in iCalendar:
</p>
<pre>
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
PRODID:Zvents Ical
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20101120T100000
DTEND:20101120T16000000
SUMMARY:Event: JLNS Holiday Home Tour &amp; Winter Market at Friedman
  Event Center, Sat, Nov 20 10:00a
END:VEVENT
END:VCALENDAR
</pre>
<div style="font-style:italic;margin-bottom:20px">Fig. 3: Same event in an iCalendar feed</div>
<p>
A point that technologists often miss, when we fight religious wars amongst ourselves about competing formats &#8212; RSS versus Atom, iCalendar versus xCalendar, and so on &#8212; is that the existence of structure matters far more than the kind of structure. Fig. 1 and Fig. 3 are two species within the same genus. Fig. 2, though, belongs to another phylum altogether. If you&#8217;re using the method shown in Fig. 2 to syndicate your data on the web, you&#8217;re doing it wrong. That RSS feed is no more useful for the purpose than a PDF file, or an HTML file.</p>
<p>
When I realized that Zvents produces RSS+xCal feeds, and that multiple newspaper sites rely on Zvents, I added support for that format to the elmcity service. A translator reads RSS+xCal and writes iCalendar. Because the Zvents flavor of RSS+xCal is well structured, it was trivial to create that translator.
</p>
<p>
This new feature for elmcity hubs creates some interesting opportunities. For example, since each Zvents feed is the result of a query, the set of these RSS+xCal feeds is unbounded. Here&#8217;s one kind of query used on the Press Democrat&#8217;s <a href="http://events.pressdemocrat.com/">events page</a>; it lists events in the &#8220;Dance&#8221; category.
</p>
<p align="center">
<a href="http://events.pressdemocrat.com/search?cat=4&amp;st=event">http://events.pressdemocrat.com/search?cat=4&amp;st=event</a>
</p>
<p>
We can easily transform that URL into one that yields the corresponding RSS feed:
</p>
<p align="center">
<p>http://events.pressdemocrat.com/search?cat=4&#038;st=event&#038;rss=1</p>
<p>
Observing this, Tim Sawtell was able to merge a <a href="http://www.delicious.com/insantarosa">set of categorized feeds</a> into the Santa Rosa hub. In doing so, he illustrated a number of key <a href="http://www.slideshare.net/judell/the-local-internet/3">principles</a> that computational thinkers know and apply:
</p>
<ol>
<li> query &#8212; the feed is the output of an open-ended search</li>
<li> data structure &#8212; a structured representation of the search is available as RSS+xCal</li>
<li> transformation &#8212; from RSS+xCal to iCalendar</li>
<li> abstraction and generalization &#8211; what works for one category works for all</li>
</ol>
<p>
Even more is possible. Suppose you&#8217;re a grief counselor in Santa Rosa, and you would like to provide your clientele with a comprehensive list of support resources. Here&#8217;s a useful search:
</p>
<p align="center">
<a href="http://events.pressdemocrat.com/search?swhat=bereavement">http://events.pressdemocrat.com/search?swhat=bereavement</a>
</p>
<p>
It yields two recurring events for two different support groups at Hospice By The Bay.
</p>
<table cellpadding="10" cellspacing="10">
<tr>
<td><a href="http://events.pressdemocrat.com/sonoma-ca/events/show/118647045-free-hospice-by-the-bay-dropin-group-supports-newly-bereaved">Free Hospice By The Bay Drop-in Group Supports Newly Bereaved</a><br />
Join others who are beginning the journey through grief at a free, ongoing, drop-in &#8230;</td>
<td>10/26/2010 Tuesday<br />
12:00p to 1:00p <br />
<a href="http://events.pressdemocrat.com/sonoma-ca/events/show/118647045-free-hospice-by-the-bay-dropin-group-supports-newly-bereaved">(repeats 9 times)</a><br />
<a href="http://events.pressdemocrat.com/sonoma-ca/venues/show/276112-hospice-by-the-bay">Hospice By The Bay</a>,<br />
Sonoma CA</td>
</tr>
<tr>
<td><a href="http://events.pressdemocrat.com/sonoma-ca/events/show/137694185-hospice-by-the-bay-support-group-for-spousalpartner-loss">Hospice By The Bay Support Group for Spousal/Partner Loss</a><br />
Hospice By The Bay offers an eight-week support group to help adults who have lost &#8230;</td>
<td>10/26/2010 Tuesday<br />
10:00a to 11:30a<br />
<a href="http://events.pressdemocrat.com/sonoma-ca/venues/show/276112-hospice-by-the-bay">Hospice By The Bay</a>,<br />
Sonoma CA</td>
</tr>
</table>
<div style="font-style:italic;margin-bottom:20px">Fig. 4: Bereavement support group meetings in Santa Rosa, via the Press Democrat</div>
<p>
Here&#8217;s a transformation of that search URL that yields a RSS+xCal data feed:
</p>
<p align="center">
<p>http://events.pressdemocrat.com/search?swhat=bereavement&#038;rss=1</p>
<p>
That feed can now be further transformed into an iCalendar feed and included in an elmcity hub, or in any other cloud-based service or device-based app that reads iCalendar feeds. If you wanted to create a bereavement category in an elmcity hub you&#8217;d be off to a great start! But where else would you look? There&#8217;s plenty of information about public events on the web today. But only a tiny fraction of it exists as structured data that can flow through syndicated networks. Most of it lives in PDF files, or HTML files, that are only valuable to people who find their way to the sites that serve up those files.
</p>
<p>
In an effort to visualize this iceberg of unstructured information below the waterline of the data web, I added a feature to the elmcity service that searches for recurring events. It works by looking for the kinds of phrases that we humans use in our discourse: <em>first Monday of every month at 9PM</em> or <em>2nd and 4th Tuesday, 6:15-7:45 pm</em>. In this week&#8217;s <a href="http://answers.oreilly.com/tag/elmcity">companion article</a> I show how that search harvests pages containing these terms from Google and Bing. Here, let&#8217;s consider a few of the 3,500 items found when running that kind of search <a href="http://elmcity.cloudapp.net/services/insantarosa/search">for Santa Rosa</a>:
</p>
<div style="padding:6px;border-style:solid;border-width:thin">
<p>
<div>google: 1253</div>
<div>bing: 2023</div>
<div>google_and_bing: 292</div>
</p>
<p>1. <a href="http://therapists.psychologytoday.com/rms/name/Hannah_Caratti_MFTI_Santa%2BRosa_California_61368">Hannah Caratti, Pre-Licensed Professional, Santa Rosa, CA 95404 &#8230;</a> (google)
<p>Every Monday at 6pm &#8211; 7pm $20 &#8211; $30 per session. Meditation &amp; Stress Reduction   Group &#8230; Chronic Pain or Illness Therapist in Santa Rosa, CA &#8230;</p>
</p>
<p>2. <a href="http://therapists.psychologytoday.com/rms/name/Bob_Greenberg_MA,MFT_Santa%2BRosa_California_39657">Bob Greenberg, Marriage &amp; Family Therapist, Santa Rosa, CA 95404 &#8230;</a> (google)
<p>Every Monday at 12am &#8211; 12am $40+ per session. An in depth group for adult &#8230;</p>
</p>
<p>3. <a href="http://www.womenshealthandbirthcenter.com/classes.html">Classes at the Women&#039;s Health and Birth Center</a> (google)
<p>Every Monday (except for holiday Mondays). Group/walk-in from 12 noon &#8230;   Women&#039;s Health and Birth Center since 1993, 583 Summerfield Road Santa Rosa, CA   95405.</p>
</p>
<p>4. <a href="http://www.suttervnaandhospice.org/support/support_NorthBay.html">North Bay Bereavement and Grief Support Programs</a> (google)
<p>Every Monday, Noon-1:30 p.m.. Back to top &#8230; 547 Mendocino Avenue, Santa Rosa,   CA 95401 (Parking garage 521 7th Street) &#8230;</p>
</p>
</div>
<div style="font-style:italic;margin-bottom:20px">Fig. 5: Unstructured event data for Santa Rosa</div>
<p>
Investigating the fourth item, North Bay Bereavement and Grief Support Programs, we find a bunch of events represented in an unstructured way:
</p>
<div style="padding:6px;border-style:solid;border-width:thin">
<p>
Bereaved Parents: For parents whose young or adult child has died.<br />
2nd and 4th Thursdays, 6:00 &#8211; 7:30 p.m.</p>
<p>
Family and Caregiver Support Groups: For adults whose loved one has a life-threatening illness.<br />
Every Tuesday, 4:00-5:30 p.m.</p>
<p>
Survivors of Suicide: For those who have lost a loved one to suicide.<br />
Every Monday, Noon-1:30 p.m.</p>
<p>
People in Grief: For people whose loved one has died.<br />
Every Wednesday, 6:00-7:30 p.m.</p>
<p>
Partner Loss &#8211; Evening: For adults whose spouse or partner has died.<br />
2nd and 4th Tuesday, 6:15-7:45 p.m.</p>
<p>
Partner Loss &#8211; Daytime: For adults whose spouse or partner has died.<br />
Every Wednesday, 11:00 a.m. &#8211; 12:30 p.m.</p>
</div>
<div style="font-style:italic;margin-bottom:20px">Fig. 6: Unstructured event data about bereavement support groups in Santa Rosa</div>
<p>
I&#8217;m sure the Press Democrat would love to include these events on its calendar. It can&#8217;t, though, because there&#8217;s only one way for <a href="http://www.suttervnaandhospice.org">Sutter VNA and Hospice</a> to get its support group meetings onto the Press Democrat&#8217;s calendar. Somebody has to <a href="https://secure.zvents.com/elx/events_pressdemocrat_com/user/login?return_to=%2Flistings%2Fevent">log into the site</a> and input the data.
</p>
<p>
That model has never worked well, and it never will. The folks at Sutter VNA and Hospice only want to input that information once, on their own website. And that&#8217;s all they should be expected to do! Their site ought to be the authoritative source for both human-readable information about events <em>and</em> machine-readable data that can syndicate to the Press Democrat or to any other site that needs it. </p>
<p>
Unfortunately the Sutter VNA folks don&#8217;t know about this dual possibility, and don&#8217;t realize that they could achieve it using Google Calendar, or Hotmail Calendar, or any other single source of human-readable text and machine-readable data about public events.
</p>
<p>
Likewise, the Press Democrat does not realize that it could subscribe to a data feed from Sutter VNA, once, and thereafter automatically receive a stream of data as comprehensive and accurate as the authoritative source wishes to provide.
</p>
<p>
This model for collective information management relies on <a href="http://www.slideshare.net/judell/the-local-internet/13">principles</a> that computational thinkers know and apply, including:
</p>
<ol>
<li> pub/sub &#8212; the communication pattern is publish/subscribe</li>
<li> indirection &#8212; event data is passed by reference, not by value, from publisher to subscriber</li>
<li> syndication &#8212; a loosely-coupled network of publishers and subscribers</li>
</ol>
<p>
How might we teach these kinds of principles to the Sutter VNAs and Press Democrats of the world? Maybe we can start by teaching them to the kids we think are digital natives, but who don&#8217;t actually learn these principles &#8212; because we haven&#8217;t formulated them and don&#8217;t teach them.</p>
<p>If you teach in a middle school or a high school, here&#8217;s an interesting civics lesson you could try. Spin up an elmcity hub for your town, point kids at the unstructured iceberg revealed by the search feature, and show them how to use a service like Google Calendar or Hotmail Calendar to convert unstructured event information into structured event data that can syndicate through the hub.</p>
<p>The task can easily be parallelized by carving the list of search results into chunks, and assigning chunks to individual students or teams of students. Working together they should soon be able to produce a substantial calendar of events that won&#8217;t appear in any existing online directory. That calendar will be both a valuable civic contribution and a lesson in underlying principles.
</p>
<p>
For extra credit, have the students engage with the sources and explain the principles to them. The script might go like this:
</p>
<blockquote>
<p>
Dear Mr. Jones,
</p>
<p>
We&#8217;re students at the Jefferson Middle School, and we&#8217;re working on a class project to improve the amount and quality of online event information for our community. We noticed that the following information is available on your website: [EXAMPLES].
</p>
<p>
However, these events aren&#8217;t published in a form that enables them to show up automatically elsewhere &#8212; for example, on the Herald&#8217;s site, or the Chamber of Commerce site, or on people&#8217;s personal calendars. To show how that can work, we have reformulated your information as a data feed. You can see it merged together with other data feeds here: [EXAMPLE].
</p>
<p>
This is just a demonstration. We&#8217;re not the appropriate source for your data, you are. As part of our class project, we&#8217;re reaching out to organizations like yours to show them how they can publish their own event information in two ways: as text for people to read, and also as data for computers to process and for networks to syndicate.
</p>
<p>
We know that sounds complicated, but it&#8217;s really just a way of applying the ordinary calendar software that you probably already have and use. May we contact the person in your organization who&#8217;s responsible for the events page on your website, and make a presentation about how you could be publishing event information in a more useful way?
</p>
<p>
Sincerely,
</p>
<p>
Kayla Smith, Tim Miller, Samantha Williams<br />
Jefferson Middle School Civic Data Project
</p>
</blockquote>
<p>
If you&#8217;re not a teacher yourself, but you know teachers who might like to try this project-based exercise in civic data gathering and computational thinking, by all means invite them to <a href="mailto:jonu@microsoft.com?subject=civic data project">contact me</a>. I&#8217;ll be happy to help set up the exercise, support it, and document the outcome.
</p>
<p></p>
<p><strong>Related:</strong></p>
<ul>
<li> <a href="http://radar.oreilly.com/2010/10/developing-intuitions-about-da.html">Developing intuitions about data</a></li>
<li> <a href="http://radar.oreilly.com/2010/09/the-principle-of-indirection.html">The principle of indirection</a></li>
<li> <a href="http://radar.oreilly.com/2010/09/personal-data-stores-and-pubsu.html">Personal data stores and pub/sub networks</a></li>
<li> <a href="http://radar.oreilly.com/tag/elmcity">See all Radar elmcity stories</a></li>
<li> <a href="http://answers.oreilly.com/tag/elmcity">See all Answers elmcity stories</a></li>
</ul>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://radar.oreilly.com/2010/10/a-lesson-in-civics-public-data.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Developing intuitions about data</title>
		<link>http://radar.oreilly.com/2010/10/developing-intuitions-about-da.html</link>
		<comments>http://radar.oreilly.com/2010/10/developing-intuitions-about-da.html#comments</comments>
		<pubDate>Thu, 07 Oct 2010 20:00:00 +0000</pubDate>
		<dc:creator>Jon Udell</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[@home]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[education]]></category>
		<category><![CDATA[elmcity]]></category>

		<guid isPermaLink="false">http://blogs.oreilly.com/radar/2010/10/developing-intuitions-about-da.html</guid>
		<description><![CDATA[Some kinds of computer files have different properties than others, and thus serve different purposes. Structured representation of data is one such property. If we are trying to put data onto the web, and if we want others to have the use of that data, and if we hope it will flow reliably through networks to all the places where it&apos;s needed, then we ought to consider how the files we choose to publish do, or don&apos;t, respect that property.  ]]></description>
				<content:encoded><![CDATA[<p>
In <a href="http://radar.oreilly.com/2010/08/the-laws-of-information-chemis.html">The laws of information chemistry</a> I mentioned that my local high school uses a <a href="http://keene.k12.nh.us/documents/Weekly_Calendar.pdf">PDF file</a> to publish the school&#8217;s calendar of events. Let&#8217;s look at some different ways to represent the calendar entries for Oct 6, 2010. First I&#8217;ll divide these representations into two major categories: &#8220;What People See,&#8221; and &#8220;What Computers See.&#8221; Then I&#8217;ll discuss how the various formats serve various purposes.
</p>
</p>
<h2>Category 1: What People See</h2>
</p>
<p>
Here&#8217;s a piece of the PDF file for the week of Oct 4, 2010.
</p>
<div style="width: 573px;height: auto;padding: 10px;margin: 15px 0 15px 0;border: 1px solid #ddd;font-style: italic;text-align: left"><a href="http://jonudell.net/images/khs-weekly-pdf.png" target="_blank"><img src="http://jonudell.net/images/khs-weekly-pdf.png" width="573" border="0" alt="How the PDF looks to a person" style="margin-bottom: 15px"></a></p>
<p style="width: 573px;border-top: 1px solid #ddd;padding: 5px 0 0 0;text-align: left;font-style: italic">Fig. 1a: How the PDF looks to a person</p>
</div>
<p>
And here&#8217;s how the same entries might look in Google Calendar (or in any other calendar program).
</p>
<div style="width: 573px;height: auto;padding: 10px;margin: 15px 0 15px 0;border: 1px solid #ddd;font-style: italic;text-align: left">
<a href="http://jonudell.net/images/khs-weekly-gcal.png" target="_blank"><img width="573" src="http://jonudell.net/images/khs-weekly-gcal.png" style="margin-bottom: 15px"></a></p>
<p style="width: 573px;border-top: 1px solid #ddd;padding: 5px 0 0 0;text-align: left;font-style: italic">Fig. 1b: How the calendar looks to a person</div>
</p>
<h2>Category 2: What Computers See</h2>
</p>
<p>
The PDF file describes fonts and layout in a highly structured way. But the calendar&#8217;s data &#8212; dates, times, descriptions &#8212; only lives in free-form text. Computers use it to enable people to read or print that text.
</p>
<div style="width: 573px;border: 1px solid #ddd;padding: 10px;margin-bottom: 15px">
<p>10/6</p>
<p>
-Junior class NECAP testing info. Meeting block 4 (aud.)<br />
-Rain date for AP Env. Sci. trip to Monadnock 7:30 am-3 pm (Davenson/Sintros)<br />
-Field trip: Physics to Arnone&#8217;s 7:40-11 a.m. (Lybarger/Romano) List will be sent. <br />
-Senior workshop: &#8220;Tips &amp; tricks for writing your college essay 8:05-8:45 &amp; 1:200-2:02 (GCR) <br />
-New teacher workshop 2:15-3:00 p.m. (PCR) &#8220;Guidance &amp; Special Ed. Responsibilities&#8221;
</p>
<p style="width: 573px;border-top: 1px solid #ddd;padding: 5px 0 0 0;text-align: left;font-style: italic">Fig. 2a: How the data in the PDF file looks to a computer</p>
</div>
<p>
When your browser renders the calendar, it sees a mixture of HTML and JavaScript. Computers use that mixture to enable people to read, print, and also interact with the text.
</p>
<pre>
<span>&lt;</span>TR class<span>=</span><span>"</span><span>lv-row lv-newdate lv-firstevent lv-alt</span><span>"</span><span>&gt;</span>
<span>
&lt;</span>TH class<span>=</span>lv<span>-</span>datecell rowSpan<span>=</span><span>5</span><span>&gt;</span><span>&lt;</span>A class<span>=</span>lv<span>-</span>datelink
href<span>=</span><span>"</span><span>javascript:void(Vaa('20101006'))</span><span>"</span><span>&gt;</span>Wed Oct <span>6</span><span>&lt;</span><span>/</span>A<span>&gt;</span><span>&lt;</span><span>/</span>TH<span>&gt;</span>

<span>&lt;</span>TD class<span>=</span><span>"</span><span>lv-eventcell lv-status</span><span>"</span><span>&gt;</span> <span>&lt;</span><span>/</span>TD<span>&gt;</span>

<span>&lt;</span>TD class<span>=</span><span>"</span><span>lv-eventcell lv-time</span><span>"</span><span>&gt;</span><span>&lt;</span>SPAN class<span>=</span>lv<span>-</span>event<span>-</span>time
onmousedown<span>=</span><span>"</span><span>Waa(event,'listview','YzFmYT...b2tAZw','20101006');return false;</span><span>"</span><span>&gt;</span>All
day<span>&lt;</span><span>/</span>SPAN<span>&gt;</span><span>&lt;</span><span>/</span>TD<span>&gt;</span>

<span>&lt;</span>TD class<span>=</span><span>"</span><span>lv-eventcell lv-titlecell</span><span>"</span><span>&gt;</span>
<span>&lt;</span>DIV id<span>=</span>listviewzYzFmYT<span>.</span><span>.</span><span>.</span>b2tAZw20101006 class<span>=</span>lv<span>-</span>zippy
onmousedown<span>=</span><span>"</span><span>Waa(event,'listview','YzFmYT...b2tAZw','20101006');return false;</span><span>"</span><span>&gt;</span><span>&lt;</span><span>/</span>DIV<span>&gt;</span>

<span>&lt;</span>DIV class<span>=</span>lv<span>-</span>event<span>-</span>title<span>-</span>line<span>&gt;</span><span>&lt;</span>A style<span>=</span><span>"</span><span>COLOR: #1f753c</span><span>"</span> class<span>=</span>lv<span>-</span>event<span>-</span>title
onmousedown<span>=</span><span>"</span><span>Waa(event,'listview','YzFmYT...b2tAZw','20101006');return false;</span><span>"</span>
href<span>=</span><span>"</span><span>javascript:void(0)</span><span>"</span><span>&gt;</span><span>-</span>Junior class NECAP testing info<span>.</span> Meeting block <span>4
</span> <span>&lt;</span>SPAN dir<span>=</span>ltr<span>&gt;</span><span>(</span>aud<span>.</span><span>)</span><span>&lt;</span><span>/</span>SPAN<span>&gt;</span><span>&lt;</span><span>/</span>A<span>&gt;</span> <span>&lt;</span><span>/</span>DIV<span>&gt;</span>
</pre>
<p style="width: 600px;border-top: 1px solid #ddd;padding: 5px 0 0 0;text-align: left;font-style: italic;margin-bottom: 15px">Fig. 2b: How the HTML looks to a computer</p>
<p>
A calendar application or service that knows how use a standard format called iCalendar will receive a structured representation of the data. It relies on that structure to identify, recombine, and exchange the dates, times, and descriptions.
</p>
<div style="width: 590px;border: 1px solid #ddd;padding: 10px;margin-bottom: 15px">
<p>BEGIN:VCALENDAR<br />
PRODID:-//Google Inc//Google Calendar 70.9054//EN<br />
VERSION:2.0<br />
BEGIN:VEVENT<br />
DTSTART:20101006T113000Z<br />
DTEND:20101006T190000Z<br />
DTSTAMP:20101005T172506Z<br />
UID:bccvmn5aooodokincjbgl8crc0@google.com<br />
CREATED:20101005T161914Z<br />
DESCRIPTION:<br />
LOCATION:<br />
SUMMARY:-Rain date for AP Env. Sci. trip to Monadnock 7:30 am-3 pm (Davenso<br />
 n/Sintros)<br />
END:VEVENT</p>
<p style="width: 590;border-top: 1px solid #ddd;padding: 5px 0 0 0;text-align: left;font-style: italic">Fig. 2c: How the iCalendar feed looks</p>
</div>
<p>
If a <a href="http://tools.ietf.org/html/draft-daboo-et-al-icalendar-in-xml-06">proposed format called xCalendar</a> is approved as a standard, and is widely adopted by calendar applications and services, then calendar applications or services might also use that format to identify, recombine, and exchange dates, times, and descriptions.
</p>
<pre>
<span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>icalendar</span> <span style='color:#666616'>xmlns</span><span style='color:#808030'>=</span><span style='color:#0000e6'>"</span><span style='color:#666616'>urn</span><span style='color:#800080'>:</span><span style='color:#40015a'>ietf:params:xml:ns:icalendar-2.0</span><span style='color:#0000e6'>"</span><span style='color:#a65700'>&gt;</span>
 <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>vcalendar</span><span style='color:#a65700'>&gt;</span>
  <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>properties</span><span style='color:#a65700'>&gt;</span>
   <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>prodid</span><span style='color:#a65700'>&gt;</span>
    <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>text</span><span style='color:#a65700'>&gt;</span>-//Google Inc//Google Calendar 70.9054//EN<span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>text</span><span style='color:#a65700'>&gt;</span>
   <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>prodid</span><span style='color:#a65700'>&gt;</span>
   <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>version</span><span style='color:#a65700'>&gt;</span>
    <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>text</span><span style='color:#a65700'>&gt;</span>2.0<span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>text</span><span style='color:#a65700'>&gt;</span>
   <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>version</span><span style='color:#a65700'>&gt;</span>
  <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>properties</span><span style='color:#a65700'>&gt;</span>
  <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>components</span><span style='color:#a65700'>&gt;</span>
   <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>vevent</span><span style='color:#a65700'>&gt;</span>
    <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>properties</span><span style='color:#a65700'>&gt;</span>
     <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>dtstamp</span><span style='color:#a65700'>&gt;</span>20101005T172506Z<span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>dtstamp</span><span style='color:#a65700'>&gt;</span>
     <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>dtstart</span><span style='color:#a65700'>&gt;</span>20101006T113000Z<span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>dtstart</span><span style='color:#a65700'>&gt;</span>
     <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>dtend</span><span style='color:#a65700'>&gt;</span>20101006T190000Z<span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>dtend</span><span style='color:#a65700'>&gt;</span>
     <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>uid</span><span style='color:#a65700'>&gt;</span>
     <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>text</span><span style='color:#a65700'>&gt;</span>bccvmn5aooodokincjbgl8crc0@google.com<span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>text</span><span style='color:#a65700'>&gt;</span>
     <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>uid</span><span style='color:#a65700'>&gt;</span>
     <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>summary</span><span style='color:#a65700'>&gt;</span>
     <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>text</span><span style='color:#a65700'>&gt;</span>-Rain date for AP Env. Sci. trip to Monadnock 7:30 am-3 pm
(Davenson/SintrosEvent #2<span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>text</span><span style='color:#a65700'>&gt;</span>
     <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>summary</span><span style='color:#a65700'>&gt;</span>
    <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>properties</span><span style='color:#a65700'>&gt;</span>
   <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>vevent</span><span style='color:#a65700'>&gt;</span>
  <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>components</span><span style='color:#a65700'>&gt;</span>
 <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>vcalendar</span><span style='color:#a65700'>&gt;</span>
<span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>icalendar</span><span style='color:#a65700'>&gt;</span>
</pre>
<p style="width: 600px;border-top: 1px solid #ddd;padding: 5px 0 0 0;text-align: left;font-style: italic;margin-bottom: 15px">Fig. 2d: How an xCalendar feed might look</p>
<p>
Note that Fig. 2c (iCalendar) and Fig 2d (xCalendar) look very different. The iCalendar format uses lines of plain text to represent name:value pairs. The xCalendar format use a package of nested XML entities to represent the same data. Technical experts can, and do, endlessly debate the pros and cons of these different approaches. But for our purposes here, the key observations are:
</p>
<ul>
<li>
Fig. 2c and Fig. 2d contain the same data</p>
<li>
Computers can reliably extract that data</p>
<li>
Computers can transform either format into the other without loss of fidelity</p>
<li>
Computers can also transform either format into one that&#8217;s more directly useful to people &#8212; e.g., HTML or PDF
</ul>
<p>
It&#8217;s also worth noting that this simple name:value technique, which has been the Internet calendar standard for over a decade, is broadly useful. Curators of <a href="http://elmcity.cloudapp.net">elmcity calendar hubs</a>, for example, follow a <a href="http://radar.oreilly.com/2010/08/the-power-of-informal-contract.html">convention</a> for representing name:value pairs as tags, attached to Delicious bookmarks, that have the form name=value. A similar convention enables any calendar event, made by any calendar program, to specify the URL for the event and the categories that it belongs to. In this week&#8217;s companion article on <a href="http://answers.oreilly.com/topic/2124-how-to-parse-keyvalue-pairs-in-c/">answers.oreilly.com</a> I show how to extract these name:value pairs from free text.
</p>
</p>
<h2>A taxonomy of representations and purposes</h2>
</p>
<p>
Let&#8217;s chart these representations and arrange them according to purpose.
</p>
<table style="border: none;border-collapse:collapse;margin-bottom:20px;width:600">
<tbody>
<tr style="background: #ddd">
<th align="center">What people see</th>
<th align="center">Why?</th>
<th align="center">What computers see</th>
<th align="center">Why?</th>
</tr>
<tr>
<td colspan="4">
<p style="width: 100%;margin: 5px 0 5px 0;border-top: 1px solid #fff"></td>
</tr>
<tr>
<td style="vertical-align:middle;border-style:none;padding:10px">
<img style="margin:auto;border-style:solid;border-width:thin" src="http://jonudell.net/images/khs-weekly-pdf-icon.png"></p>
<div style="text-align:center;font-style:italic;margin: 5px 0 0 0">Fig. 1a: pdf</div>
</td>
<td style="vertical-align:middle;border-style:none;padding:10px;width:100px">
To view and print
</td>
<td style="vertical-align:middle;width:200;border-width:1px;padding:10px">
<img style="margin:auto;border-style:solid;border-width:thin" src="http://jonudell.net/images/khs-weekly-pdf-as-text-icon.png"></p>
<div style="text-align:center;font-style:italic;margin: 5px 0 0 0">Fig 2a: pdf</div>
</td>
<td style="vertical-align:middle;border-style:none;padding:10px;width:100px">
To enable people to view and and print
</td>
</tr>
<tr>
<td colspan="4">
<p style="width: 100%;margin: 10px 0 10px 0;border-top: 1px solid #ddd"></td>
</tr>
<tr>
<td style="vertical-align:middle;border-width:1px;padding:10px">
<img style="border-style:solid;border-width:thin" src="http://jonudell.net/images/khs-weekly-gcal-icon.png"></p>
<div style="text-align:center;font-style:italic;margin: 5px 0 0 0">Fig. 1b: html</div>
</td>
<td style="vertical-align:middle;border-style:none;padding:10px;width:100px">
To view, print, and interact
</td>
<td style="vertical-align:middle;border-width:1px;padding:10px">
<img style="margin:auto;border-style:solid;border-width:thin" src="http://jonudell.net/images/khs-weekly-gcal-as-html-icon.png"></p>
<div style="text-align:center;font-style:italic;margin: 5px 0 0 0">Fig 2b: html</div>
</td>
<td style="vertical-align:middle;border-style:none;padding:10px;width:100px">
To enable people to view, print, and interact
</td>
</tr>
<tr>
<td colspan="4">
<p style="width: 100%;margin: 10px 0 10px 0;border-top: 1px solid #ddd"></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td style="border-width:1px;padding:10px">
<img style="margin:auto;border-style:solid;border-width:thin" src="http://jonudell.net/images/khs-weekly-as-ical-icon.png"></p>
<div style="text-align:center;font-style:italic;margin: 5px 0 0 0">Fig 2c: iCalendar</div>
</td>
<td style="vertical-align:middle;border-style:none;padding:10px;width:100px">
To enable data to flow reliably and recombine easily
</td>
</tr>
<tr>
<td colspan="4">
<p style="width: 100%;margin: 10px 0 10px 0;border-top: 1px solid #ddd"></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td style="border-width:1px;padding:10px">
<img style="margin:auto;border-style:solid;border-width:thin" src="http://jonudell.net/images/khs-weekly-as-xcal-icon.png"></p>
<div style="text-align:center;font-style:italic;margin: 5px 0 0 0">Fig 2d: xCalendar</div>
</td>
<td style="vertical-align:middle;border-style:none;padding:10px;width:100px">
To enable data to flow reliably and recombine easily
</td>
</tr>
</tbody>
</table>
<p>
To most people, all four items in the What Computers See column are roughly equivalent. They&#8217;re understood to be computer files of one sort or another. But when computers use these files on our behalf, they use them in very different ways. The first two uses enable people to read, print, and interact online. The latter two enable computers to exchange data without loss of fidelity, so that other people can read, print, and interact online.
</p>
<p>
The laws of information chemistry say that if we want to exchange data, we must provide it in a format that&#8217;s useful for that purpose. In this example the PDF and HTML formats aren&#8217;t; the iCalendar and xCalendar formats are. To most people it&#8217;s not obvious why that&#8217;s so. Our brains are such powerful pattern recognizers, and we know so much about the world in which the patterns occur, that we can look at Fig. 2a and see that the text clearly implies a structure involving dates, times, titles, and descriptions. Computers can&#8217;t do that so easily or so well.
</p>
<p>
Computers are, of course, getting smarter all the time. Google Calendar&#8217;s Quick Add feature is a perfect example. I used it to create the example shown in Fig. 1b, and it did a great job of parsing out the times and titles of the events. But that was only possible because I inserted the events, one at time, into a container that Google Calendar understood to represent Wed Oct 6. It wouldn&#8217;t be able to import the original free-form text that was the original source for the PDF file. No other calendar program could either.
</p>
</p>
<h2>The surprising difficulty of structured information</h2>
</p>
<p>
It&#8217;s counter-intuitive that computers don&#8217;t recognize structure easily or reliably. But so are many other things. For example:
</p>
<blockquote><p>You have $100. It grows by 25%, then shrinks by 25%. Do you end up with more or less?
</p>
</blockquote>
<p>
You can live a long time without ever developing an intuition that the final amount is less. And you may be profoundly harmed because you lack that intuition. If you have it, you most likely didn&#8217;t acquire it all by yourself. Either <a title="Khan Academy: Growing by a percentage" href="http://www.youtube.com/watch?v=X2jVap1YgwI">somebody taught it to you</a>, or nobody did.
</p>
<p>
Although our sample PDF file contains no structured representation of the events that it exists to convey, it does contain some other structured data:
</p>
<table style="margin: 15px 0 15px 0">
<tr>
<td style="border: 1px solid #ddd">Title</td>
<td style="border: 1px solid #ddd">Microsoft Word &#8211; weekly draft</td>
</tr>
<tr>
<td style="border: 1px solid #ddd">Made_by</td>
<td style="border: 1px solid #ddd">Word</td>
</tr>
<tr>
<td style="border: 1px solid #ddd">Created_with</td>
<td style="border: 1px solid #ddd">Mac OS X 10.4.11 Quartz PDFContext</td>
</tr>
</table>
<p>
From this we learn that that calendar originates in Microsoft Word. Why Word instead of a calendar program? Available cloud-based applications include Google Calendar and Hotmail Calendar. On the Mac desktop where the document originated, there&#8217;s Apple iCal. If one of these alternatives were even considered, a number of valid concerns would arise:
</p>
<ol>
<li> It&#8217;s cumbersome to enter data into a calendar program&#8217;s input fields; it&#8217;s much easier and quicker to type into a Word table</li>
<li>
The document doesn&#8217;t only contain structured data, it is also a textual narrative. Calendar programs don&#8217;t flexibly accomodate narrative.</li>
<li>
The webmaster knows how to post a PDF, but wouldn&#8217;t know what to do with dual outputs from a calendar program (one for humans to read, another for computers to process).</li>
</ol>
<p>
And if alternatives were considered, we could discuss those concerns:
</p>
<ol>
<li> Yes, it is more cumbersome to enter data into a calendar program. But do we want students and teachers and parents to be able to pull these events into their own calendars? Do we want the events to also be able to flow automatically to community-wide calendars? If so, these are big payoffs for a fairly small investment of extra effort. And by doing things this way, we&#8217;ll demonstrate the 21st-century skills that we say our students need to learn and apply.</li>
<li>Yes, it&#8217;s true that calendar programs don&#8217;t accomodate narrative. But we&#8217;re publishing to the web. We can use documents and links to build a context that includes: the calendar in an HTML format that people can read, print, and interact with; the calendar in another format that can syndicate to other calendars; narrative related to the calendar.</li>
<li>
Yes, but the webmaster needn&#8217;t even be tasked with this chore. Various tools &#8212; some that we already have and use, others that are freely available &#8212; enable us to publish the desired formats ourselves. </li>
</ol>
<p>
Since alternatives are almost never considered, though, the ensuing discussion almost never happens. Why not? Key intuitions are missing. Some kinds of computer files have different properties than others, and thus serve different purposes. Structured representation of data is one such property. If we are trying to put data onto the web, and if we want others to have the use of that data, and if we hope it will flow reliably through networks to all the places where it&#8217;s needed, then we ought to consider how the files we choose to publish do, or don&#8217;t, respect that property.
</p>
<p>
Nobody is born knowing this stuff. We need to learn it. Schools aren&#8217;t the only <a href="http://www.khanacademy.org/">source of instruction</a>. But they ought to teach core principles that govern the emerging web of people, data, and services. And they ought to cultivate intuitions about when, why, and how to apply those principles.
</p>
<p></p>
<p><strong>Related:</strong></p>
<ul>
<li> <a href="http://answers.oreilly.com/topic/2124-how-to-parse-keyvalue-pairs-in-c/">How to parse key/value pairs in C#</a></li>
<li> <a href="http://radar.oreilly.com/2010/08/the-laws-of-information-chemis.html">The laws of information chemistry</a></li>
<li><a href="http://radar.oreilly.com/tag/elmcity">See all Radar elmcity stories</a></li>
<li><a href="http://answers.oreilly.com/tag/elmcity">See all Answers elmcity stories</a></li>
</ul>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://radar.oreilly.com/2010/10/developing-intuitions-about-da.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>The principle of indirection</title>
		<link>http://radar.oreilly.com/2010/09/the-principle-of-indirection.html</link>
		<comments>http://radar.oreilly.com/2010/09/the-principle-of-indirection.html#comments</comments>
		<pubDate>Thu, 30 Sep 2010 15:00:00 +0000</pubDate>
		<dc:creator>Jon Udell</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[@home]]></category>
		<category><![CDATA[education]]></category>
		<category><![CDATA[elmcity]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blogs.oreilly.com/radar/2010/09/the-principle-of-indirection.html</guid>
		<description><![CDATA[Networks of people and data are governed by principles as basic as the commutative law of addition and multiplication. Indirection is one of those principles. ]]></description>
				<content:encoded><![CDATA[<p>
Programmers learn, early on, that there&#8217;s a difference between values stored in memory and pointers to (or references to, or addresses of) values stored in memory. The key distinction emerges when these things move around within programs, and it is captured by a pair of phrases: <em>pass by value</em> and <em>pass by reference</em>.</p>
<p>
Suppose the value stored in some memory location represents the number 6. In a pass-by-value regime, 6 is copied from one part of the program to another part of the program. If the value stored in the original memory location then becomes 8, those parts of the program that got copies of 6 still represent 6. The 6 was &#8220;passed by value.&#8221;
</p>
<p>
In a pass-by-reference regime, though, what&#8217;s copied from one part of the program to another isn&#8217;t the value, 6, but rather a reference, or pointer, to the memory location where 6 is stored. In this case, if the value stored in that memory location becomes 8, the parts of the program that received references to 6&#8242;s memory location now represent 8 too. The 6 was &#8220;passed by reference&#8221; and, by way of that reference, has become 8.
</p>
<p>
It used to be that nobody except programmers had to appreciate this subtle distinction. But along came the web, and now everybody does. Why? Another name for a pointer, or a reference, or an address, is a hyperlink. We use hyperlinks every day. But most people don&#8217;t use them as well as they could, because most people don&#8217;t see &#8220;pass by value&#8221; and &#8220;pass by reference&#8221; at work in our everyday online discourse.
</p>
<p>
Here&#8217;s a quiz that looks easy, and should be, but turns out to be quite hard for most people. Somebody asks you: &#8220;What information do you have about topic X?&#8221; It&#8217;s a multiple-choice quiz. There are two ways to answer:
</p>
<p>
1. Make a list of things, and send a copy of the list.
</p>
<p>
2. Make a list of things, and send a reference to the list.
</p>
<p>
Most people choose 1 &#8212; that is, pass by value. The value they send, in this case, is a list of things we can describe using words, phrases, sentences, paragraphs, URLs. The list can be printed on paper and delivered by hand. Or it can be typed and sent as an email or text message. Either way, what&#8217;s sent is a copy of the list. The original list remains in situ. When it changes, over time, those changes don&#8217;t propagate through the network of copies.
</p>
<p>
The minority who choose 2 &#8212; that is, to pass by reference &#8212; achieve the same two goals as do the pass-by-value majority. One goal is to send a social signal: &#8220;Here is information I want to give you.&#8221; The other is to convey the actual information. You get these same two effects no matter whether you pass by value or pass by reference.
</p>
<p>
When I send you a link to the list, though, instead of a copy of the list, I connect you to a live list that provides four extra benefits:
</p>
<p>
1. I am the authoritative source for the list. It lives at a location in memory (that is, at a URL in the cloud) that&#8217;s under my control, and is bound to my identity.
</p>
<p>
2. The list is always up-to-date. When I add items, you (and everyone else) will see a freshly-updated list when you follow the link I sent you.
</p>
<p>
3. The list is social. If other people cite my link, I can find their citations and connect with them.
</p>
<p>
4. The list is collaborative. Suppose you want to extend my list. In a pass-by-value world, the best you can do is add to the copy I sent you. I won&#8217;t see what you&#8217;ve added, and neither will anybody else. In a pass-by-reference world, though, we can both keep our own lists, publish references to them, and then produce a merged list by combining the referents.
</p>
<p>
(Of course there&#8217;s no free lunch. If you depend on the link and it fails, we&#8217;re out of luck. This week&#8217;s companion piece at <a href="http://answers.oreilly.com/tag/elmcity">answers.oreilly.com</a> explores one way to handle transient failure.)
</p>
<p>
The fourth benefit, the collaborative one, is rather abstract. So let&#8217;s nail it down to a common real-world scenario. Suppose you&#8217;re running a newspaper, or a hyperlocal website, or some other nexus for community information. And suppose I am a source for that information. Almost always, as things stand today, you&#8217;ll ask me to pass information to you by value. If I&#8217;m promoting a council meeting, or a church supper, or a riverside cleanup, or an open mic night, you&#8217;ll expect me to inform you about my event&#8217;s date, time, and description by sending you an email, or by visiting your website and typing the data into a form. Either way, it boils down to: &#8220;Give me a copy of your information.&#8221;
</p>
<p>
Before 1994 there was no alternative. My original, whether it was a piece of paper in my drawer or a file on my computer&#8217;s hard drive, wasn&#8217;t immediately available to you. It could only be passed by value. Since 1994 we&#8217;ve had an exciting new option, albeit one the world mostly hasn&#8217;t yet caught up to. Now the original can reside on the web, at a permanent and well-known address within its vast memory. And it can be passed by reference.
</p>
<p>
So providers of information about community events &#8212; the city government, the church, the environmental group, the musicians &#8212; can post references to information about their events. Those references can appear wherever the providers choose to establish their online identities: on conventional websites, on blogs, on Twitter, on Facebook. Purveyors of that information &#8212; newspapers, hyperlocal websites, other nexuses &#8212; can use those references to create views that join many sources, from many perspectives, for many purposes.
</p>
<p>
That&#8217;s still a notch too abstract so let&#8217;s make it even more concrete. City governments provide calendars of council and committee meetings. Local newspapers purvey those calendars. Citizens use them. In the prevailing pass-by-value model, the city gives copies of its event information to the newspaper, which in turn makes copies to give to citizens, who in turn may need to make more copies to pass around. Where&#8217;s the original? In a document on a computer at city hall.
</p>
<p>
In a pass-by-reference world, the original resides in the cloud at a unique URL. That URL refers to a list of events. And each item on the list &#8212; each event on the calendar &#8212; has its own URL. The city publishes its calendar on its own website, in HTML, so citizens can read it there. But instead of giving the newspaper copies of event information, it gives the newspaper a link to the calendar&#8217;s feed. The newspaper, by subscribing to the link, ensures that the information it receives from the city is as timely, accurate, and complete as the city cares to make it. Of course the newspaper still has to make copies for its print version. But online, along with the subset of facts about each event that it chooses to relay, it provides the event&#8217;s URL. Citizens can click through the event URL to see the whole description, and to check for updates. Citizens can also subscribe directly to the city&#8217;s calendar URL, and thus merge its stream of civic event data with their own streams of personal event data.
</p>
<p>
I&#8217;ve yet to convince a local newspaper to adopt this model. It could be that they fear disintermediation. After all, if citizens can subscribe directly to calendar feeds, why will they need the newspaper to tell them about what&#8217;s going on? But I don&#8217;t think that&#8217;s the real problem. There will always be community attention hubs. Newspapers, or whatever they evolve into, will continue to occupy that niche. In their role as purveyors of community information, though, pass-by-value makes them less effective than pass-by-reference could.
</p>
<p>
The real problem, I think, is that if you&#8217;re a newspaper editor, or a city official, or a citizen, pass-by-reference just isn&#8217;t part of your mental toolkit. We teach the principle of indirection to programmers. But until recently there was no obvious need to teach it to everybody else, so we don&#8217;t.
</p>
<p>
I&#8217;ve noticed that educators do, nowadays, talk a lot about about systems thinking and digital literacy and 21st-century skills. Good! Now let&#8217;s codify what we mean. Networks of people and data are governed by principles as basic as the commutative law of addition and multiplication. Indirection is one of those principles. Others include<a href="http://radar.oreilly.com/2010/09/personal-data-stores-and-pubsu.html"> pub/sub syndication</a>, universal naming, and data structure. First we need to write them down. Then we need to figure out how to teach them.
</p>
<p></p>
<p><strong>Related:</strong></p>
<ul>
<li><a href="http://radar.oreilly.com/2010/08/the-laws-of-information-chemis.html">The laws of information chemistry</a> </li>
<li> <a href="http://radar.oreilly.com/2010/09/personal-data-stores-and-pubsu.html">Personal data stores and pub/sub networks</a></li>
<li> <a href="http://radar.oreilly.com/tag/elmcity">See all Radar elmcity stories</a></li>
<li> <a href="http://answers.oreilly.com/tag/elmcity">See all Answers elmcity stories</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://radar.oreilly.com/2010/09/the-principle-of-indirection.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Personal data stores and pub/sub networks</title>
		<link>http://radar.oreilly.com/2010/09/personal-data-stores-and-pubsu.html</link>
		<comments>http://radar.oreilly.com/2010/09/personal-data-stores-and-pubsu.html#comments</comments>
		<pubDate>Wed, 22 Sep 2010 16:00:00 +0000</pubDate>
		<dc:creator>Jon Udell</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[@home]]></category>
		<category><![CDATA[calendar]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[elmcity]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[syndication]]></category>

		<guid isPermaLink="false">http://blogs.oreilly.com/radar/2010/09/personal-data-stores-and-pubsu.html</guid>
		<description><![CDATA[Most people and organizations think of the calendar information they push as text for people to read. Few realize it&apos;s also data networks can syndicate. When that mindset changes, a river of data will be unleashed. ]]></description>
				<content:encoded><![CDATA[<p>
The <a href="http://elmcity.cloudapp.net/">elmcity project</a> joins five streams of data about public calendar events. Four of them are well-known services: Facebook, EventBrite, Upcoming, and Eventful. They all work the same way. You sign up for a service, you post your events there, other people can go there to find out about your events. What they find, when they go there, are copies of your event data. If you want to promote an event in more than one place, you have to push a copy to each place. If you change the time or day of an event, you have to revisit all those places and push new copies to each.
</p>
<p>
The fifth stream works differently. It&#8217;s a loosely-coupled network of publishers and subscribers. To join it you post events once to your own website, blog, or online calendar, in a way that yields two complementary outputs. For people, you offer HTML files that can be read and printed. For mechanized web services like elmcity, you offer iCalendar feeds that can be aggregated and syndicated. If you want to promote an event in more than one place, you ask other services to subscribe to your feed. If you change the time or day of the event, every subscriber sees the change.
</p>
<p>
The first and best example of a decentralized pub/sub network is the blogosphere. My original blogging tool, <a href="http://radio.userland.com/">Radio UserLand</a>, embodied the pub/sub pattern. It made everything you wrote automatically available in two ways: as HTML for people to read, and as RSS for machines to process. What&#8217;s more, Radio UserLand didn&#8217;t just produce  RSS feeds that other services could read and aggregate. It was itself an aggregator that pointed the way toward what became a vibrant ecosystem of applications &#8212; and services &#8212; that knew how to merge RSS streams. In that network the feeds we published flowed freely, and appeared in many contexts. But they always remained tethered to original sources that we stamped with our identities, hosted wherever we liked, and controlled ourselves. Every RSS feed that was published, no matter where it was published, contributed to a global pool of RSS feeds. Any aggregator could create a view of the blogosphere by merging a set of feeds, chosen from the global pool, based on subject, author, place, time, or combinations of these selectors.
</p>
<p>
Now social streams have largely eclipsed RSS readers, and the feed reading service I&#8217;ve used for years &#8212; <a href="http://www.bloglines.com/">Bloglines</a> &#8212; will soon go dark. Dave Winer thinks the RSS ecosystem could be <a href="http://scripting.com/stories/2010/09/13/howToRebootRss.html">rebooted</a>, and argues for centralized subscription handling on the next turn of the crank. Of course definitions tend to blur when we talk about centralized versus decentralized services. Consider <a href="http://friendfeed.com/">FriendFeed</a>. It&#8217;s centralized in the sense that a single provider offers the service. But it can be used to create many RSS hubs that merge many streams for many purposes. In <a href="http://radar.oreilly.com/2010/08/the-power-of-informal-contract.html">The power of informal contracts</a> I showed how an <a href="http://friendfeed.com/elmcity">instance of FriendFeed</a> merges a particular set of RSS feeds to create a news service just for elmcity curators. The elmcity service itself has the same kind of dual nature. A single provider offers the service. But many curators can use it to spin up many event hubs, each tuned to a location or topic.
</p>
<p>
The early blogosphere proved that we could create and share many views drawn from the same pool of feeds. That&#8217;s one of the bedrock principles that I hope we&#8217;ll remember and carry forward to other pub/sub networks. Another principle is that we ought to control and syndicate our data. Radio UserLand, for example, was happy to host your blog, just as Twitter and Facebook are now happy to host your online social presence. But unlike Twitter and Facebook, Radio UserLand was just as happy to let you push your data to another host. To play in the syndication network your feed just had to exist &#8212; it didn&#8217;t matter where &#8212; and be known to one or more hubs.
</p>
<p>
This notion of a cloud-based personal data store is only now starting to come into focus. When I was groping for a term to describe it back in 2007 I came up with <a href="http://blog.jonudell.net/2007/05/22/hosted-lifebits/">hosted</a> <a href="http://blog.jonudell.net/2007/08/22/hosted-lifebits-scenarios/">lifebits</a>. More recently the <a href="http://www.internetidentityworkshop.com/">Internet Identity Workshop</a> gang have settled on <em>personal data store</em>, as recently described by <a href="http://www.identitywoman.net/vision-principles-for-the-personal-data-ecosystem">Kaliya Hamlin</a> and <a href="http://www.windley.com/archives/2010/09/pdx_principles.shtml">Phil Windley</a>. The acronym is variously PDS or PDX, where X, as Kaliya says, stands for &#8220;store, service, locker, bank, broker, vault, etc.&#8221; Phil elaborates:
</p>
<blockquote>
<p>The term itself is a problem. When you say &#8220;store&#8221; or &#8220;locker&#8221; people assume that this is a place to put things (not surprisingly). While there will certainly be data stored in the PDS, that really misses its primary purposes: acting as a broker for all the data you&#8217;ve got stored all over the place, and managing the metadata about that data. That is, it is a single place, but a place of indirection not storage. The PDS is the place where services that need access to your data will come for permission, metadata, and location.</p>
</blockquote>
<p>
The elmcity service aligns with that vision. If we require the calendar data for a city, town, or neighborhood to live in a single place of storage, we&#8217;ll never agree to use the same place. Thus the elmcity service merges streams from Facebook, EventBrite, Upcoming, and Eventful. But those streams are fed by people who put copies of their events into them, one event at at time, once per stream. What if we managed our public calendar data canonically, in personal (or organizational) data stores fed from our own preferred calendar applications? These data stores would in turn feed downstream hubs like Facebook, EventBrite, Upcoming, and Eventful, all of which could &#8212; although they currently don&#8217;t &#8212; receive and transmit such feeds. Other hubs, based on instances of the elmcity service or a similar system, would enable curators to create particular geographic or topical views.
</p>
<p>
I&#8217;ve identified a handful of <a href="http://www.delicious.com/judell/icalpub+howto">common calendar applications</a> that can publish calendar data at URLs accessible to any such hub, in a format (iCalendar) that enables automated processing. The short list includes Google Calendar, Outlook, Apple iCal, and Windows Live Calendar. But there are many others. Here&#8217;s the full list of producers as captured so far by the elmcity service:
</p>
<table style="margin-bottom:10px;width: 600px">
<tr>
<td style="padding:4;text-align:right;vertical-align:bottom"><b>feed producer</b></td>
<td style="padding:4;text-align:center"><b># of</br> feeds</b></td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//Google Inc//Google Calendar 70.9054//EN</td>
<td style="text-align:right;padding:4">151</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//Meetup Inc//RemoteApi//EN</td>
<td style="text-align:right;padding:4">14</td>
</tr>
<tr>
<td style="padding:4;text-align:right">unknown</td>
<td style="text-align:right;padding:4">14</td>
</tr>
<tr>
<td style="padding:4;text-align:right">iCalendar-Ruby</td>
<td style="text-align:right;padding:4">6</td>
</tr>
<tr>
<td style="padding:4;text-align:right">e-vanced event management system</td>
<td style="text-align:right;padding:4">6</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//DDay.iCal//NONSGML ddaysoftware.com//EN</td>
<td style="text-align:right;padding:4">5</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//Last.fm Limited Event Feeds//NONSGML//EN</td>
<td style="text-align:right;padding:4">4</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//openmikes.org/NONSGML openmikes.org//EN</td>
<td style="text-align:right;padding:4">3</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//CollegeNET Inc//NONSGML R25//EN</td>
<td style="text-align:right;padding:4">3</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//Drupal iCal API//EN</td>
<td style="text-align:right;padding:4">3</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//Microsoft Corporation//Windows Live Calendar//EN</td>
<td style="text-align:right;padding:4">3</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//Trumba Corporation//Trumba Calendar Services 0.11.6830//EN</td>
<td style="text-align:right;padding:4">2</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//herald-dispatch/calendar//NONSGML v1.0//EN</td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//WebCalendar-v1.1.2</td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">Zvents Ical</td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">Coldfusion8</td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//Intand Corporation//Tandem for Schools//EN</td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//strange bird labs//Drupal iCal API//EN</td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//SchoolCenter/NONSGML Calendar v9.0//EN</td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//blogTO//NONSGML Toronto Events V1.0//EN</td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//Events at Stanford//iCal4j 1.0//EN</td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//University of California\, Berkeley//UCB Events Calendar//EN </td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//EVDB//www.eventful.com//EN</td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">-//mySportSite Inc.//mySportSite//EN</td>
<td style="text-align:right;padding:4">1</td>
</tr>
<tr>
<td style="padding:4;text-align:right">Mobile Geographics Tides 3988 2010</td>
<td style="text-align:right;padding:4">1</td>
</tr>
</table>
<p>
Google Calendar dominates overwhelmingly, but the long tail hints at the variety of event sources that could feed into a calendar-oriented pub/sub network. How much of the total event flow comes by way of this assortment of iCalendar sources, as compared to centralized sources? Here&#8217;s the breakdown:
</p>
<p align="center">
<a title="click to enlarge" href="http://jonudell.net/images/elmcity_sources.png" target="_blank"><img style="border-width:thin;border-style:solid;border-color:black;width:600px" src="http://jonudell.net/images/elmcity_sources.png"></a><br /></br><br />
(<a title="click to enlarge" href="http://jonudell.net/images/elmcity_sources.png" target="_blank">Click to enlarge</a>)
</p>
<p>
It&#8217;s roughly half Eventful, a third Upcoming, a fifth iCalendar. There&#8217;s negligible flow from EventBrite, which focuses on big events. Likewise FaceBook where the focus, though it&#8217;s <a href="http://blog.jonudell.net/2010/05/07/facebook-is-now-an-elmcity-event-source/">evolving</a>, remains on group versus world visibility.
</p>
<p>
In a companion piece at <a href="http://answers.oreilly.com/topic/2083-how-to-visualize-an-azure-table-in-excel-using-odata/">O&#8217;Reilly Answers</a> I show how I made this visualization. It&#8217;s a nice example of another kind of pub/sub network, in this case one that&#8217;s enabled by the <a href="http://www.delicious.com/judell/odata">OData protocol</a>. For our purposes here, I just want to draw attention to the varying contributions made by the five streams to each of the hubs. The Eventful stream is strong almost everywhere. The Upcoming and iCalendar tributaries are only strong in some places. But where the iCalendar stream does flow powerfully, there&#8217;s a curator who has mined one or more rich veins of data from a school system, or a city government, or a newspaper. Today the vast majority of these organizations think of the calendar information they push as text for people to read. Few realize it is also data for networks to syndicate. When that mindset changes, a river of data will be unleashed.
</p>
<p></p>
<p><strong>Related:</strong></p>
<ul>
<li> <a href="http://radar.oreilly.com/2010/08/the-power-of-informal-contract.html">The power of informal contracts</a></li>
<li> <a href="http://radar.oreilly.com/2010/08/the-laws-of-information-chemis.html">The laws of information chemistry</a></li>
<li> <a href="http://radar.oreilly.com/tag/elmcity">See all Radar elmcity stories</a></li>
<li> <a href="http://answers.oreilly.com/tag/elmcity">See all Answers elmcity stories</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://radar.oreilly.com/2010/09/personal-data-stores-and-pubsu.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
