<?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>techfounder</title>
	<atom:link href="http://www.techfounder.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.techfounder.net</link>
	<description>Blog about web development and Internet entrepreneurship</description>
	<lastBuildDate>Mon, 21 Jun 2010 19:41:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>On the pitfalls of date validation with the Zend Framework</title>
		<link>http://www.techfounder.net/2010/06/21/on-the-pitfalls-of-date-validation-with-the-zend-framework/</link>
		<comments>http://www.techfounder.net/2010/06/21/on-the-pitfalls-of-date-validation-with-the-zend-framework/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 19:41:37 +0000</pubDate>
		<dc:creator>Eran Galperin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zend_date]]></category>
		<category><![CDATA[zend_locale]]></category>

		<guid isPermaLink="false">http://www.techfounder.net/?p=513</guid>
		<description><![CDATA[I'm writing this post as a warning for people using Zend_Date to validate dates, either as a standalone or as a validator in a chain. I've been using Zend_Validate_Date validator, which uses the Zend_Date::isDate() method internally, for a while now - mainly for form processing. I've recently completed a project where a very bizarre bug [...]]]></description>
			<content:encoded><![CDATA[<p>I'm writing this post as a warning for people using Zend_Date to validate dates, either as a standalone or as a validator in a chain. I've been using Zend_Validate_Date validator, which uses the Zend_Date::isDate() method internally, for a while now - mainly for form processing. </p>
<p>I've recently completed a project where a very bizarre bug would occur on some machines, and I wasn't able to reproduce it myself on any test machine that I tried. The bug manifested in a calendar system we built for the project, and in certain situations form submissions would not pass the date validation through Zend_Validate_Date, despite using the exact same input that was passing on the test machines. </p>
<p>After bringing in one of the "affected" machines for testing, I used the process of elimination to determine the problem originates in the Zend_Date::isDate() method, which has different behavior on different machines. </p>
<p>Zend_Date tries to validate dates according to a given format (with a default fallback). The dangerous behavior is that it tries to convert the given format to a localized format using Zend_Locale. Zend_Locale attempts to detect automatically the locale of the requesting client, and it appears that on the machines that were exhibiting the bug, a different locale was determined than those I was testing it on.</p>
<p>Despite trying to validate a non-localized format (to be exact, the MySQL timestamp format - YYYY-MM-dd HH:mm:sss), it was being converted on the affected machine sdue to the auto-detection by Zend_Locale (on a side note - it was happening on Internet Explorer 8 on Windows 7). To avoid this issue, I set the locale for all requests manually to en_US, since I don't have any other use for Zend_Locale in the application. I put the following lines in the bootstrap - </p>
<pre class="php">
$locale = new Zend_Locale('en_US');
Zend_Registry::set('Zend_Locale', $locale);
</pre>
<p>As recommended by the manual to achieve this effect.</p>
<p>In my opinion, the Locale should be not be auto-detected by default - it should be an opt-in feature if it affects other components behind the scenes.</p>
 <img src="http://www.techfounder.net/wp-content/plugins/feed-statistics.php?view=1&post_id=513" width="1" height="1" style="display: none;" /><div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.techfounder.net%2F2010%2F06%2F21%2Fon-the-pitfalls-of-date-validation-with-the-zend-framework%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.techfounder.net%2F2010%2F06%2F21%2Fon-the-pitfalls-of-date-validation-with-the-zend-framework%2F" height="61" width="51" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.techfounder.net/2010/06/21/on-the-pitfalls-of-date-validation-with-the-zend-framework/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Fetching specific rows from a group with MySQL</title>
		<link>http://www.techfounder.net/2010/03/12/fetching-specific-rows-from-a-group-with-mysql/</link>
		<comments>http://www.techfounder.net/2010/03/12/fetching-specific-rows-from-a-group-with-mysql/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 01:25:29 +0000</pubDate>
		<dc:creator>Eran Galperin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[derived tables]]></category>
		<category><![CDATA[group by]]></category>
		<category><![CDATA[latest post]]></category>
		<category><![CDATA[subquery]]></category>

		<guid isPermaLink="false">http://www.techfounder.net/?p=476</guid>
		<description><![CDATA[In a normalized database, we store separate entities in separate tables and define relationships between them, those being - one-to-one, one-to-many and many-to-many. We often want to fetch data which is split over two or more related tables, which is dead simple when fetching the extra data from the 'one' side of a relationship (ie, [...]]]></description>
			<content:encoded><![CDATA[<p>In a normalized database, we store separate entities in separate tables and define relationships between them, those being - one-to-one, one-to-many and many-to-many. We often want to fetch data which is split over two or more related tables, which is dead simple when fetching the extra data from the 'one' side of a relationship (ie, from a "parent" table):</p>
<pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> product_images.src,products.name
<span style="color: #993333; font-weight: bold;">FROM</span> product_images
<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> products <span style="color: #993333; font-weight: bold;">ON</span> product_images.parent_id=products.id</pre>
<p>Literally: Get the name of the parent product for each row in the products_images table.</p>
<p>Going the other direction is not as trivial. If we just want all the referenced rows in the child table, the query seen before would do the trick. But if we wanted a specific row to be found - for example, the latest inserted image, it becomes somewhat more complicated.<br />
<span id="more-476"></span><br />
Lets explore a common scenario - fetching the latest comment for each row in a list of posts in a forum. </p>
<p><a href="http://forums.devnetwork.net/viewforum.php?f=1"><img src="http://www.techfounder.net/wp-content/uploads/2010/03/latest-posts.png" alt="" title="latest-posts" width="570" height="145" class="alignnone size-full wp-image-480" /></a><br />
Latest posts from the <a href="http://forums.devnetwork.net">devnet forums</a></p>
<p>Dealing with the following simplified schema for a forum:</p>
<pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`threads`</span> <span style="color: #66cc66;">&#40;</span>
   <span style="color: #ff0000;">`id`</span> INT <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>  <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span>,
   <span style="color: #ff0000;">`title`</span> VARCHAR<span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">250</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> ,
   <span style="color: #ff0000;">`created`</span> TIMESTAMP <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> CURRENT_TIMESTAMP ,
   <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #ff0000;">`id`</span> <span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span> ENGINE = InnoDB;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`posts`</span> <span style="color: #66cc66;">&#40;</span>
   <span style="color: #ff0000;">`id`</span> INT <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>  <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span>,
   <span style="color: #ff0000;">`thread_id`</span> INT <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> ,
   <span style="color: #ff0000;">`content`</span> TEXT <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> ,
   <span style="color: #ff0000;">`created`</span> TIMESTAMP <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> CURRENT_TIMESTAMP ,
   <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #ff0000;">`id`</span> <span style="color: #66cc66;">&#41;</span> ,
   <span style="color: #993333; font-weight: bold;">INDEX</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #ff0000;">`thread_id`</span> <span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span> ENGINE = InnoDB;</pre>
<p>A naive approach to fetching 10 threads with the latest post for each thread would be something like:</p>
<pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> threads.*, posts.*
<span style="color: #993333; font-weight: bold;">FROM</span> threads
<span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> posts <span style="color: #993333; font-weight: bold;">ON</span> posts.thread_id=threads.id
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> threads.id
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> posts.created <span style="color: #993333; font-weight: bold;">DESC</span>
<span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">10</span></pre>
<p>This query might appear to work as long as there is only one post per thread. Once there are more, you will start getting unexpected results (go ahead, try it). Lets try and understand why:</p>
<p>In the SQL standard, a GROUP BY modifier can return only columns that are either aggregated or the same for the entire group. MySQL extends this and allows returning non unique or aggregated columns from the group, instead of throwing an error. </p>
<p>However, values from those columns could come from any row in the group and we have no control over which row it will be.</p>
<blockquote><p>... all rows in each group should have the same values for the columns that are ommitted from the GROUP BY part. The server is free to return any value from the group, so the results are indeterminate unless all values are the same.<br />
<cite><a href="http://dev.mysql.com/doc/refman/5.1/en/group-by-hidden-columns.html" target="_blank">The MySQL manual on GROUP BY modifiers</a></cite></p></blockquote>
<p>In addition, grouping occurs before the order clause is even applied. After the grouping, unpredictable values for the order column (posts.created) would exist for each group, making the sorting afterward somewhat meaningless (since we wanted the latest post for each thread).</p>
<p>A more experienced SQL user might think - why not just use an aggregate function instead? leading to the following query:</p>
<pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> threads.*, posts.*, MAX<span style="color: #66cc66;">&#40;</span>posts.created<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> maxcreated
<span style="color: #993333; font-weight: bold;">FROM</span> threads
<span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> posts <span style="color: #993333; font-weight: bold;">ON</span> posts.thread_id=threads.id
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> threads.id
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> maxcreated <span style="color: #993333; font-weight: bold;">DESC</span>
<span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">10</span></pre>
<p>This is somewhat better, as it does retrieve the timestamp belonging to the latest post in each thread - however, surprisingly (or not, if you've been following closely) the rest of the non grouped columns from the threads table are still indeterminate and do not necessarily belong to the row with the latest timestamp.</p>
<p>The solution to this issue is not completely trivial, but it makes sense once you understand the limitations. The key is to use the GROUP BY statement to return the filtering criteria (latest timestamps from the posts table) but to avoid it affecting the result set directly.</p>
<p>First, the filtering criteria - </p>
<pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> thread_id,MAX<span style="color: #66cc66;">&#40;</span>created<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> created
<span style="color: #993333; font-weight: bold;">FROM</span> posts
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> posts.thread_id</pre>
<p>Here we return only aggregate (latest timestamp) and unique (thread_id) data for each group. Now we have the timestamp of the latest post from each thread, along with the matching thread identifier. </p>
<p>We will move the filtering criteria into a subquery, and JOIN that against the threads and posts table respectively.</p>
<pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> threads.*, posts.*
<span style="color: #993333; font-weight: bold;">FROM</span> threads
<span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> <span style="color: #66cc66;">&#40;</span>
   <span style="color: #993333; font-weight: bold;">SELECT</span> thread_id,MAX<span style="color: #66cc66;">&#40;</span>created<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> created <span style="color: #993333; font-weight: bold;">FROM</span> posts
   <span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> thread_id
<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> latest <span style="color: #993333; font-weight: bold;">ON</span> latest.thread_id = threads.id
<span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> posts <span style="color: #993333; font-weight: bold;">ON</span> latest.created=posts.created <span style="color: #993333; font-weight: bold;">AND</span>
latest.thread_id=posts.thread_id
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> posts.created <span style="color: #993333; font-weight: bold;">DESC</span>
<span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">10</span></pre>
<p>Literally: Fetch rows from the threads table, (left) join that with the timestamp from the latest post in each thread, and then (left) join that with the posts table with the condition that the timestamp and thread_id match. This returns all the rows in the threads table along with the latest post from each thread.</p>
<p>People have a disposition for avoiding subqueries due to performance concerns, but in this case it is a <b>derived</b> subquery (also referred to as a derived table) which will compute once for the entire query as opposed to a correlated subquery which computes once per row ( = bad performance with many rows).</p>
<p>* Note - in real-world situations you would like to specify the columns to be returned in the result set</p>
<p>For more advanced usage, I suggest you read Baron Schwartz's article on <a href="http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/">selecting the first/least/max row per group in SQL</a></p>
 <img src="http://www.techfounder.net/wp-content/plugins/feed-statistics.php?view=1&post_id=476" width="1" height="1" style="display: none;" /><div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.techfounder.net%2F2010%2F03%2F12%2Ffetching-specific-rows-from-a-group-with-mysql%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.techfounder.net%2F2010%2F03%2F12%2Ffetching-specific-rows-from-a-group-with-mysql%2F" height="61" width="51" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.techfounder.net/2010/03/12/fetching-specific-rows-from-a-group-with-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating embedabble widgets</title>
		<link>http://www.techfounder.net/2010/02/05/creating-embedabble-widgets/</link>
		<comments>http://www.techfounder.net/2010/02/05/creating-embedabble-widgets/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 03:38:39 +0000</pubDate>
		<dc:creator>Eran Galperin</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[embed]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://www.techfounder.net/?p=461</guid>
		<description><![CDATA[Distribution of embeddable widgets is a common feature in many web services today. The most well known example is probably google's adsense that allows site owners to add google ads to their sites. Embeddable widgets allow a subset of functionality to be used on third-party sites, greatly increasing possible market reach for a web service [...]]]></description>
			<content:encoded><![CDATA[<p>Distribution of embeddable widgets is a common feature in many web services today. The most well known example is probably google's adsense that allows site owners to add google ads to their sites. Embeddable widgets allow a subset of functionality to be used on third-party sites, greatly increasing possible market reach for a web service / application.<br />
<span id="more-461"></span></p>
<h2>What is a [web] widget</h2>
<blockquote><p>... a <strong>web widget</strong> is a portable chunk of code that can be installed  and executed within any separate HTML-based web  page by an end user without requiring additional compilation.<br />
<a href="http://en.wikipedia.org/wiki/Web_widget" target="_blank">Web widget by Wikipedia</a></p></blockquote>
<p>Put simply, we need to provide prospective site owners with a short piece of code (henceforth, the "embed code") that they can place on their sites and have the widget appear without any additional modifications to the site.</p>
<p>How would we go about creating an embeddable widget?</p>
<h2>Cross-site scripting (XSS)</h2>
<p>Cross-site scripting is more often mentioned as a <a href="http://en.wikipedia.org/wiki/Cross-site_scripting" target="_blank">web vulnerability</a> which uses the same technique maliciously to manipulate the target site. In this case, Javascript will be used to create the widget on the host site and not to attack it (you should always beware of including scripts from untrusted sources).</p>
<p>This technique is based on embedding a script &lt;tag&gt; on the host site that will refer to a script residing on your service. The script should then dynamically create the widget on the host site by manipulating the DOM and adding stylesheets and script tags as needed. Dr. Nic gives a nice overview of this technique in <a href="http://drnicwilliams.com/2006/11/21/diy-widgets/" target="_blank">this detailed tutorial</a>.</p>
<p>As the tutorial mentions, your embeddable script should have a unique namespace to avoid colliding with local scripts on the host site. Don't be shy to use a long and verbose name for this purpose. Example:</p>
<pre class="javascript">;<span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> techfounder_super_embed = window.<span style="color: #006600;">techfounder_super_embed</span> = <span style="color: #66cc66;">&#123;</span>
		init: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			<span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'embedded!'</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #66cc66;">&#125;</span>
	<span style="color: #66cc66;">&#125;</span>;
	techfounder_super_embed.<span style="color: #006600;">init</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</pre>
<p>Some quick notes:</p>
<ul>
<li>I used a self executing anonymous function. This allows me to declare additional variables and functions other than my main namespace ('techfounder_super_embed' in this case) without polluting the main scope or interferring with existing code on the site.</li>
<li>In order for the main namespace to be available outside of the anonymous function scope, I attach it to the window object.</li>
<li>I preceded the function with a semi-colon to close any potentially open Javascript statement that might have been loaded before it, which would have resulted in an error.</li>
</ul>
<p>As opposed to the advice given in Dr. Nic's article, I usually opt to use an external library such as jQuery, in order to better account for cross-browser differences as well as leverage the power inherent in such libraries. jQuery in particular has the useful <a href="http://api.jquery.com/jQuery.noConflict/" target="_blank">noConflict()</a> method which allows it to work side-by-side with other libraries, and can be loaded from a <a href="http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery" target="_blank">google CDN</a> so it does not add bandwidth load on your server.</p>
<p>As for retrieving data cross-site (from your service server to the host site), there are 3 paths you could take:</p>
<ul>
<li>Embedding extra script tags which include JSON data that is constructed dynamically (as shown in Dr. Nic's tutorial).</li>
<li>Creating an Iframe element that accesses a remote resource (ie, on your server) to retrieve the data, and then passing the data back to the document.</li>
<li>Using a <a href="http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/" target="_blank">JSONP</a> call to simulate a cross-site AJAX request. I personally opt for this technique as I find it the most elegant. jQuery <a href="http://api.jquery.com/jQuery.getJSON/" target="_blank">supports this natively</a> in recent versions, making it almost too easy to implement.</li>
</ul>
<p>An important note to keep in mind that styling the widget elements should be done very explicitly. As the widget is embedded directly into the host document it could be affected by any previously loaded stylesheets. A good start would be to use a CSS reset (such as <a href="http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/" target="_blank">this one</a> by Eric Meyer) and apply it directly to a unique ID that identifies the base widget element.</p>
<h2>Iframe embedding</h2>
<p>An Iframe is the most direct approach to including content from a remote site. It's easy to pass arguments in the Iframe source URL and have a response dynamically built in return. However the Iframe approach suffers from some limitations:</p>
<ul>
<li>You have to specify the Iframe proportions in the embed code and it should match the content exactly, else the content can get truncated. This also means the embed code would need to change if the widget appearance changes (which comes up often for customizable widgets).</li>
<li>There are some security limitations for Iframe scripting, so if you need to manipulate the host site page in any additional way,  you would need to include a script &lt;tag&gt; as well in the initial embed code to <a href="http://www.nczonline.net/blog/2009/09/15/iframes-onload-and-documentdomain/" target="_blank">bypass the security restrictions</a>.</li>
<li>Iframes are invalid markup in XHTML Strict doctype. Depending on the host site doctype declaration, this could present a minor issue (if the host site owner is concerned about with valid markup).</li>
</ul>
<p>A big advantage in using an Iframe over directly embedding the widget in the host page is that you don't have to be concerned with external styles affecting the widget.</p>
<h2>Which should you use</h2>
<p>Cross site scripting is useful when there is a need to dynamically manipulate the host site page. This would include placing the widget in positions different to where the embed code was placed at, offering additional user-interface interactions or communicating data back to your server (as Google analytics does, for example).</p>
<p>The Iframe approach is useful when you can tell ahead of time the exact size of the embedded widget, and you only want it to display content and not offer any Javascript interactions that occur outside of the Iframe.</p>
 <img src="http://www.techfounder.net/wp-content/plugins/feed-statistics.php?view=1&post_id=461" width="1" height="1" style="display: none;" /><div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.techfounder.net%2F2010%2F02%2F05%2Fcreating-embedabble-widgets%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.techfounder.net%2F2010%2F02%2F05%2Fcreating-embedabble-widgets%2F" height="61" width="51" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.techfounder.net/2010/02/05/creating-embedabble-widgets/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Back to business</title>
		<link>http://www.techfounder.net/2010/01/26/back-to-business/</link>
		<comments>http://www.techfounder.net/2010/01/26/back-to-business/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 00:10:36 +0000</pubDate>
		<dc:creator>Eran Galperin</dc:creator>
				<category><![CDATA[Web development]]></category>

		<guid isPermaLink="false">http://www.techfounder.net/?p=440</guid>
		<description><![CDATA[After a long hiatus, I'm getting back to blogging on web technologies, startups and other miscellanea. I've just completed a re-design of the site, which I'm proud to say I've done myself (with some finishing touches and advice from my two partners at Lionite). I'm looking forward to expand discussion on some subjects I've brought [...]]]></description>
			<content:encoded><![CDATA[<p>After a long hiatus, I'm getting back to blogging on web technologies, startups and other miscellanea. I've just completed a re-design of the site, which I'm proud to say I've done myself (with some finishing touches and advice from my two partners at <a href="http://www.lionite.com/about">Lionite</a>).</p>
<p>I'm looking forward to expand discussion on some subjects I've brought up in the past (especially models in the Zend Framework) as well write on some of things we've been doing lately. Hope you will find it useful / interesting.</p>
 <img src="http://www.techfounder.net/wp-content/plugins/feed-statistics.php?view=1&post_id=440" width="1" height="1" style="display: none;" /><div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.techfounder.net%2F2010%2F01%2F26%2Fback-to-business%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.techfounder.net%2F2010%2F01%2F26%2Fback-to-business%2F" height="61" width="51" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.techfounder.net/2010/01/26/back-to-business/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to add semantics to content? embed it in the tools</title>
		<link>http://www.techfounder.net/2009/09/02/how-to-add-semantics-to-content-embed-it-in-the-tools/</link>
		<comments>http://www.techfounder.net/2009/09/02/how-to-add-semantics-to-content-embed-it-in-the-tools/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 01:43:11 +0000</pubDate>
		<dc:creator>Eran Galperin</dc:creator>
				<category><![CDATA[Interesting]]></category>
		<category><![CDATA[The Webs]]></category>
		<category><![CDATA[authoring tools]]></category>
		<category><![CDATA[data mining]]></category>
		<category><![CDATA[semantic web]]></category>
		<category><![CDATA[semantics]]></category>

		<guid isPermaLink="false">http://www.techfounder.net/?p=422</guid>
		<description><![CDATA[Through reading an interesting post by Chris Dixon titled "To make smarter systems, it's all about the data", I came across another interesting link in one of the comments - the google research blog post on "The unreasonable effectiveness of data". The post links to a PDF document written by three Google researchers, and covers [...]]]></description>
			<content:encoded><![CDATA[<p>Through reading an interesting post by Chris Dixon titled "<a href="http://www.cdixon.org/?p=340" target="_blank">To make smarter systems, it's all about the data</a>", I came across another interesting link in one of the comments - the google research blog post on "<a href="http://googleresearch.blogspot.com/2009/03/unreasonable-effectiveness-of-data.html" target="_blank">The unreasonable effectiveness of data</a>". </p>
<p>The post links to a PDF document written by three Google researchers, and covers a subject I've been experimenting with a lot lately - the semantic extraction of data.<br />
<span id="more-422"></span><br />
The document is a nice read though probably too technical for most, and it brings up the <em>difficulty of implementation</em> as one of the barriers for taking the next step towards structured data on the web. The argument is that most small content publishers do not posses the knowledge and expertise required to publish their content in a semantically meaningful way.</p>
<p>It seems to me that there's an easy solution for that - and that is to <strong>embed semantic awareness in the publishing tools themselves</strong>. Most people publish content through one of several high-profile content management systems (WordPress, Moveable type, Blogger, etc), meaning it is possible to reach a very large segment of content publishers from relatively few integration points.</p>
<p>Expecting people to learn about and implement web semantics is unreasonable, as the document suggests. Delegating that responsibility to the authoring tools by enhancing the backend logic and the interface, is very much doable. Need to add a calender event? allow the interface to add it in the proper <a href="http://microformats.org/wiki/datetime-design-pattern" target="_blank">microformat</a>. Want to affect the styling of your content? allow the interface to give several <a href="http://www.joedolson.com/articles/2008/04/guide-to-semantic-html/" target="_blank">semantically significant options</a> (headers, paragraphs etc.). <strong>Most of those options are available today</strong>, yet they are not obvious enough that they are used in a consistent manner.</p>
<p>HTML 5 is <a href="http://www.alistapart.com/articles/previewofhtml5" target="_blank">around the corner</a>, with more semantically relevant tags (such as header, footer, navigation, sections). Integrating support for it in those content management systems is a good first step towards more semantically accessible content.</p>
<p>Going even further with this, content management systems could provide more structured data on demand - or wait, they are already doing this! XML feeds, anyone? seems to me that if you poke a little beneath the surface you find that there is actually a lot of structure in modern online content. What's lacking is uniformity, but even so the number of dominant standards is not great.</p>
<p>Who will be "the next Google" who can examine this structure and extract meta-meaning that can provide value? you can be certain some bright minds are already on the case. </p>
 <img src="http://www.techfounder.net/wp-content/plugins/feed-statistics.php?view=1&post_id=422" width="1" height="1" style="display: none;" /><div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F09%2F02%2Fhow-to-add-semantics-to-content-embed-it-in-the-tools%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F09%2F02%2Fhow-to-add-semantics-to-content-embed-it-in-the-tools%2F" height="61" width="51" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.techfounder.net/2009/09/02/how-to-add-semantics-to-content-embed-it-in-the-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Client development &#8211; think partners, not employers</title>
		<link>http://www.techfounder.net/2009/07/30/client-development-think-partners-not-employers/</link>
		<comments>http://www.techfounder.net/2009/07/30/client-development-think-partners-not-employers/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 23:58:21 +0000</pubDate>
		<dc:creator>Eran Galperin</dc:creator>
				<category><![CDATA[Business Development]]></category>
		<category><![CDATA[Lionite]]></category>
		<category><![CDATA[Web development]]></category>

		<guid isPermaLink="false">http://www.techfounder.net/?p=396</guid>
		<description><![CDATA[Saying there is a lot of variation in the field of web development would be a huge understatement. You have everything from anonymous freelancers to large known firms, several hundred dollar budgets to several hundred thousand dollar budgets (and more). How much does it cost to build a website? what does building a website entails? [...]]]></description>
			<content:encoded><![CDATA[<p>Saying there is a lot of variation in the field of web development would be a huge understatement. You have everything from anonymous freelancers to large known firms, several hundred dollar budgets to several hundred thousand dollar budgets (and more). </p>
<p>How much does it cost to build a website? what does building a website entails? <strong>there are no universal answers to those questions</strong>.</p>
<blockquote><p>Client: "Enough talking, let's get down to business. What will 50$ get me?"<br />
Brad: * looks at wrist watch *<br />
Brad: "About 5 more minutes of my time."<br />
<a href="http://www.bradcolbow.com/archive.php/?p=76" target="_blank" style="float:right;">Brad Colbow on Time</a></p></blockquote>
<p>In fact, there is so much variation, that a recent client told <a href="http://www.lionite.com" target="_blank" title="Lionite Internet Ventures">us</a> post-project completion that when he was shopping around for offers from various firms, he got offers between 2000$ and 60,000$. That's a factor of 30 between offers! </p>
<p>He picked us since we conveyed the best value (quality / price) of all offers, even though he had much cheaper offers (we were about midway in the range). All things being equal, all he had was his gut-feeling and our resume to guide him. That is, if we didn't engage in <em>client development</em>.<br />
<span id="more-396"></span><br />
The client-provider relationship in web development is complicated. Most would-be clients are lay-man, possessing no insight on what goes into every feature and pixel you see on a website. They are also, most likely, unfamiliar with their prospective provider and how to evaluate him - is he a hack? what are the qualities that he brings to table? how can I quantify the value he gives me?</p>
<p>That's where the process we term "Client development" comes in. It involves several activities, most of which are not directly related to web development:</p>
<h3>Matching expectations</h3>
<p>This is a basic rule of engagement in most business operations, and web-development is not excluded - especially since it is such a misunderstood and technical field. </p>
<p>A lot of clients look at website features and think "that's easy! you just put the thing there and do that...". Well, in the real world things are usually more complicated. What might look simple on the surface could involve a lot of back-end work and a lot of custom integration with various services... and the user interface itself is probably more work than you'd think.</p>
<p>The first thing we try to do is <strong>lower expectations</strong> to some degree. Our stance is that if it takes any amount of time to design / develop / test, then it will be priced in the proposal. That might sound harsh - but it's the only way to properly evaluate and convey the value of the project.</p>
<p>As I've written in <a href="http://www.techfounder.net/2009/04/05/conveying-value-to-clients/" target="_blank">conveying value to clients</a>, creating a transparent and fair price proposal can go a long way to matching up the client's expectations with yours. It should be accompanied by a well written <a href="http://www.techfounder.net/2009/07/03/writing-specifications-for-web-applications/" target="_blank">specification document</a>, composed interactively with the client and which is completely understood by him (or her).</p>
<h3>Educating clients</h3>
<p>To help clients really get a sense of what they are getting in return for their money, it's important to explain some basic terminology and elaborate on the process of web development. </p>
<p>Explaining terms such as <i>usability</i>, <i>user experience</i>, <i>mockups</i>, <i>layouts</i>, <i>client-side</i> / <i>server-side</i>, <i>testing</i>, <i>maintainability</i>, <i>standards</i> and the interactions between them can really shed light on the considerations and work involved in building a website. </p>
<p>This in turn allows clients to better understand the price-stamp put on features, and feel more secure overall in decisions they make since they better understand what is involved.</p>
<h3>Knowing when to say "No"</h3>
<p>In some cases, clients get over involved in day-to-day decisions, especially in something as tangible as design. The design of a website is very visible which makes it very susceptible to micro-management and over-feedback from clients as they watch it evolve into a finished product. Convincing clients to trust our experience and expertise is imperative.</p>
<p>Another aspect that is constantly under-pressure is <b>scope</b>. Scope-creep is a common yet undesirable side-effect of perfectionism inherent in most of us (including clients). This tendency to think how things could be improved beyond what was originally specified is something that needs to be properly monitored. </p>
<p>This often means just saying a strict "No" to client suggestions and ideas when it's appropriate to do so. If features and requirements change (and they will), they have to come at the expense of some other features deemed less important. <b>The project scope must be maintained</b>.</p>
<h3>Selecting clients</h3>
<p>Client development is a two way street. Consider for example the following project outline:</p>
<blockquote><p><b>US Company looking to develop financial website</b></p>
<p>Requirements:<br />
Budget 10,000$-25,000$<br />
Maximum Billrate per Man Hour: $6/hour<br />
Minimum Number of Men assigned to Project: 30</p>
<p>We require a well established firm that meets these basic requirements in addition to being able to delivery quality and accuracy in its work.
</p></blockquote>
<p>(This is an <a href="http://www.elance.com/c/rfp/main/rfpBid.pl?jobid=17588429&">actual posting</a> on Elance, in case you were wondering)</p>
<p>In short, this person wants a financial website, but gives no project requirements / specifications or feature list of any kind. Instead, the requirements are that the provider:<br />
A) Has a minimum of 30 men (why gender biased?) assigned to the project, and<br />
B) No one should be paid more than 6$ an hour (which is less than what a register clerk at McDonalds makes)</p>
<p>For this he wants <b>quality</b> and <b>accuracy</b>. Is his expectations unreasonable? might be (I'm voting no).</p>
<p>Even more common is the "work for minor shares" offer in what is probably "the next big thing". Somehow people believe that having an idea by itself is sufficient leverage, and should prompt serious firms into developing their products.</p>
<blockquote style="padding-bottom:25px;"><p>The fact that there's no market for startup ideas suggests there's no demand.<br />
Which means, in the narrow sense of the word, that startup ideas are <b>worthless</b>.<br />
<a style="float:right;" target="_blank" href="http://www.paulgraham.com/ideas.html">Paul Graham on Ideas for startups</a>
</p></blockquote>
<p>People in the industry seem to agree that <a href="http://startupblog.wordpress.com/2009/07/11/idea-vs-execution/">execution is the main key</a> for the success of a startup. <b>We do execution</b> (and also <a href="http://www.lionite.com/method" target="_blank" title="Concept development @ lionite">concept development</a>, but that's for another article).</p>
<p>The point I'm making is that a good relationship with a client can only be achieved when both sides understand and respect each other. This is not just about money, it's about the value generated by both sides. </p>
<p>What does this mean? it means that in order to get the right clients, we need to be selective ourselves. Clients not only choose us, but we get to choose them as well. For this reason, we should never undercut our price-proposals. We need to believe they represent not only fair, but <b>great</b> value. </p>
<p>It's the client's privilege to agree or disagree, but we want to work with people who understand the value we represent. If they want to pay less, they need to drop features. It's give-and-take and there are no freebies - this is a business after all. Nobody gets rich from web development, the least they could do is get paid on par with the value they represent.</p>
<p>This feeling out process usually happens during the expectation matching phase. If both sides can not bring their expectations to the same level, it's best to part ways and wish each other the best than trying to hammer in a shaky relationship. </p>
<h3>It's up to you</h3>
<p>Client development is a process that a lot of small businesses and freelancers skip (and sometimes larger firms as well). Whether you put the time and effort to make prospective clients your partners instead of your employers is <strong>up to you</strong>. </p>
 <img src="http://www.techfounder.net/wp-content/plugins/feed-statistics.php?view=1&post_id=396" width="1" height="1" style="display: none;" /><div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F07%2F30%2Fclient-development-think-partners-not-employers%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F07%2F30%2Fclient-development-think-partners-not-employers%2F" height="61" width="51" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.techfounder.net/2009/07/30/client-development-think-partners-not-employers/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>What makes a good programmer?</title>
		<link>http://www.techfounder.net/2009/07/22/what-makes-a-good-programmer/</link>
		<comments>http://www.techfounder.net/2009/07/22/what-makes-a-good-programmer/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 02:24:38 +0000</pubDate>
		<dc:creator>Eran Galperin</dc:creator>
				<category><![CDATA[Web development]]></category>
		<category><![CDATA[techfounder]]></category>
		<category><![CDATA[practices]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[quality]]></category>

		<guid isPermaLink="false">http://www.techfounder.net/?p=368</guid>
		<description><![CDATA[Some casual surfing led me to this article from a couple of years ago, titled "How to recognize a good programmer". It was a nice read, but as many in the comments pointed out, the criteria the author set forth most likely describe himself and are not really useful as rules-of-thumb on how to recognize [...]]]></description>
			<content:encoded><![CDATA[<p>Some casual surfing led me to <a href="http://www.inter-sections.net/2007/11/13/how-to-recognise-a-good-programmer/">this article</a> from a couple of years ago, titled "How to recognize a good programmer". It was a nice read, but as many in the comments pointed out, the criteria the author set forth most likely describe himself and are not really useful as rules-of-thumb on how to recognize a good programmer. </p>
<p>It got me thinking though, on what are the attributes I consider useful in fellow programmers. So what makes a good programmer?<br />
<span id="more-368"></span></p>
<h2>An analytical thinker</h2>
<p>Programmers need to be problem solvers. The process of programming requires that we systematically break complicated problems down, plan and implement solutions and find / eliminate small inconsistencies in code (bugs). </p>
<p>Analytical thinking also manifests in the ability to follow complicated logic through disparate code segments and understand it. It  allows us to grasp abstract concepts such as Object Oriented methodology and design patterns and implement it in practice.</p>
<h2>Has his priorities straight</h2>
<p>If I would ask you to rate the following according to priority, how would you order them?</p>
<ul>
<li>Security</li>
<li>Maintainability</li>
<li>Usability</li>
<li>Performance</li>
<li>LOC (lines-of-code) count</li>
</ul>
<p>Take a moment to think about that, and then consider:</p>
<ol>
<li>If you picked <b>LOC count</b> first, you failed big time in my book. In fact, LOC optimization can often go directly against the other metrics (such as maintainability). A lower LOC count should never be a goal, only a result of careful application of well factored architecture.</li>
<li>If you picked <b>performance</b> first, you are probably the guy who keeps writing articles about how you should use a <i>while</i> loop instead of a <i>for</i> loop since it came out a few milliseconds faster in your benchmarks. You might be inflicted with a case of premature optimization.<br />
<blockquote><p>We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.<br />
<a href="http://en.wikipedia.org/wiki/Optimization_%28computer_science%29#When_to_optimize" target="_blank" style="float:right;">Donald Knuth</a></p>
</blockquote>
<p>Performance should only be good enough to satisfy the requirements of the application. Aside from caveats to well-known pitfalls (such as executing queries in each iteration of a long loop), performance optimizations should be deferred to the very last and even then should be used appropriately (profile ... profile ... profile ... optimize). </p>
<p>The only exception to this is if you are primarily developing performance dependent applications (such as low-level system drivers).
</li>
<li><b>Security</b> is on somewhat of a middle ground. Depending on the application and distribution model it can be completely useless or mission critical. It's mostly somewhere in between, and thus can't be ranked as number one.</li>
<li><b>Maintainability</b> is definitely one of the most important attributes of a software application. High maintainability allows you to improve other attributes (such as performance), <i>when it is needed</i>.
<p>Maintainability is the single most important factor for keeping productivity up and costs down. For a long time I strongly believed this to be <b>the</b> most important attribute of software design.<br />
However ...</li>
<li>The most important attribute is <b>usability</b>. In the end, the worth of your application is only as much value as it delivers to the end-user.
<p>We should always remember - software is not written to serve its developers or the systems they run on. They are written to solve problems. If those problems are not solved, then the project is a failure.</p>
<p>I wrote usability here as a more general term than just UI/UX effectiveness. Even a command line application or a background service has its usability factor in the sense of how well it answers a specific need.
</li>
</ol>
<h2>Gets things done</h2>
<blockquote><p>In principle, it’s simple. You’re looking for people who are</p>
<p>   1. Smart, and<br />
   2. Get things done.<br />
<a href="http://www.joelonsoftware.com/articles/GuerrillaInterviewing3.html" target="_blank" style="float:right;">Joel Spolsky</a><br />

</p></blockquote>
<p>Quite possibly the single most important trait in a developer. You can excel at all the previous attributes and still be a mediocre programmer if you just <b>can't get things done</b>. One average but productive developer could easily replace several highly talented but slowly moving developers, depending on his responsibilities. </p>
<p>At the end of the day you definitely want more highly-productive developers than those who are high on theory but not actual work.</p>
<h2>Does more than "just enough"</h2>
<p>Getting things done is important. Getting things done "the right way" is even more important. </p>
<p>Constantly paying off your technical debt is crucial - if you keep accruing debt by "hacking" quick fixes that work now but are not maintainable, you only create the appearance of progress. In reality, the cost of getting rid of a large technical debt could become prohibitive before you know it.</p>
<p>Taking the time to constantly refactor code into a more maintainable state is the best way to prevent the spiral into project oblivion. </p>
<h2>Responsible</h2>
<p>A person could be a very capable programmer on technical ability alone, however if he does not own up to his mistakes and does not respect deadlines he could become a liability very quickly. </p>
<p>Responsibility also means to know where to let go of your ego for the good of the project. We developer often high large egos as we consider ourselves experts on many things. Putting the project first is a sign of a good developer.</p>
<h2>Good human relations</h2>
<p>Another all-around useful trait, this one applies to programmers as well. There is some stereotype that programmers are reclusive, unsociable creatures - programmers are still people <img src='http://www.techfounder.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . </p>
<p>In order to be a part of a team or handle clients, a programmer must have above basic social skills. Rudeness, arrogance, short-temper - do not have a place in a professional work environment. All it takes is one bad apple to ruin the mood for everybody.</p>
<h2>That's about it</h2>
<p>If you answer to all of the above, you are probably a pretty good programmer (and you are <a href="http://www.lionite.com/jobs">welcome to apply with us</a> <img src='http://www.techfounder.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). </p>
<p>If you read the article I mentioned at the beginning, you might notice I didn't mention passion or technological diversity as qualifying traits. Simply put, I don't think they're very relevant to the quality of a programmer. </p>
<p>Passion is nice to have, however I've known many very professional and high-quality developers who were just content to go about their work professionally from 9 to 5 and then go home and have a meaningful and fulfilling family life. A programmer can definitely completely professional without being passionate about programming.</p>
<p>Technological diversity is another nice to have but not a prerequisite - as long as you are in command of the technologies you work with, a lack of diversity shouldn't affect you too much. Decision makers need to be well aware of all the options before starting a project, however nowadays the choice of technology simply is not that important. </p>
<p>You can achieve good results regardless of the programming language and database engine among other consideration. The biggest consideration should be the type of skills available to your personnel.</p>
<p>I hope to see more suggestions and thoughts in the comments on what you think make a good programmer.</p>
 <img src="http://www.techfounder.net/wp-content/plugins/feed-statistics.php?view=1&post_id=368" width="1" height="1" style="display: none;" /><div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F07%2F22%2Fwhat-makes-a-good-programmer%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F07%2F22%2Fwhat-makes-a-good-programmer%2F" height="61" width="51" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.techfounder.net/2009/07/22/what-makes-a-good-programmer/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Writing specifications for web applications</title>
		<link>http://www.techfounder.net/2009/07/03/writing-specifications-for-web-applications/</link>
		<comments>http://www.techfounder.net/2009/07/03/writing-specifications-for-web-applications/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 23:44:52 +0000</pubDate>
		<dc:creator>Eran Galperin</dc:creator>
				<category><![CDATA[Lionite]]></category>
		<category><![CDATA[Web development]]></category>

		<guid isPermaLink="false">http://www.techfounder.net/?p=233</guid>
		<description><![CDATA[Specifications are an integral part of any web project (or any software project for that matter). Writing good specifications will improve the probability of success for a given project by a great deal. Why spec? Specifications encapsulate a project's goals, requirements, features and scope. This is very important for several reasons: Understanding project requirements Understanding [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Specifications</strong> are an integral part of any web project (or any software project for that matter). Writing good specifications will improve the probability of success for a given project by a great deal.<br />
<span id="more-233"></span></p>
<h2>Why spec?</h2>
<p>Specifications encapsulate a project's <strong>goals</strong>, <strong>requirements</strong>, <strong>features</strong> and <strong>scope</strong>. This is very important for several reasons:</p>
<h3>Understanding project requirements</h3>
<p>Understanding what a project sets out to achieve might seem obvious, but in reality, when at least two people are involved - some difference in perception of the project goals and needs is inevitable. Putting in writing the goals and requirements goes a long way towards resolving such differences. </p>
<p>Writing specifications will often reveal requirements not thought of initially, as a result of detailing and thinking through the initial set of requirements. This is very important for determining project <strong>scope</strong>.</p>
<h3>Developing a project scope</h3>
<p>The <strong>scope</strong> of a project is probably the single most important attribute for determining project success. A well defined scope will determine the time-frame, costs and requirements with good precision. </p>
<p>In essence, a scope is the sum of a project features, requirements and deliverables or in other words - the sum of the work required for project completion.</p>
<p><em>Scope is the main element against which projects are priced at <a href="http://www.lionite.com" title="Lionite Internet Ventures">Lionite</a>. </em></p>
<p>The more complicated and/or innovative a project is, the more likely it is that features will change during the project lifetime (sometimes even drastically). </p>
<p>We can allow that to happen by adhering to scope instead of individual features. With good specifications it is much easier to avoid <a target="_blank" href="http://en.wikipedia.org/wiki/Scope_creep">scope-creep</a>.</p>
<h3>Estimating project time-frame and pricing</h3>
<p>Accurate time and cost estimates are important are as important to project success as anything else, and specifications are what it should be based on. </p>
<p>The better the written specifications are, the more accurate those estimates would be. </p>
<h3>Creating a workable reference for development and design</h3>
<p>Working with a good specifications document can do wonders for productivity and focus in the design and development stages. At the very least it can serve as a task list for project completion. </p>
<p>Well thought through description of features and relevant mockups can solve a lot of potential dillemas for both designers and developers and save a lot of time. </p>
<p>The specifications process itself should be used for ironing out as many issues as possible, helping the implementation phase to be as productive as possible.</p>
<h3>Having a standard to test against project delivery</h3>
<p>Specifications outline the agreement between parties on what constitutes a successful project delivery. Contracts, if relevant, will point to the specifications as the legally binding document for this purpose. </p>
<p>A good specifications document can resolve many potential disputes simply by stating clearly what should be delivered.</p>
<h2>How to create better specifications</h2>
<p>Creating good specifications entails some ground work, there's no around it. Keep in mind the effort you put in will pay itself back as the project progresses.</p>
<h3>Break everything down</h3>
<p>Decompose every requirement and feature to a list of small tasks. Add relevant detail that might affect completion time. The level of detail and scope of each task should be enough so that it could be accurately estimated in work hours (and not days, and certainly not weeks).</p>
<p><strong>Research</strong> what you are not sufficiently familiar with. This will greatly help avoid nasty surprises later, and will make your estimates that much more accurate.</p>
<h3>Be thorough</h3>
<p>Try to make sure there are no gaping holes in the specifications - are all requirements and features accounted for? are there any hidden prerequisites you might have over-looked? read everything twice and then give it to a colleague to read.</p>
<p>Don't forget to add more technical detail such as security concerns, coding standards, post-project technical support and supported browsers.</p>
<h3>Compose interactively with clients</h3>
<p>It is very important for the specifications to capture correctly the vision the client has for the project. Specifications writing can be used to correctly align client's expectations with your own. </p>
<p>Your interaction with the client can (and probably will) lead to more insights on project requirements and features. It is not at all uncommon for a project to change direction somewhat during specifications writing - and it is much better that it happens at that time than at mid-project.</p>
<h3>Be clear and concise</h3>
<p>Be clear and and use as much detail as necessary. Be concise, since overly descriptive texts are harder to consume and understand.</p>
<p>Don't skimp on rewording and reorganizing bulky / technical paragraphs and edit out unnecessary detail.</p>
<h3>Read more articles like this one</h3>
<p>Joel Spolsky on painless functional specifications - <a target="_blank" href="http://www.joelonsoftware.com/articles/fog0000000036.html">part 1</a>, <a href="http://www.joelonsoftware.com/articles/fog0000000035.html">part 2</a><br />
Allen Smith on <a target="_blank" href="http://www.mojofat.com/tutorial/">functional specifications</a><br />
Jason Fried of 37Signals on <a target="_blank" href="http://www.37signals.com/svn/archives/001050.php">avoiding functional specifications</a> (basically refuting everything I've written here. A good read for counter arguments.)</p>
 <img src="http://www.techfounder.net/wp-content/plugins/feed-statistics.php?view=1&post_id=233" width="1" height="1" style="display: none;" /><div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F07%2F03%2Fwriting-specifications-for-web-applications%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F07%2F03%2Fwriting-specifications-for-web-applications%2F" height="61" width="51" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.techfounder.net/2009/07/03/writing-specifications-for-web-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multiple row operations in MySQL / PHP</title>
		<link>http://www.techfounder.net/2009/05/14/multiple-row-operations-in-mysql-php/</link>
		<comments>http://www.techfounder.net/2009/05/14/multiple-row-operations-in-mysql-php/#comments</comments>
		<pubDate>Thu, 14 May 2009 01:43:43 +0000</pubDate>
		<dc:creator>Eran Galperin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[insert]]></category>
		<category><![CDATA[multiple rows]]></category>
		<category><![CDATA[on duplicate key]]></category>
		<category><![CDATA[update]]></category>

		<guid isPermaLink="false">http://www.techfounder.net/?p=229</guid>
		<description><![CDATA[Multiple row operations are in common use in a normalized application databases as one database entity is often linked to multiple sub-entities (for example a user and his tags). By row operations I'm referring to write queries, namely UPDATE and INSERT queries (DELETE is less interesting so I'll leave it out for now). Too often [...]]]></description>
			<content:encoded><![CDATA[<p>Multiple row operations are in common use in a normalized application databases as one database entity is often linked to multiple sub-entities (for example a user and his tags). By row operations I'm referring to write queries, namely UPDATE and INSERT queries (DELETE is less interesting so I'll leave it out for now). </p>
<p>Too often I've seen such queries ran in long loops one at a time, which is very bad for performance (as I will show here) and sometimes equally bad for integrity (if the process is interrupted). So what are the alternatives?<br />
<span id="more-229"></span></p>
<h2>Inserting multiple rows</h2>
<p>Insertion of multiple rows comes about often in batch jobs, database migrations and handling table relationships. A naive approach, via PHP, would be to loop over the data to be inserted, inserting one row at a time. Suppose the data is already properly filtered and quoted:</p>
<pre class="php"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #b1b100;">foreach</span><span style="color: #66cc66;">&#40;</span> <span style="color: #0000ff;">$data</span> <span style="color: #b1b100;">as</span> <span style="color: #0000ff;">$row</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">      <span style="color: #0000ff;">$query</span> = <span style="color: #ff0000;">&quot;INSERT INTO `test_table` (user_id,content)&quot;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">          . <span style="color: #ff0000;">&quot; VALUES (&quot;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">          . <span style="color: #0000ff;">$row</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'user_id'</span><span style="color: #66cc66;">&#93;</span> . <span style="color: #ff0000;">&quot;,&quot;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">          . <span style="color: #0000ff;">$row</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'content'</span><span style="color: #66cc66;">&#93;</span> . <span style="color: #ff0000;">&quot;)&quot;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">      <a href="http://www.php.net/mysql_query"><span style="color: #000066;">mysql_query</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$query</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div></li></ol></pre>
<p>Depending on the amount of rows to be inserted, this can be a costly process. A better approach would be to concatenate the values into one insert query and then execute it:</p>
<pre class="php"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #0000ff;">$values</span> = <a href="http://www.php.net/array"><span style="color: #000066;">array</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #b1b100;">foreach</span><span style="color: #66cc66;">&#40;</span> <span style="color: #0000ff;">$data</span> <span style="color: #b1b100;">as</span> <span style="color: #0000ff;">$row</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <span style="color: #0000ff;">$values</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span> =  <span style="color: #ff0000;">&quot;(&quot;</span> . <span style="color: #0000ff;">$row</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'user_id'</span><span style="color: #66cc66;">&#93;</span> . <span style="color: #ff0000;">&quot;,&quot;</span> . <span style="color: #0000ff;">$row</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'content'</span><span style="color: #66cc66;">&#93;</span> . <span style="color: #ff0000;">&quot;)&quot;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span> !<a href="http://www.php.net/empty"><span style="color: #000066;">empty</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$values</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <span style="color: #0000ff;">$query</span> = <span style="color: #ff0000;">&quot;INSERT INTO `test_table` (user_id,content) VALUES &quot;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">             . <a href="http://www.php.net/implode"><span style="color: #000066;">implode</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">','</span>,<span style="color: #0000ff;">$values</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <a href="http://www.php.net/mysql_query"><span style="color: #000066;">mysql_query</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$query</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div></li></ol></pre>
<p>What's the difference? lets see some benchmarks:<br />
<img src="http://www.techfounder.net/wp-content/uploads/2009/05/time.png" alt="time" title="time" width="485" height="205"  /><br />
A single query completes <b>much</b> faster than looping through multiple queries. At 2560 rows inserted, it took the loop ~36 seconds to complete, yet the single query took just 0.14 seconds.</p>
<p>Memory consumption shows a reverse trend however:<br />
<img src="http://www.techfounder.net/wp-content/uploads/2009/05/memory.png" alt="memory" title="memory" width="481" /><br />
Since the values are concatenated to create the single query, it consumes more and more memory with more rows as it needs to hold a larger query string. At 2560 rows inserted, the single query approach consumed ~800kb in memory, while the loop consumed just ~60kb.</p>
<p>Since memory is much cheaper than CPU cycles and database connections, I'd usually opt for the single query approach. It's important though to be aware of the implications.</p>
<h2>Inserting / Updating (multiple) values</h2>
<p>Another use-case of multiple row operations is when we want to insert several rows that might exist already, and in case they exist we want to update existing values instead. Of course, we could check first which rows exist, update the ones that do and insert the ones that don't - for a total of at least three separate queries. </p>
<p>The update query is the major problem here - there is no way to update multiple rows with different values using one query (and it doesn't make much sense in most cases). However in this case it does make sense to do so, and fortunately MySQL provides a way to do just that, using <a href="http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html" target="_blank">INSERT ... ON DUPLICATE KEY UPDATE</a>.</p>
<p>The KEY in this statement should be a unique key in the table you are inserting to (otherwise duplicates would be allowed and this operation would be moot). The syntax of this statement allows to pick which columns are updated in the case of matching rows. For example, suppose I'm adding translations for content pages. I have the following table schema:</p>
<pre class="sql">&nbsp;
pages
 - id
 - content
 - ...
&nbsp;
pages_translations
 - page_id
 - lang_id
 - content
&nbsp;</pre>
<p>The pages_translations table has a primary (unique) key on ( page_id , lang_id ). When adding / updating a translation, the query would look something like:</p>
<pre class="sql"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #ff0000;">`pages_translations`</span> <span style="color: #66cc66;">&#40;</span>page_id,lang_id,content<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">2</span>,<span style="color: #ff0000;">'the brown fox ...'</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">ON</span> DUPLICATE <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #993333; font-weight: bold;">UPDATE</span> content=<span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span>content<span style="color: #66cc66;">&#41;</span>
&nbsp;</pre>
<p>This will create a translation if one does not exist and update the content field if it does exist. We can combine this statement with the previous approach for multiple insertion to insert / update multiple rows with one statement.</p>
<h2>Inserting / Updating with multiple tables</h2>
<p>There are some cases where we would like to use data in one or several tables to update / insert into another table. </p>
<p>With insertion the <a href="http://dev.mysql.com/doc/refman/5.1/en/insert-select.html" target="_blank">syntax is relatively straightforward</a> - replace the VALUES part of the statement with a SELECT statement. </p>
<pre class="sql"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #ff0000;">`my_table`</span> <span style="color: #66cc66;">&#40;</span>col1,col2,col3<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> col4,col5,col6
<span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">`another_table`</span></pre>
<p>The ON DUPLICATE KEY condition can be used with this statement as well.</p>
<p>Updating rows cross-tables is done with a JOIN statement (of the less declarative type).</p>
<pre class="sql"><span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`my_table`</span>,<span style="color: #ff0000;">`other_table`</span>
   <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`my_table`</span>.col1 = <span style="color: #ff0000;">`other_table`</span>.col2
<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #ff0000;">`my_table`</span>.parent_id = <span style="color: #ff0000;">`other_table`</span>.id</pre>
<p>It's important to try the INSERT / UPDATE select statements separately to determine how many rows they will select and how fast will they complete. INSERT / UPDATE operations are relatively costly and can be a severe bottleneck for the database if not managed correctly.</p>
 <img src="http://www.techfounder.net/wp-content/plugins/feed-statistics.php?view=1&post_id=229" width="1" height="1" style="display: none;" /><div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F05%2F14%2Fmultiple-row-operations-in-mysql-php%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F05%2F14%2Fmultiple-row-operations-in-mysql-php%2F" height="61" width="51" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.techfounder.net/2009/05/14/multiple-row-operations-in-mysql-php/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Finding your web business model</title>
		<link>http://www.techfounder.net/2009/05/06/finding-your-web-business-model/</link>
		<comments>http://www.techfounder.net/2009/05/06/finding-your-web-business-model/#comments</comments>
		<pubDate>Tue, 05 May 2009 23:28:26 +0000</pubDate>
		<dc:creator>Eran Galperin</dc:creator>
				<category><![CDATA[Business Development]]></category>
		<category><![CDATA[Lionite]]></category>
		<category><![CDATA[advertising]]></category>
		<category><![CDATA[business model]]></category>
		<category><![CDATA[experiments]]></category>
		<category><![CDATA[startup]]></category>
		<category><![CDATA[subscription]]></category>

		<guid isPermaLink="false">http://www.techfounder.net/?p=236</guid>
		<description><![CDATA[The web as a commercial venue has changed and evolved much in the relatively short time since its inception. As the medium and technology evolved, more and more "real-world" business models became viable for web products. Despite this, the application of those business models in the web arena is still very much experimental, and it's [...]]]></description>
			<content:encoded><![CDATA[<p>The web as a commercial venue has changed and evolved much in the relatively short time since its inception. As the medium and technology evolved, more and more "real-world" business models became viable for web products. </p>
<p>Despite this, the application of those business models in the web arena is still very much experimental, and it's often hard for web businesses to find and implement a model that works well for them.<br />
<span id="more-236"></span></p>
<h2>Got ads?</h2>
<p>The most basic misconception about web business models is that you can never go wrong choosing an advertising-based model. If it was really that easy, then everybody would be making mad cash - however, advertising based revenue is actually hard to come by. </p>
<p>In fact, those who can actually make it stick are few and far between (Mike Speiser <a href="http://laserlike.com/2008/09/14/the-advertising-equivalence-principle/" target="_blank">shows the numbers don't lie</a>). The amount of traffic you need to generate in order to make substantial revenue from online advertising is out of reach for the vast majority of websites.</p>
<p>So when is an advertising model appropriate? </p>
<ul>
<li>When generating traffic is the <b>main purpose</b> of your web service. Such sites include all flavors of traditional content sites, social networks, user-generated content sites and the like.</li>
<li>When your service has the ability to deliver <b>targeted advertising</b>. Targeting advertising at user activity, search criteria and the like, greatly increase the relevancy of ads and thus conversion rates. A <a href="http://www.google.com" target="_blank" title="Google">little-known company</a> has made targeted advertising <a href="http://investor.google.com/fin_data.html" target="_blank" title="Google financial data">its main business</a> to devastating effect.</li>
<li>Advertising is incorporated as a part of a hybrid model, to subsidize free parts of the service (see below for more details).</li>
</ul>
<p>The important attribute here is that advertising must target a large enough audience with sufficient relevancy in order to generate significant revenue. </p>
<h2>Subscription is king</h2>
<p>Subscription business models are nothing new but have been gaining popularity on the web, especially with the proliferation of on-demand online services in which subscription payments often make the most sense.</p>
<p>A subscription-based model is often appropriate when the service / content offered is unique and hard to find elsewhere. For site visitors to shell out even a few dollars, they need to be convinced that they are getting something they can't get elsewhere (since much of the web is available for free). This is doubly true since the process of handing out payments details online is often a barrier by itself.</p>
<p>Whether it's entertainment or productivity, when the value to users is higher than or equal to the monetary cost subscription becomes a very viable model. Niche sites and web services often fall in this category when they provide something of value.</p>
<p>I'd note here that by subscription model I don't necessarily mean just recurring annual subscriptions - there are also milestone-based subscriptions (pay-as-you-go) and feature-based subscriptions (pay-per-feature). Those three types can be mixed together to create many different hybrids, with the common denominator being the "subscribed user" - a person willing to spend money to use the service.</p>
<h2>The freemium model</h2>
<p>Freemium is a trendy new name for a familiar model - offer basic or limited services for free, and charge for advanced (premium) features. <a href="http://www.avc.com/a_vc/2006/03/my_favorite_bus.html" target="_blank">The freemium model</a> is often a derivative of the subscription model, with the basic subscription plan as the free part of it. </p>
<p>Using a freemium model can be very useful for businesses who are counting on long-term users instead of one-time purchases. By getting limited services for free, a user can have a taste of what the web service has to offer thus lowering the barrier of entry. The balance of free to premium is important in creating the right incentive for paying for the premium services (example - <a href="http://www.basecamphq.com/signup" target="_blank">basecamp</a>). </p>
<p>One common application of the freemium model is combining the subscription and advertising models, by offering free services that display ads and premium services that are ad-free - this basically allows the site user to decide how he will support the service.</p>
<p>When we are conducting business development with clients I Personally lean mostly to subscription based freemium model, as </p>
<h2>The brokers</h2>
<p>Brokers are services that bring together buyers and sellers thus creating a marketplace. Revenue is generated by charging usage of the marketplace in a variety of ways:</p>
<ul>
<li>Sellers can be charged for being listed by the broker (one time / per listing)</li>
<li>Buyers can be charged for gaining access to the listing of sellers</li>
<li>Fee / commission on successful transactions</li>
</ul>
<p>The best known example of the broker model is <a href="http://www.ebay.com">Ebay</a>, a giant marketplace that succeeds on the strength of its reputation system and internal policing. A couple of good examples for creative application of the broker model are threadless and crowdspring (which I described in a <a href="http://www.techfounder.net/2008/08/23/a-web-20-business-model-can-work-and-work-well/">previous post on web business models</a>).</p>
<h2>The partnership, the exit</h2>
<p>Partnerships can be the basis of viable business model in certain circumstances - such as affiliates and sponsorships, or can be another part of the whole for others. It is often used as a hybrid with other models (such as advertising or subscription) being the driving force behind revenue.</p>
<p>An extreme case of this model is the outright takeover of the business by another company, often called "<a href="http://www.startupnation.com/articles/920/1/AT_WhatIsYourExitStrategy.asp" target="_blank">an exit</a>". Though some businesses set out with this strategy in mind, its very unpredictable nature makes it very risky without an adequate backup model. I call this strategy the "no-model" model, with businesses basically saying that they'll figure out as they go along, hoping that some giant company will swoop in and end all their problems.</p>
<h2>Picking the right one</h2>
<p>Deciding on a web business model can be tough for early stage start-ups and traditional offline businesses transitioning to the web. Each model has its pros and cons and the fear of making a mistake can be paralyzing. Sometimes the perfect business model is very obvious but more often than not it's a journey of self discovery for the business.</p>
<p>When <a href="http://www.lionite.com" target="_blank" title="Lionite Internet Ventures">we</a> engage in business development with our clients, we usually ask them the following questions:</p>
<ul>
<li>What is your target audience?</li>
<li>How much would you pay for your service?</li>
<li>Who are your competitors? What is their business model?</li>
<li>When (or how fast) do you expect web revenue to cover operating expenses?</li>
</ul>
<p>Those are mostly introductory questions, aimed at helping the business orient itself on what it needs to know to determine its business model. </p>
<h2>Analyze, improve, rinse, repeat</h2>
<p>Choosing a business model is only the beginning. Constant collection and analysis of related data - such as conversion and churn rates,  usage data and statistics - is essential for tweaking and evolving the business model and increasing its chances of success. The process of testing how much customers are willing to pay for services is sometimes called <a href="http://venturehacks.com/articles/pricing" target="_blank">bounding-box pricing</a>.</p>
<p>There are no strict rules for choosing a business model, so don't be afraid to experiment and look for business opportunities in unexpected places. You never know when or where your big break will happen, but if you believe in your product and your team your business model will reveal itself eventually - be prepared for it when it happens.</p>
 <img src="http://www.techfounder.net/wp-content/plugins/feed-statistics.php?view=1&post_id=236" width="1" height="1" style="display: none;" /><div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F05%2F06%2Ffinding-your-web-business-model%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.techfounder.net%2F2009%2F05%2F06%2Ffinding-your-web-business-model%2F" height="61" width="51" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.techfounder.net/2009/05/06/finding-your-web-business-model/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
