<?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>Dodgeball Cannon &#187; Ideas</title>
	<atom:link href="http://www.johntantalo.com/blog/category/ideas/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.johntantalo.com/blog</link>
	<description>It's not so much a time machine as it is my blog.</description>
	<lastBuildDate>Sun, 22 Jan 2012 14:10:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Paginating with Bookmarks in App Engine</title>
		<link>http://www.johntantalo.com/blog/paginating-with-bookmarks-in-app-engine/</link>
		<comments>http://www.johntantalo.com/blog/paginating-with-bookmarks-in-app-engine/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 22:57:57 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ideas]]></category>
		<category><![CDATA[Google App Engine]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=159</guid>
		<description><![CDATA[Let&#8217;s say we have a Google App Engine model with two fields, &#8220;x&#8221; and &#8220;y&#8221;, and all objects are distinct. We&#8217;d like to paginate with the sort order criteria &#8220;x ascending, y ascending&#8221;. For example, that index might look like this. While paginating, we need to know whether there is a &#8220;next page&#8221;, because we [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say we have a Google App Engine model with two fields, &#8220;x&#8221; and &#8220;y&#8221;, and all objects are distinct.</p>
<p>We&#8217;d like to paginate with the sort order criteria &#8220;x ascending, y ascending&#8221;. For example, that index might look like this.</p>
<p><a href="http://www.johntantalo.com/blog/wp-content/uploads/2011/09/example-data.png"><img src="http://www.johntantalo.com/blog/wp-content/uploads/2011/09/example-data.png" alt="" title="example-data" width="387" height="363" class="aligncenter size-full wp-image-160" /></a></p>
<p>While paginating, we need to know whether there is a &#8220;next page&#8221;, because we don&#8217;t want to return an empty page unless we have no objects.</p>
<p>To do this, we&#8217;ll look-ahead for the next item in our search. So, if the page size is 2, we&#8217;ll just fetch 3 items. That extra object will give us the necessary (x, y) coordinates we need to resume the search, that is, to fetch the next page. This object is called the &#8220;bookmark&#8221;.</p>
<p>Given the (x, y) bookmark, how do we fetch the next page? In index terms, we might construct a prefix string &#8220;/$x/$y/&#8221;, and return the next rows after that in our index. Unfortunately App Engine doesn&#8217;t give us a low-level interface like that, so we have to use filters.</p>
<p>What kind of filters? We want all objects greater than or equal to our given &#8220;x&#8221;. But, for objects with the same value as &#8220;x&#8221;, we have to skip those less than our given &#8220;y&#8221;, because we have already seen them. Clearly we will need filters on both &#8220;x&#8221; and &#8220;y&#8221;, but woe, App Engine insists that no more than one distinct field can have a filter expression per query.[1]</p>
<p><a href="https://plus.google.com/103651231634018158746">Ryan Barrett</a> observed that <a href="https://groups.google.com/d/topic/google-appengine/7lr73iDhPN4/discussion">for a search with n sorted fields, you will need n queries to resume the search from a bookmark</a>. In other words, you need one query for each field.</p>
<p>What does this look like? In our example, we have two sorted fields. To resume the search, the first query will fix &#8220;x&#8221; and filter on &#8220;y&#8221;, with &#8220;y ascending&#8221;. The second query will filter on &#8220;x&#8221; with &#8220;x ascending, y ascending&#8221;.</p>
<p>What would that look like on our example index?</p>
<p><a href="http://www.johntantalo.com/blog/wp-content/uploads/2011/09/queries.gif"><img src="http://www.johntantalo.com/blog/wp-content/uploads/2011/09/queries.gif" alt="" title="queries" width="388" height="364" class="aligncenter size-full wp-image-164" /></a></p>
<p>Each shaded region is one query, that is, one trip to the datastore. The green objects are the current page. The orange object is the next bookmark. The blue objects are the old pages.</p>
<p>The first query is on a fixed &#8220;x&#8221; and filters &#8220;y&#8221;. The second query resumes where the first left off, and filters on &#8220;x&#8221;. Since the sort orders are consistent with the filters, we obtain a consistent view of the index.</p>
<p>On the fourth search, we happen to get lucky and find our bookmark on the first query, so we can skip the second query.</p>
<h2>In general</h2>
<p>If you&#8217;re sorting on n fields {f<sub>0</sub>, f<sub>2</sub>, &#8230; f<sub>n-1</sub>} you will need n queries {q<sub>0</sub>, q<sub>1</sub>, &#8230; q<sub>n-1</sub>}.</p>
<p>Query q<sub>i</sub> will filter f<sub>n-i</sub> and fix fields {f<sub>0</sub>, &#8230; f<sub>n-i-1</sub>}.</p>
<p>For n=2, query q<sub>0</sub> filters f<sub>1</sub> and fixes f<sub>0</sub>. Query q<sub>1</sub> filters f<sub>0</sub>.</p>
<h2>Why don&#8217;t you use cursors you slob?</h2>
<p>Cursors are great! Except, they don&#8217;t immediately answer the question, &#8220;Do we have a next page?&#8221; If you don&#8217;t care then by all means use cursors, they&#8217;re much easier to use than bookmarks.</p>
<p>Cursors in App Engine can&#8217;t look-ahead. Instead, you have to fetch one object with the query&#8217;s next cursor, rather than fetching an extra object in the original query.</p>
<p>On the other hand, cursors are allowed to perform queries which users cannot. Cursors can perform the &#8220;prefix string&#8221; trick described above. So, a cursor can do in one query what takes us two or more.</p>
<p>So which should you use? That probably depends on how many fields you are sorting on. For a single field, I prefer the look-ahead technique, because it only requires one trip to the datastore. For two fields, either technique requires (at most) two trips, although cursors are usually simpler. For more than two fields, cursors easily win.</p>
<p>[1] This requirement exists to prevent users from requesting filters which the datastore cannot satisfy by scanning consecutive rows in an index. For example, the filters &#8220;x > 2 and y > 3&#8243; can specify non-consecutive rows of an index that sorts &#8220;x&#8221; and &#8220;y&#8221; ascendingly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/paginating-with-bookmarks-in-app-engine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Double-blind water study</title>
		<link>http://www.johntantalo.com/blog/double-blind-water-study/</link>
		<comments>http://www.johntantalo.com/blog/double-blind-water-study/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 23:00:32 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[science]]></category>
		<category><![CDATA[water]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/double-blind-water-study/</guid>
		<description><![CDATA[M and I performed a double-blind study of four kinds of water. Our preferences agreed, in order: purified water, filtered tap water, natural spring water, and unfiltered tap water. (I know the labels here don&#8217;t make sense. They were the first four Greek letters I could recall.)]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.johntantalo.com/blog/wp-content/uploads/2009/06/img_0184-300x225.jpg" alt="water test" title="water test" width="300" height="225" class="alignnone size-medium wp-image-43" /></p>
<p>M and I performed a double-blind study of four kinds of water. Our preferences agreed, in order: purified water, filtered tap water, natural spring water, and unfiltered tap water.</p>
<p>(I know the labels here don&#8217;t make sense. They were the first four Greek letters I could recall.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/double-blind-water-study/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vineyards sample hex and card</title>
		<link>http://www.johntantalo.com/blog/vineyards-sample-hex-and-card/</link>
		<comments>http://www.johntantalo.com/blog/vineyards-sample-hex-and-card/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 18:17:26 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[catan]]></category>
		<category><![CDATA[vineyards]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=40</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.johntantalo.com/blog/wp-content/uploads/2009/03/example1.jpg" alt="vineyards1" title="vineyards1" width="430" height="238" class="alignnone size-full wp-image-39" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/vineyards-sample-hex-and-card/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vineyards of Catan</title>
		<link>http://www.johntantalo.com/blog/vineyards-of-catan/</link>
		<comments>http://www.johntantalo.com/blog/vineyards-of-catan/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 19:37:21 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[catan]]></category>
		<category><![CDATA[vineyards]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=34</guid>
		<description><![CDATA[Working on a variation of Settlers of Catan called Vineyards of Catan. Mayfair Games has blank tiles and replacement card packs. Current plan is to print out vineyard tiles and wine cards on sticker paper to stick on the blank tiles and replacement cards. Progress updates to follow.]]></description>
			<content:encoded><![CDATA[<p>Working on a variation of <em>Settlers of Catan</em> called <em><a href="http://johntantalo.com/wiki/Vineyards_of_Catan">Vineyards of Catan</a></em>.<br />
<a href="http://www.mayfairgames.com"><br />
Mayfair Games</a> has <a href="http://www.mayfairgames.com/cgi-bin/shopper.exe?preadd=action&#038;key=MFGA8329X3&#038;reference=/cgi-bin/shopper.exe%3Fsearch%3Daction%26keywords%3DCatan-Parts%26searchstart%3D0%26template%3DPDGTemplatesPlainSearchResult.html">blank tiles</a> and <a href="http://www.mayfairgames.com/shop/product/3000-3299/pages/3110.htm">replacement card packs</a>. Current plan is to print out vineyard tiles and wine cards on sticker paper to stick on the blank tiles and replacement cards.</p>
<p>Progress updates to follow.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/vineyards-of-catan/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What&#8217;s wrong with Yelp?</title>
		<link>http://www.johntantalo.com/blog/why-you-cant-trust-yelp-reviews/</link>
		<comments>http://www.johntantalo.com/blog/why-you-cant-trust-yelp-reviews/#comments</comments>
		<pubDate>Sat, 03 May 2008 18:36:35 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=18</guid>
		<description><![CDATA[Imagine for a moment that you were a point in multidimensional space, and your nearby neighbors in this space are people that share your preferences for restaurants, bars, and clubs. In this model, a bar you like is very near to you (e.g., by a Euclidean metric), while some place you hate is far away. [...]]]></description>
			<content:encoded><![CDATA[<p>Imagine for a moment that you were a point in multidimensional space, and your nearby neighbors in this space are people that share your preferences for restaurants, bars, and clubs. In this model, a bar you like is very near to you (e.g., by a <a href="http://en.wikipedia.org/wiki/Euclidean_distance">Euclidean metric</a>), while some place you hate is far away.</p>
<p>This model rules <a href="http://yelp.com">Yelp</a>. A review on yelp is a measurement of the distance between the reviewer and the reviewed. The review will be favorable if and only if the reviewer is nearby the reviewed in the model.</p>
<p>A restaurant (e.g., <a href="http://www.yelp.com/biz/bite-san-diego">Bite</a>) gets good reviews  because the people that review it know or can guess, before they go there, that they will like it. If they didn&#8217;t, the place wouldn&#8217;t have such stellar reviews.</p>
<p>So why do some places get terrible reviews? I see cases that would cause this. First, if a new nightclub (e.g., <a href="http://www.yelp.com/biz/universal-hillcrest-san-diego">Universal</a>) is still &#8220;figuring itself out,&#8221; it might attract a lot of people expecting one thing and getting another. In other words, they are not near the place in the model, but they visit it anyway because they think they might. Likely, because the place is so new, many people are testing it out, so you can expect the reviews to be unfavorable, <em>even by the people who are supposed to like it</em>, because the presence of outsiders ruins the whole experience.</p>
<p>In another case, a super-exclusive bar might only cater to a very narrow range of clientele. In other words, you have to be unusually close to this bar in the model in order to like it. Perhaps it only supports one or two cliques of regulars, and everyone else is shunned.</p>
<p><a href='http://www.johntantalo.com/blog/wp-content/uploads/2008/05/untitled.png'><img src="http://www.johntantalo.com/blog/wp-content/uploads/2008/05/untitled-300x244.png" alt="" title="yelp" width="300" height="244" class="alignnone size-medium wp-image-19" /></a></p>
<p>In this example, the radii correspond to the ability of a bar or restaurant to support a wide or narrow section of people.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/why-you-cant-trust-yelp-reviews/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Reversed Blogs</title>
		<link>http://www.johntantalo.com/blog/reversed-blogs/</link>
		<comments>http://www.johntantalo.com/blog/reversed-blogs/#comments</comments>
		<pubDate>Wed, 09 Aug 2006 08:30:53 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=7</guid>
		<description><![CDATA[Take a regular blog, and flip it around. What do you get? A reversed blog, of course, where vistors write questions or comments and the author anwers. Sounds stupid, but I think people could get a lot of fun and use out of this. I see this manifesting as a single site with multiple instances [...]]]></description>
			<content:encoded><![CDATA[<p>Take a regular blog, and flip it around. What do you get? A reversed blog, of course, where vistors write questions or comments and the author anwers. Sounds stupid, but I think people could get a lot of fun and use out of this. I see this manifesting as a single site with multiple instances (e.g. <a href="http://blogger.com">blogger</a> or <a href="http://livejournal.com">livejournal</a>), funded by ads, and configurable to control who can ask questions, who can answer, and so on.</p>
<p>Here are a few examples. A couple&#8217;s answers their friends&#8217; questions. A researcher&#8217;s or expert&#8217;s revblog answers questions from others in her field. A CEO&#8217;s revblog answers his company&#8217;s employees. Changing the parameters around may allow anybody to ask and answer (a forum) or only the author to ask (a traditional blog), but keeping in the spirit of &#8220;questions&#8221; and &#8220;answers.&#8221;</p>
<p>For instance, imagine this were a reversed blog where I come up with silly ideas and you tell me if they suck or not. Would that be a good idea?</p>
<p><strong>Update:</strong> As pointed out in the comments, this idea has now been implemented by <a href="http://stackoverflow.com/">Stack Overflow</a> and its brethren: <a href="http://superuser.com/">Super User</a>, <a href="http://serverfault.com/">Server Fault</a>, and <a href="http://mathoverflow.net/">Math Overflow</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/reversed-blogs/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WikiSyntax</title>
		<link>http://www.johntantalo.com/blog/wikisyntax/</link>
		<comments>http://www.johntantalo.com/blog/wikisyntax/#comments</comments>
		<pubDate>Sun, 06 Aug 2006 08:56:00 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=4</guid>
		<description><![CDATA[I&#8217;m working on a Greasemonkey script to add syntax highlighting to Wikipedia in Firefox. The trick is to replace the edit page&#8217;s textarea with an editable iframe as the page loads, then you can do crazy fun stuff with the document which I will refrain from mentioning because it&#8217;s much too nerdy. At first I [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a <a href="http://greasemonkey.mozdev.org/">Greasemonkey</a> script to add syntax highlighting to <a href="http://www.wikipedia.org/">Wikipedia</a> in <a href="http://www.mozilla.com/firefox/">Firefox</a>. The trick is to replace the edit page&#8217;s textarea with an editable iframe as the page loads, then you can do crazy fun stuff with the document which I will refrain from mentioning because it&#8217;s much too nerdy.</p>
<p>At first I thought an extension was the way to go, but its turns out extensions are aimed at tweaking Firefox&#8217;s interface, not fussing with the page. Greasemonkey is perfect for the job, since it basically just executes a script on every page that matches a given pattern. Plus, users don&#8217;t have to go through the hassle of downloading crap and restarting the application.</p>
<p><a class="imagelink" title="WikiSyntax" href="http://www.johntantalo.com/blog/wp-content/uploads/2006/12/picture-1.png"><img align="left" id="image12" alt="WikiSyntax" title="WikiSyntax" src="http://www.johntantalo.com/blog/wp-content/uploads/2006/12/picture-1.thumbnail.png" /></a>This screenshot shows link underlining, headers, and boldface (i.e., embiggening). I haven&#8217;t figured out how to handle styling as the page is edited, though, but once that&#8217;s out of the way the rest should just be a matter of regex hacking.</p>
<p>Here is a quick <a href="http://johntantalo.com/wikisyntax/">WikiSyntax demonstration</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/wikisyntax/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bourgeoisie</title>
		<link>http://www.johntantalo.com/blog/bourgeoisie/</link>
		<comments>http://www.johntantalo.com/blog/bourgeoisie/#comments</comments>
		<pubDate>Thu, 27 Jul 2006 08:08:17 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Ideas]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=3</guid>
		<description><![CDATA[To celebrate my endeavor to read Howard Zinn&#8216;s Why Southerners are Jerks: A People&#8217;s History of the United States, Michael and I have started designing a game called Bourgeoisie in the spirit of SimCity, basically what SimCity 2 through 4 could have been if Will Wright had more than two ideas to rub together. The [...]]]></description>
			<content:encoded><![CDATA[<p>To celebrate my endeavor to read <a href="http://en.wikipedia.org/wiki/Howard_Zinn">Howard Zinn</a>&#8216;s <i>Why Southerners are Jerks: A People&#8217;s History of the United States</i>, Michael and I have started designing a game called <a href="http://johntantalo.com/wiki/index.php?title=Bourgeoisie">Bourgeoisie</a> in the spirit of SimCity, basically what SimCity 2 through 4 could have been if <a href="http://en.wikipedia.org/wiki/Will_Wright">Will Wright</a> had more than two ideas to rub together.</p>
<p>The idea is to get a bunch of players to represent business owners, and they collude against each other to gain the upper hand in a diverse marketplace based around neighborhoods and cities.</p>
<p>An excerpt from the wiki, dealing with law enforcement:</p>
<blockquote><p>
Workers and players may perform illegal activities that attract the attention of law enforcement. For instance, a player may own a mafia syndicate that extorts protection monies from the nearby businesses of other players in exchange for not sending soldiers over to permanently silence the other players&#8217; workers. This is just business. The victim in this case may either pay the protection or pay the cops to protect him by bribes or pushing through legislation against organized crime. The mafia boss, of course, may also bribe law enforcement to look the other way. This is the mechanism by which illegitimate (under the table) transactions are taxed.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/bourgeoisie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

