<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Quick Brown Frog</title>
	<atom:link href="http://blog.quickbrownfrog.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.quickbrownfrog.com</link>
	<description>developing software for learning to type online</description>
	<lastBuildDate>Sat, 20 Aug 2011 09:09:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.quickbrownfrog.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Quick Brown Frog</title>
		<link>http://blog.quickbrownfrog.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.quickbrownfrog.com/osd.xml" title="Quick Brown Frog" />
	<atom:link rel='hub' href='http://blog.quickbrownfrog.com/?pushpress=hub'/>
		<item>
		<title>How to make Ajax links crawlable with GWT and Google App Engine</title>
		<link>http://blog.quickbrownfrog.com/2011/01/07/how-to-make-ajax-links-crawlable-with-gwt-and-google-app-engine/</link>
		<comments>http://blog.quickbrownfrog.com/2011/01/07/how-to-make-ajax-links-crawlable-with-gwt-and-google-app-engine/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 23:18:11 +0000</pubDate>
		<dc:creator>George Armhold</dc:creator>
				<category><![CDATA[Google App Engine]]></category>
		<category><![CDATA[GWT]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://quickbrownfrog.wordpress.com/?p=180</guid>
		<description><![CDATA[If you care about SEO you know that using GWT has a downside: much of your app&#8217;s content is generated dynamically via Javascript, and is therefore invisible to search engines. You might have dozens of pages of awesome content, but &#8230; <a href="http://blog.quickbrownfrog.com/2011/01/07/how-to-make-ajax-links-crawlable-with-gwt-and-google-app-engine/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=180&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you care about <a href="http://en.wikipedia.org/wiki/Search_engine_optimization">SEO</a> you know that using GWT has a downside: much of your app&#8217;s content is generated dynamically via Javascript, and is therefore invisible to search engines. You might have dozens of pages of awesome content, but all the Googlebot sees is the static HTML page that hosts your app. This can be a real problem.</p>
<p>Fortunately, Google has proposed a <a href="http://code.google.com/web/ajaxcrawling/docs/getting-started.html">solution</a> for crawling ajax content:</p>
<ul>
<li>change your hrefs to support &#8220;bang notation&#8221;:  <span style="font-size:13px;color:#007000;font-family:monospace;line-height:19px;white-space:pre;">www.example.com/ajax.html<strong>#!key=value</strong></span></li>
<li><span style="color:#000000;font-size:small;"><span style="font-size:13px;line-height:19px;white-space:pre;"><strong><span style="font-size:medium;"><span style="font-size:16px;font-weight:normal;line-height:24px;white-space:normal;">when Googlebot makes requests of the form: </span></span></strong></span></span><span style="font-size:13px;color:#007000;font-family:monospace;line-height:19px;white-space:pre;">www.example.com/ajax.html<strong>?_escaped_fragment_=key=value </strong></span><span style="font-size:13px;line-height:19px;white-space:pre;"><strong><span style="color:#444444;font-family:Georgia, 'Bitstream Charter', serif;line-height:1.5;font-size:medium;"><span style="color:#444444;font-family:Georgia, 'Bitstream Charter', serif;line-height:24px;font-size:16px;font-weight:normal;white-space:normal;">, you return a static HTML version of the Ajax content</span></span></strong></span></li>
</ul>
<p>So then the problem becomes one of generating static content from your Ajax links. You could do that by hand if your site is small and changes infrequently. More likely you&#8217;ll want a way to automate this.</p>
<p>Google recommends using a &#8220;headless browser&#8221; approach, i.e. using something like <a href="http://htmlunit.sourceforge.net/">HtmlUnit</a>. That&#8217;s a fine solution, but if you&#8217;re running on App Engine <em>it&#8217;s almost guaranteed not to work</em> because of the request timeout.  So if you want to run on App Engine, you&#8217;re probably going to have to spider your own pages and pre-generate your HTML content.</p>
<p>My solution to this problem is to break the spidering up into small chunks, and farm them out as tasks on App Engine&#8217;s <a href="http://code.google.com/appengine/docs/java/taskqueue/overview.html">Task Queues</a>. Whenever I update my app&#8217;s content, I submit a job that spiders the landing page looking for Ajax links. For each link that&#8217;s found, I submit a task that recursively spiders the link (taking care not to get into loops). Each task saves the HTML content into the data store, which is then returned as cached static content to Googlebot.</p>
<p>Suddenly my &#8220;simple&#8221; solution is sounding quite complicated, but it gets the job done reliably. Here&#8217;s some code to make it clearer.</p>
<p>I use a CachedAjaxLink data object to persist the static content:</p>
<pre style="padding-left:30px;">public class CachedAjaxLink implements Serializable
{
    @Id
    private String href;
    private String cachedContent;
    private Date dateCached;
}</pre>
<p>Then I use an AjaxCacher which crawls a given link, stores the results as CachedAjaxLinks, and queues Task Queue tasks for each link that it finds:</p>
<pre style="padding-left:30px;">public class AjaxCacher
{
    protected static final Logger log = Logger.getLogger(AjaxCacher.class.getName());
    protected static final DAO dao = new DAO();

    public static final long PUMP_TIME = 5000;
    protected WebClient webClient;
    protected String crawlServletUrl;

    public AjaxCacher(String crawlServletUrl)
    {
        this.crawlServletUrl = crawlServletUrl;
        webClient = Holder.get();
    }

    public void crawl(URL urlToCrawl, Date crawlRequestTimestamp)
    {
        // URLs we've already queued
        Set queuedURLs = new HashSet();
        queuedURLs.add(urlToCrawl);

        try
        {
            HtmlPage page = webClient.getPage(urlToCrawl);

            // appengine hack because it's single threaded
            webClient.getJavaScriptEngine().pumpEventLoop(PUMP_TIME);

            String pageContent = page.asXml();

            CachedAjaxLink cachedAjaxLink = new CachedAjaxLink();
            cachedAjaxLink.setHref(urlToCrawl.getRef());
            cachedAjaxLink.setCachedContent(pageContent);
            cachedAjaxLink.setDateCached(new Date());  // time actually cached
            dao.updateCachedAjaxLink(cachedAjaxLink);

            List anchors = page.getAnchors();
            for (HtmlAnchor anchor : anchors)
            {
                // only care about ajax links
                if (! anchor.getHrefAttribute().startsWith("#")) continue;

                URL newUrl = new URL(urlToCrawl, anchor.getHrefAttribute());

                // don't queue multiple requests for the same URL
                if (queuedURLs.contains(newUrl)) continue;

                queuedURLs.add(newUrl);

                // prevent loops
                CachedAjaxLink link = dao.getCachedAjaxLink(newUrl.getRef());
                if (link == null || link.getDateCached().getTime() &lt; crawlRequestTimestamp.getTime())
                {
                    queueCrawlRequest(newUrl.toString(), crawlRequestTimestamp);
                }
            }

        } catch (IOException e)
        {
            log.log(Level.SEVERE, e.getMessage(), e);
        }
        finally
        {
            webClient.closeAllWindows();
        }
    }

    /**
     * submits a crawl request to the queue; TaskQueueServlet will then handle the request asynchronously
     */
    public void queueCrawlRequest(String urlToCrawl, Date timeStamp)
    {
        Queue queue = QueueFactory.getDefaultQueue();
        TaskOptions options = TaskOptions.Builder.url(crawlServletUrl);
        options.param("encodedUrl", ServerUtils.encodeURL(urlToCrawl));
        options.param("timeStamp", ServerUtils.fromDate(timeStamp));
        options.method(TaskOptions.Method.GET);
        queue.add(options);
    }

    /**
     * try to cache a copy of the WebClient in ThreadLocal for faster startups on Google App Engine
     */
    public static class Holder
    {
        private static ThreadLocal holder = new ThreadLocal()
        {
            protected synchronized WebClient initialValue()
            {
                WebClient result = new WebClient(BrowserVersion.FIREFOX_3);
                result.setWebConnection(new UrlFetchWebConnection(result));
                return result;
            }
        };

        public static WebClient get()
        {
            return holder.get();
        }
    }
}</pre>
<p>Finally, I use a TaskQueueServlet to handle the queued tasks:</p>
<pre style="padding-left:30px;">public class TaskQueueServlet extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
    {
        doPost(req, res);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
    {
        String encodedUrl = req.getParameter("encodedUrl");
        if (encodedUrl == null)
        {
            throw new IllegalArgumentException("missing param: encodedUrl");
        }

        String timeStamp = req.getParameter("timeStamp");
        if (timeStamp == null)
        {
            throw new IllegalArgumentException("missing param: timeStamp");
        }

        String decodedUrl = ServerUtils.decodeURL(encodedUrl);
        URL urlToCrawl = new URL(decodedUrl);

        getServletContext().getInitParameter("taskQueuePath");
        AjaxCacher cacher = new AjaxCacher(getServletContext().getInitParameter("taskQueuePath"));
        cacher.crawl(urlToCrawl, ServerUtils.toDate(timeStamp));
    }
}</pre>
<p>Thanks Google, for making it so easy. <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>You can grab all of this code from my <a title="GWT Quickstarter" href="http://code.quickbrownfrog.com/">gwtquickstarter</a> library. It&#8217;s the library that powers the <a href="http://www.quickbrownfrog.com">best typing tutor</a> on the web.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/quickbrownfrog.wordpress.com/180/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/quickbrownfrog.wordpress.com/180/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/quickbrownfrog.wordpress.com/180/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/quickbrownfrog.wordpress.com/180/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/quickbrownfrog.wordpress.com/180/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/quickbrownfrog.wordpress.com/180/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/quickbrownfrog.wordpress.com/180/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/quickbrownfrog.wordpress.com/180/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/quickbrownfrog.wordpress.com/180/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/quickbrownfrog.wordpress.com/180/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/quickbrownfrog.wordpress.com/180/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/quickbrownfrog.wordpress.com/180/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/quickbrownfrog.wordpress.com/180/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/quickbrownfrog.wordpress.com/180/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=180&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.quickbrownfrog.com/2011/01/07/how-to-make-ajax-links-crawlable-with-gwt-and-google-app-engine/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/35752f1794d9a5f8ab8fe8edf272f0cc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">quickbrownfrog</media:title>
		</media:content>
	</item>
		<item>
		<title>Top 10 Ways to Improve Your Typing</title>
		<link>http://blog.quickbrownfrog.com/2010/12/28/top-10-ways-to-improve-your-typing/</link>
		<comments>http://blog.quickbrownfrog.com/2010/12/28/top-10-ways-to-improve-your-typing/#comments</comments>
		<pubDate>Wed, 29 Dec 2010 00:08:05 +0000</pubDate>
		<dc:creator>George Armhold</dc:creator>
				<category><![CDATA[Typing]]></category>

		<guid isPermaLink="false">http://blog.quickbrownfrog.com/?p=257</guid>
		<description><![CDATA[Everyone loves top-10 lists, so here&#8217;s the Quick Brown Frog list of Top-10 Ways to Improve Your Typing. 1. Slow Down This may seem counter-intuitive, but most new typists need to actually slow down in order to see an improvement &#8230; <a href="http://blog.quickbrownfrog.com/2010/12/28/top-10-ways-to-improve-your-typing/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=257&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Everyone loves top-10 lists, so here&#8217;s the <a href="http://quickbrownfrog.com">Quick Brown Frog</a> list of <strong>Top-10 Ways to Improve Your Typing</strong>.</p>
<h2>1. Slow Down</h2>
<p>This may seem counter-intuitive, but most new typists need to actually <em>slow down</em> in order to see an improvement in their typing skills. Your Words-Per-Minute score also takes into account the number of typos and corrections you make. A slower speed tends to lead to fewer typos, and an overall <em>increase</em> in typing speed.</p>
<h2>2. Pretend you don&#8217;t have a backspace key</h2>
<p>In the bad old days of manual typewriters there was no such thing as backspacing to correct a typo; you had to apply some white-out or else start over from scratch. Some typists have become overly dependent upon their backspace key. If you find yourself making lots of mistakes, pretend that you don&#8217;t have a backspace key, and that every character you type must be perfect. This may slow you down in the short-term, but it will pay dividends as you better learn the keyboard.</p>
<h2>3. Unlearn Bad Habits</h2>
<p>Most people learn to type in a very ad-hoc manner. Often we learn the location of the keys through hunt-and-peck, rather than deliberately practicing proper typing technique. This also means typing keys with the wrong fingers. When these habits are learned early, they&#8217;re very hard to break. Make a concentrated effort to use the proper fingering and position for each key-press.</p>
<h2>4. Use Both Shift Keys</h2>
<p>Every keyboard comes with two shift keys for a good reason- certain key combinations are meant to be typed <em>with two hands. </em>This is something that even experienced typists often get wrong. It&#8217;s <strong>not</strong> OK to use only the left or right shift key for all your typing!</p>
<p>Our <a href="http://quickbrownfrog#!lessons:">typing lessons</a> clearly explain which shift key to use with each letter or symbol. As each key is introduced, its corresponding shift key is also given. Generally speaking, if the key is on the <em>left</em> side of the keyboard you should use the <em>right</em> shift key with it, and vice-versa.</p>
<h2>5. Practice on Unfamiliar Text</h2>
<p>If you&#8217;re trying to break some old habits, typing commonly-used words and phrases may actually be counter-productive, since you&#8217;ll just be reinforcing your improper technique. Muscle memory tends to take over when typing familiar things such as your email address, or web site URLs that you commonly use.</p>
<p>Instead, try typing unfamiliar text so that muscle memory doesn&#8217;t get in the way of unlearning your old technique. Quick Brown Frog offers a <a href="http://quickbrownfrog.com#!practice:">huge selection of practice text</a> with new content added every week. You can also practice with unfamiliar content by using our <a href="http://quickbrownfrog.com#!practice:">random words</a> feature.</p>
<h2>6. Use the Home Row</h2>
<p>There&#8217;s a reason that the <a href="http://www.quickbrownfrog.com/#!typing:lesson:lesson001:0">Home Row</a> is the very first lesson taught by every typing course- it forms the basis of proper finger placement, and allows you to easily reach all the keys of the keyboard.</p>
<p>Always start with your fingers above the Home Row- <strong>asdf</strong> for the left hand, and <strong>jkl;</strong> for the right. Always return your fingers to this position after typing keys on the other rows.</p>
<h2>7. Strive for Economy of Movement</h2>
<p>&#8220;Economy of movement&#8221; is a fancy way of saying &#8220;try to move your hands as little as possible&#8221;. If you&#8217;re a &#8220;two finger typist&#8221;, chances are you&#8217;re having to move your hands all over the place to reach the keys.</p>
<p>The idea with economy of movement is that you want to make use of <em>all of your fingers</em>, and <em>both hands</em>, rather than favoring your &#8220;strong&#8221; fingers (typically your index and middle fingers).</p>
<p>It&#8217;s no coincidence that this is the exact same concept that musicians use when learning their instruments.</p>
<h2>8. Relax and Stretch</h2>
<p>Like any physical activity, typing requires you to use your muscles. Your muscles work their best when you&#8217;re relaxed. Take breaks frequently, and <a href="http://exercise.about.com/od/flexibilityworkouts/tp/officestretches.htm">stretch your muscles</a>.</p>
<h2>9. Watch the screen, not the keyboard</h2>
<p>Many new typists spend way too much time looking at the keyboard rather than the screen. In addition to slowing down your learning the location of the keys, this habit encourages bad posture, as your head is constantly tilting up and down to go from the screen to the keyboard.</p>
<p>Instead, watch the screen to see what you&#8217;re typing. That might mean that you have to slow down your typing initially until you learn all the keys, but it will pay dividends in the long run.</p>
<h2>10. Practice daily</h2>
<p>Like any skill, developing good typing ability requires a certain amount of dedication and practice. As with practicing a musical instrument, short-but-daily sessions are better than long marathon sessions done infrequently. Try to set aside a certain amount of time each day to spend practicing with Quick Brown Frog, and you&#8217;ll be a typing expert in no time!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/quickbrownfrog.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/quickbrownfrog.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/quickbrownfrog.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/quickbrownfrog.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/quickbrownfrog.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/quickbrownfrog.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/quickbrownfrog.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/quickbrownfrog.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/quickbrownfrog.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/quickbrownfrog.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/quickbrownfrog.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/quickbrownfrog.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/quickbrownfrog.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/quickbrownfrog.wordpress.com/257/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=257&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.quickbrownfrog.com/2010/12/28/top-10-ways-to-improve-your-typing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/35752f1794d9a5f8ab8fe8edf272f0cc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">quickbrownfrog</media:title>
		</media:content>
	</item>
		<item>
		<title>Add a badge to your blog with your typing score!</title>
		<link>http://blog.quickbrownfrog.com/2010/12/28/add-a-badge-to-your-blog-with-your-typing-score/</link>
		<comments>http://blog.quickbrownfrog.com/2010/12/28/add-a-badge-to-your-blog-with-your-typing-score/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 20:45:09 +0000</pubDate>
		<dc:creator>George Armhold</dc:creator>
				<category><![CDATA[Typing]]></category>

		<guid isPermaLink="false">http://blog.quickbrownfrog.com/?p=249</guid>
		<description><![CDATA[Did you get an awesome word-per-minute score on your Quick Brown Frog typing speed test? Well now you can share it with the world by posting a Quick Brown Frog badge on your blog or website: We just added a &#8230; <a href="http://blog.quickbrownfrog.com/2010/12/28/add-a-badge-to-your-blog-with-your-typing-score/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=249&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Did you get an awesome word-per-minute score on your Quick Brown Frog typing speed test? Well now you can share it with the world by posting a Quick Brown Frog badge on your blog or website:<br />
<a href="http://quickbrownfrog.com#!practice:"><img class="aligncenter size-full wp-image-250" title="typing-badge" src="http://quickbrownfrog.files.wordpress.com/2010/12/typing-badge.png?w=640" alt=""   /></a></p>
<p>We just added a <a href="http://quickbrownfrog.com#!practice:">new feature</a> to all our typing practice sessions- at the end of the lesson you&#8217;ll be shown the badge and the HTML code that generates it. Simply copy and paste the blue HTML code into your blog or website to add the badge for all to see.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/quickbrownfrog.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/quickbrownfrog.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/quickbrownfrog.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/quickbrownfrog.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/quickbrownfrog.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/quickbrownfrog.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/quickbrownfrog.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/quickbrownfrog.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/quickbrownfrog.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/quickbrownfrog.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/quickbrownfrog.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/quickbrownfrog.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/quickbrownfrog.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/quickbrownfrog.wordpress.com/249/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=249&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.quickbrownfrog.com/2010/12/28/add-a-badge-to-your-blog-with-your-typing-score/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/35752f1794d9a5f8ab8fe8edf272f0cc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">quickbrownfrog</media:title>
		</media:content>

		<media:content url="http://quickbrownfrog.files.wordpress.com/2010/12/typing-badge.png" medium="image">
			<media:title type="html">typing-badge</media:title>
		</media:content>
	</item>
		<item>
		<title>New Feature: create a typing practice from random English words</title>
		<link>http://blog.quickbrownfrog.com/2010/12/28/new-feature-create-a-typing-practice-from-random-english-words/</link>
		<comments>http://blog.quickbrownfrog.com/2010/12/28/new-feature-create-a-typing-practice-from-random-english-words/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 20:30:10 +0000</pubDate>
		<dc:creator>George Armhold</dc:creator>
				<category><![CDATA[Typing]]></category>

		<guid isPermaLink="false">http://blog.quickbrownfrog.com/?p=236</guid>
		<description><![CDATA[We&#8217;ve been busy adding new features over the Christmas holidays. The first of these is already available for you to use: you can now create a practice typing session from a set of random English words: We&#8217;ve had numerous requests &#8230; <a href="http://blog.quickbrownfrog.com/2010/12/28/new-feature-create-a-typing-practice-from-random-english-words/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=236&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve been busy adding new features over the Christmas holidays. The first of these is already available for you to use: you can now create a practice typing session from a set of <a href="http://www.quickbrownfrog.com/#!practice:">random English words</a>:</p>
<p><a href="http://quickbrownfrog.com#!practice:"><img class="aligncenter size-full wp-image-241" title="type-random-words" src="http://quickbrownfrog.files.wordpress.com/2010/12/type-random-words1.png?w=640&#038;h=113" alt="type random words" width="640" height="113" /></a></p>
<p>We&#8217;ve had numerous requests from users for a feature that would generate random typing lessons based on actual words. You can now generate instant typing practices, simply by choosing the number of words you wish to type.</p>
<p><a href="http://quickbrownfrog.com#!practice:"><img class="aligncenter size-full wp-image-237" title="random-word-lesson" src="http://quickbrownfrog.files.wordpress.com/2010/12/random-word-lesson.png?w=640&#038;h=452" alt="Random word typing practice" width="640" height="452" /></a></p>
<p>We&#8217;re planning to extend this feature in the future to create automatically create lessons targeting letters that you need to practice (the ones you make the most typos with).</p>
<p>Enjoy!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/quickbrownfrog.wordpress.com/236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/quickbrownfrog.wordpress.com/236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/quickbrownfrog.wordpress.com/236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/quickbrownfrog.wordpress.com/236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/quickbrownfrog.wordpress.com/236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/quickbrownfrog.wordpress.com/236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/quickbrownfrog.wordpress.com/236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/quickbrownfrog.wordpress.com/236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/quickbrownfrog.wordpress.com/236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/quickbrownfrog.wordpress.com/236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/quickbrownfrog.wordpress.com/236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/quickbrownfrog.wordpress.com/236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/quickbrownfrog.wordpress.com/236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/quickbrownfrog.wordpress.com/236/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=236&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.quickbrownfrog.com/2010/12/28/new-feature-create-a-typing-practice-from-random-english-words/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/35752f1794d9a5f8ab8fe8edf272f0cc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">quickbrownfrog</media:title>
		</media:content>

		<media:content url="http://quickbrownfrog.files.wordpress.com/2010/12/type-random-words1.png" medium="image">
			<media:title type="html">type-random-words</media:title>
		</media:content>

		<media:content url="http://quickbrownfrog.files.wordpress.com/2010/12/random-word-lesson.png" medium="image">
			<media:title type="html">random-word-lesson</media:title>
		</media:content>
	</item>
		<item>
		<title>Quick Brown Frog is now available in the Chrome Web Store</title>
		<link>http://blog.quickbrownfrog.com/2010/12/09/quick-brown-frog-is-now-available-in-the-chrome-web-store/</link>
		<comments>http://blog.quickbrownfrog.com/2010/12/09/quick-brown-frog-is-now-available-in-the-chrome-web-store/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 21:46:25 +0000</pubDate>
		<dc:creator>George Armhold</dc:creator>
				<category><![CDATA[Business/Marketing]]></category>
		<category><![CDATA[Chrome Web Store]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://quickbrownfrog.wordpress.com/?p=225</guid>
		<description><![CDATA[The best typing tutor on the web is now available for sale in the Chrome Web Store. It was surprisingly easy to get into the store if you&#8217;ve got an existing webapp running: pay Google $5 (one-time developer fee; not &#8230; <a href="http://blog.quickbrownfrog.com/2010/12/09/quick-brown-frog-is-now-available-in-the-chrome-web-store/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=225&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.quickbrownfrog.com">best typing tutor on the web</a> is now available for sale in the <a href="https://chrome.google.com/webstore/detail/cngicknllndfldloclinjdfgjdbagkfn">Chrome Web Store</a>.</p>
<p><a href="https://chrome.google.com/webstore/detail/cngicknllndfldloclinjdfgjdbagkfn"><img class="aligncenter size-medium wp-image-226" title="Quick Brown Frog" src="http://quickbrownfrog.files.wordpress.com/2010/12/screen-shot-2010-12-09-at-4-33-25-pm.png?w=300&#038;h=144" alt="" width="300" height="144" /></a></p>
<p>It was surprisingly easy to <a href="http://code.google.com/chrome/webstore/docs/get_started_simple.html">get into the store</a> if you&#8217;ve got an existing webapp running:</p>
<ul>
<li>pay Google $5 (one-time developer fee; <strong>not</strong> per-app)</li>
<li>create a 16-line JSON manifest file</li>
<li>take some screen shots and create an icon (the hardest part, really)</li>
<li>bundle it into a zip</li>
<li>checkmark a few boxes, add some descriptive text, click &#8220;publish&#8221;</li>
</ul>
<p>All you are really doing is bundling up some meta-data so that Chrome users can see your app as being &#8220;installed&#8221;. Even though my app is very much server-dependent, and has its own concept of user accounts and payments, Google is happy to have it in the store. And I&#8217;m happy for the potential extra customers.</p>
<p>It&#8217;s obvious that the Chrome Web Store is a great boon for developers. However it&#8217;s unclear whether users will actually find this useful, much less flock to it.</p>
<p>My guess is that once we start seeing more apps that <em>really</em> use HTML5 features like local storage, it might take off. I hope it does.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/quickbrownfrog.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/quickbrownfrog.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/quickbrownfrog.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/quickbrownfrog.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/quickbrownfrog.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/quickbrownfrog.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/quickbrownfrog.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/quickbrownfrog.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/quickbrownfrog.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/quickbrownfrog.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/quickbrownfrog.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/quickbrownfrog.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/quickbrownfrog.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/quickbrownfrog.wordpress.com/225/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=225&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.quickbrownfrog.com/2010/12/09/quick-brown-frog-is-now-available-in-the-chrome-web-store/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/35752f1794d9a5f8ab8fe8edf272f0cc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">quickbrownfrog</media:title>
		</media:content>

		<media:content url="http://quickbrownfrog.files.wordpress.com/2010/12/screen-shot-2010-12-09-at-4-33-25-pm.png?w=300" medium="image">
			<media:title type="html">Quick Brown Frog</media:title>
		</media:content>
	</item>
		<item>
		<title>Patrick McKenzie launches Appointment Reminder</title>
		<link>http://blog.quickbrownfrog.com/2010/12/06/patrick-mckenzie-launches-appointment-reminder/</link>
		<comments>http://blog.quickbrownfrog.com/2010/12/06/patrick-mckenzie-launches-appointment-reminder/#comments</comments>
		<pubDate>Mon, 06 Dec 2010 15:43:37 +0000</pubDate>
		<dc:creator>George Armhold</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://quickbrownfrog.wordpress.com/?p=219</guid>
		<description><![CDATA[Patrick McKenzie, a solo entrepreneur whom I admire greatly has launched his second project: Appointment Reminder. Appointment Reminder is a service for personal business services (think: hair salons, medical offices, law firms, or anyone that regularly schedules appointments with clients). &#8230; <a href="http://blog.quickbrownfrog.com/2010/12/06/patrick-mckenzie-launches-appointment-reminder/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=219&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Patrick McKenzie, a solo entrepreneur whom I admire greatly has launched his second project: <a href="https://www.appointmentreminder.org/">Appointment Reminder</a>.</p>
<p>Appointment Reminder is a service for personal business services (think: hair salons, medical offices, law firms, or anyone that regularly schedules appointments with clients). Appointment Reminder sends out reminders to clients automatically, via phone, SMS or email. Fewer forgotten appointments = increased revenue.</p>
<p>He&#8217;s leveraging <a href="http://www.twilio.com/">Twilio</a>, and API that I&#8217;m just dying to find an excuse to use.</p>
<p>Congrats Patrick, and good luck!</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/quickbrownfrog.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/quickbrownfrog.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/quickbrownfrog.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/quickbrownfrog.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/quickbrownfrog.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/quickbrownfrog.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/quickbrownfrog.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/quickbrownfrog.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/quickbrownfrog.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/quickbrownfrog.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/quickbrownfrog.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/quickbrownfrog.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/quickbrownfrog.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/quickbrownfrog.wordpress.com/219/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=219&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.quickbrownfrog.com/2010/12/06/patrick-mckenzie-launches-appointment-reminder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/35752f1794d9a5f8ab8fe8edf272f0cc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">quickbrownfrog</media:title>
		</media:content>
	</item>
		<item>
		<title>UI Refresh- new logo and other eye candy</title>
		<link>http://blog.quickbrownfrog.com/2010/11/30/ui-refresh-new-logo-and-other-eye-candy/</link>
		<comments>http://blog.quickbrownfrog.com/2010/11/30/ui-refresh-new-logo-and-other-eye-candy/#comments</comments>
		<pubDate>Tue, 30 Nov 2010 21:31:35 +0000</pubDate>
		<dc:creator>George Armhold</dc:creator>
				<category><![CDATA[Business/Marketing]]></category>

		<guid isPermaLink="false">http://quickbrownfrog.wordpress.com/?p=154</guid>
		<description><![CDATA[I spent some time (and some $$) prettying up the Quick Brown Frog user interface. I bought a logo from Logosamurai.  Not bad for $67. Then I added some gauges to display WPM and accuracy in real-time. They&#8217;re part of the Google &#8230; <a href="http://blog.quickbrownfrog.com/2010/11/30/ui-refresh-new-logo-and-other-eye-candy/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=154&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I spent some time (and some $$) prettying up the <a href="http://www.quickbrownfrog.com">Quick Brown Frog</a> user interface. I bought a logo from <a href="http://www.logosamurai.com/">Logosamurai</a>.  Not bad for $67.</p>
<p><a href="http://quickbrownfrog.files.wordpress.com/2010/11/alternat-edit.jpg"><img class="aligncenter size-full wp-image-162" title="Quick Brown Frog logo" src="http://quickbrownfrog.files.wordpress.com/2010/11/alternat-edit.jpg?w=640" alt="Quick Brown Frog logo"   /></a></p>
<p>Then I added some gauges to display WPM and accuracy in real-time. They&#8217;re part of the <a href="http://code.google.com/apis/visualization/documentation/gadgetgallery.html">Google Visualization API</a>, and they&#8217;re awesome.  That is, when they work. They don&#8217;t seem to work in IE8, so I&#8217;ve disabled them for that browser.</p>
<p>And they have some pretty odd resizing behavior: if you don&#8217;t explicitly specify a width attribute, the gauges will <em>shrink</em> every time you update the gauge value. It took me quite a bit of experimentation to figure that one out, but thankfully it seems to be working now.</p>
<p style="text-align:center;"><a href="http://quickbrownfrog.files.wordpress.com/2010/11/gauges.png"><img class="aligncenter size-medium wp-image-158" title="speed test gauges" src="http://quickbrownfrog.files.wordpress.com/2010/11/gauges.png?w=300&#038;h=53" alt="speed test gauges" width="300" height="53" /></a></p>
<p>You can check out the changes in this <a title="typing speed test" href="http://www.quickbrownfrog.com/#!speedTest:">typing speed test</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/quickbrownfrog.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/quickbrownfrog.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/quickbrownfrog.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/quickbrownfrog.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/quickbrownfrog.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/quickbrownfrog.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/quickbrownfrog.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/quickbrownfrog.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/quickbrownfrog.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/quickbrownfrog.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/quickbrownfrog.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/quickbrownfrog.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/quickbrownfrog.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/quickbrownfrog.wordpress.com/154/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=154&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.quickbrownfrog.com/2010/11/30/ui-refresh-new-logo-and-other-eye-candy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/35752f1794d9a5f8ab8fe8edf272f0cc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">quickbrownfrog</media:title>
		</media:content>

		<media:content url="http://quickbrownfrog.files.wordpress.com/2010/11/alternat-edit.jpg" medium="image">
			<media:title type="html">Quick Brown Frog logo</media:title>
		</media:content>

		<media:content url="http://quickbrownfrog.files.wordpress.com/2010/11/gauges.png?w=300" medium="image">
			<media:title type="html">speed test gauges</media:title>
		</media:content>
	</item>
		<item>
		<title>$210,542</title>
		<link>http://blog.quickbrownfrog.com/2010/11/29/210542/</link>
		<comments>http://blog.quickbrownfrog.com/2010/11/29/210542/#comments</comments>
		<pubDate>Tue, 30 Nov 2010 01:50:07 +0000</pubDate>
		<dc:creator>George Armhold</dc:creator>
				<category><![CDATA[Business/Marketing]]></category>

		<guid isPermaLink="false">http://quickbrownfrog.wordpress.com/?p=113</guid>
		<description><![CDATA[No, that&#8217;s not my revenue (I wish!) It&#8217;s what SLOCCount estimates Quick Brown Frog cost to develop. I&#8217;ve always felt that SLOCCount tends to exaggerate development cost. Either that or I&#8217;m vastly underpaid. 7.6 months and $210K seems way high &#8230; <a href="http://blog.quickbrownfrog.com/2010/11/29/210542/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=113&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>No, that&#8217;s not my revenue (I wish!)</p>
<p>It&#8217;s what <a href="http://www.dwheeler.com/sloccount/">SLOCCount</a> estimates Quick Brown Frog cost to develop. I&#8217;ve always felt that SLOCCount tends to exaggerate development cost. Either that or I&#8217;m vastly underpaid.</p>
<p>7.6 months and $210K seems way high for this app, even with the salary is set to a rather low $56K default.</p>
<p>Still, it&#8217;s quite the ego boost for a solo programmer. I&#8217;ve only been developing this <a href="http://www.quickbrownfrog.com">typing tutor</a> for about 6 weeks so far, and this feels kind of like a pat on the back.</p>
<pre>SLOC	Directory	SLOC-by-Language (Sorted)
3688    typing          java=3688
3183    gwtstore        java=3183
196     mystore         java=196

Totals grouped by language (dominant language first):
java:          7067 (100.00%)

Total Physical Source Lines of Code (SLOC)                = 7,067
Development Effort Estimate, Person-Years (Person-Months) = 1.56 (18.70)
 (Basic COCOMO model, Person-Months = 2.4 * (KSLOC**1.05))
Schedule Estimate, Years (Months)                         = 0.63 (7.61)
 (Basic COCOMO model, Months = 2.5 * (person-months**0.38))
Estimated Average Number of Developers (Effort/Schedule)  = 2.46
Total Estimated Cost to Develop                           = $ 210,542
 (average salary = $56,286/year, overhead = 2.40).
SLOCCount, Copyright (C) 2001-2004 David A. Wheeler
Please credit this data as "generated using David A. Wheeler's 'SLOCCount'."</pre>
<p>This also goes to show that the <em>cost</em> of software development does not necessarily have anything at all to do with its<em> worth</em>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/quickbrownfrog.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/quickbrownfrog.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/quickbrownfrog.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/quickbrownfrog.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/quickbrownfrog.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/quickbrownfrog.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/quickbrownfrog.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/quickbrownfrog.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/quickbrownfrog.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/quickbrownfrog.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/quickbrownfrog.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/quickbrownfrog.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/quickbrownfrog.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/quickbrownfrog.wordpress.com/113/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=113&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.quickbrownfrog.com/2010/11/29/210542/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/35752f1794d9a5f8ab8fe8edf272f0cc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">quickbrownfrog</media:title>
		</media:content>
	</item>
		<item>
		<title>Quick Brown Frog Typing Tutor is launched!</title>
		<link>http://blog.quickbrownfrog.com/2010/11/25/quick-brown-frog-is-launched/</link>
		<comments>http://blog.quickbrownfrog.com/2010/11/25/quick-brown-frog-is-launched/#comments</comments>
		<pubDate>Thu, 25 Nov 2010 14:34:18 +0000</pubDate>
		<dc:creator>George Armhold</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://quickbrownfrog.wordpress.com/?p=144</guid>
		<description><![CDATA[After lots of helpful feedback from beta testers and Hacker News, my typing tutor app &#8220;Quick Brown Frog&#8221; is live and open for business! Some of the things I changed in response to feedback include: price reduction from $29.95 -&#62; &#8230; <a href="http://blog.quickbrownfrog.com/2010/11/25/quick-brown-frog-is-launched/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=144&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>After lots of helpful feedback from beta testers and Hacker News, my <a href="http://www.quickbrownfrog.com">typing tutor</a> app &#8220;Quick Brown Frog&#8221; is live and open for business!</p>
<p>Some of the things I changed in response to feedback include:</p>
<ul>
<li><a href="http://www.quickbrownfrog.com/#!store:">price reduction</a> from $29.95 -&gt; $9.95</li>
<li>support both Google Checkout and Paypal options for payment</li>
<li><a href="http://www.quickbrownfrog.com/#!progress:">stats reporting</a> (WPM/Accuracy improvement over time)</li>
<li>report on frequently mis-typed keys after practice lessons</li>
<li>allow automatic single/double spacing after end of sentences (<em>very</em> frequently requested)</li>
<li>implemented crawlable Ajax links for SEO</li>
<li>plus many bug fixes for cross-browser compatibility</li>
</ul>
<p>I consider this an <a href="http://en.wikipedia.org/wiki/Minimum_viable_product">MVP-level</a> release, which means that it still needs lots of work and polish (in particular, the look-and-feel of the UI).</p>
<p>The important thing is to get it out there, and start getting feedback from actual customers. Absent that, I&#8217;d just be spinning my wheels.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/quickbrownfrog.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/quickbrownfrog.wordpress.com/144/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/quickbrownfrog.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/quickbrownfrog.wordpress.com/144/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/quickbrownfrog.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/quickbrownfrog.wordpress.com/144/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/quickbrownfrog.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/quickbrownfrog.wordpress.com/144/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/quickbrownfrog.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/quickbrownfrog.wordpress.com/144/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/quickbrownfrog.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/quickbrownfrog.wordpress.com/144/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/quickbrownfrog.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/quickbrownfrog.wordpress.com/144/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=144&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.quickbrownfrog.com/2010/11/25/quick-brown-frog-is-launched/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/35752f1794d9a5f8ab8fe8edf272f0cc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">quickbrownfrog</media:title>
		</media:content>
	</item>
		<item>
		<title>Measuring Typing Accuracy</title>
		<link>http://blog.quickbrownfrog.com/2010/11/22/measuring-typing-accuracy/</link>
		<comments>http://blog.quickbrownfrog.com/2010/11/22/measuring-typing-accuracy/#comments</comments>
		<pubDate>Mon, 22 Nov 2010 15:38:25 +0000</pubDate>
		<dc:creator>George Armhold</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[Typing]]></category>

		<guid isPermaLink="false">http://quickbrownfrog.wordpress.com/?p=27</guid>
		<description><![CDATA[It turns out that measuring typing accuracy (how accurately you hit the intended keys) is non-trivial. A quick survey of the online typing courses out there shows that there is considerable confusion over how to correctly measure typing accuracy. One site &#8230; <a href="http://blog.quickbrownfrog.com/2010/11/22/measuring-typing-accuracy/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=27&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It turns out that measuring typing accuracy (how accurately you hit the intended keys) is non-trivial. A quick survey of the online typing courses out there shows that there is considerable confusion over how to correctly measure typing accuracy. One site actually gives a <em>negative percentage</em> if you backspace too many times!</p>
<p>This was kind of surprising to me. I figured it would take me perhaps 10 minutes to implement. It ended up taking a day and a half of my time, $10 spent on an ACM article, and some quality time with a recent CS grad&#8217;s <a href="http://www.dynamicnetservices.com/~will/academic/Soukoreff%20PhD%20Dissertation.pdf">PhD thesis</a>. No joke.</p>
<p>Well, to be completely honest, in the end, the implementation <em>was</em> in fact fairly trivial. What was hard was figuring out <em>what to measure</em>. It&#8217;s more of a human problem than a technical one.</p>
<h3>Why is this hard?</h3>
<p>Your intuition might be to simply measure the ratio of correct characters to total characters typed. At first glance this seems OK, but consider the following case:</p>
<pre>intended: The quick brown frog jumped over the lazy fox.
actual  : The qu<span style="color:#993300;font-family:Monospace;">ck brown frog jumped over the lazy fox.</span></pre>
<p>If we match up the typed characters with what was expected, the accuracy of this typed statement is a very low 15 %. But looking at it from a human perspective, what were the actual errors here? The typist missed the &#8220;i&#8221; character in the word &#8220;quick&#8221;, and as a result the rest of the line was offset by one.  It seems like there ought to be a way to more accurately capture the fact that the user made a single typo. There is.</p>
<h3>Edit Distance</h3>
<p><a href="http://en.wikipedia.org/wiki/Edit_distance">Edit Distance</a> is the number of operations required to transform one string into another. The operations include <em>insertion</em>, <em>deletion</em> and <em>substitution</em>. In this example, it requires only a single edit- &#8216;insert an i&#8217;.</p>
<p>Soukoreff&#8217;s <a href="http://www.dynamicnetservices.com/~will/academic/Soukoreff%20PhD%20Dissertation.pdf">thesis</a> describes a <em>Minimum String Distance Error Rate</em> as the Edit Distance divided by the maximum of the lengths of the presented vs typed text, times 100%. For our &#8220;off by one&#8221; example above, the error rate is a mere 2%, i.e. 98% accurate. That seems more reasonable!</p>
<p>So for a while I was using the <a href="http://en.wikipedia.org/wiki/Levenshtein_distance">Levenshtein Distance algorithm</a> to compute the edit distance, and hence the accuracy. This certainly worked better than my initial naive algorithm, but it still had a problem- What if the typist made <em>lots</em> of errors, but was fastidious about backspacing over the mistakes and correcting them? His error rate would be zero in this case, with an accuracy of 100%.</p>
<p>While correcting all your mistakes is admirable, it seems wrong to award a &#8220;100% accurate&#8221; rating to a typist sporting a bruised backspace key. Somehow, we&#8217;ve got to take the mistakes into account, even if they&#8217;ve been corrected.</p>
<h3>Text-Entry Taxonomy</h3>
<p>Soukoreff&#8217;s PhD thesis again provides a solution. Classify each of the keystrokes into one of the following categories:</p>
<ul>
<li><strong>C</strong> &#8211; Correctly typed</li>
<li><strong>IF</strong> &#8211; Incorrect, but Fixed</li>
<li><strong>INF</strong> &#8211; Incorrect, Not Fixed</li>
<li><strong>F</strong> &#8211; Fixes, i.e. backspace or cursor movement used to correct mistakes</li>
</ul>
<p>Using these classifications, he proposes a <em>Total Error Rate</em> defined as:</p>
<blockquote><p>(INF + IF) / (C + INF + IF) * 100%</p></blockquote>
<p>So, going back to our &#8220;off by one&#8221; example, if the typist noticed immediately that he missed the &#8216;i&#8217; in &#8216;quick&#8217;, and backspaced to correct it,</p>
<pre>The qu<span style="color:#993300;font-family:Monospace;">c</span>⌫ick brown frog jumped over the lazy fox.</pre>
<p>the breakdown would be C: 47, F: 1, IF: 1,. INF: 0, for a total error rate of (0 + 1) / (47 + 0 + 1) = 2%, or 98% accurate. Same as using the Edit Distance alone, in this example.</p>
<p>But what if the user didn&#8217;t notice the mistake until 10 characters later? The input stream would look something like this:</p>
<pre>The qu<span style="color:#993300;font-family:Monospace;">ck brown f</span>⌫⌫⌫⌫⌫⌫⌫⌫⌫⌫ick brown frog jumped over the lazy fox.</pre>
<p>What&#8217;s the error rate now? C:47, F:10, IF: 10, INF: 0, or (0 + 10) / (47 + 0 + 10) * 100% = 17.5%, or roughly 82% accurate. Aha!</p>
<p>I plugged this formula into <a href="http://www.quickbrownfrog.com">Quick Brown Frog</a> and watched the error rate go up and down while typing. <em>Finally</em>, it seemed to be doing the right thing- rewarding accurate, deliberate typing, and taking off points for outright mistakes as well expensive corrections.</p>
<p>Yet another example of why it&#8217;s hard to estimate software schedules- sometimes the &#8216;trivial&#8217; is anything but.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/quickbrownfrog.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/quickbrownfrog.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/quickbrownfrog.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/quickbrownfrog.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/quickbrownfrog.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/quickbrownfrog.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/quickbrownfrog.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/quickbrownfrog.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/quickbrownfrog.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/quickbrownfrog.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/quickbrownfrog.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/quickbrownfrog.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/quickbrownfrog.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/quickbrownfrog.wordpress.com/27/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.quickbrownfrog.com&amp;blog=17478577&amp;post=27&amp;subd=quickbrownfrog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.quickbrownfrog.com/2010/11/22/measuring-typing-accuracy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/35752f1794d9a5f8ab8fe8edf272f0cc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">quickbrownfrog</media:title>
		</media:content>
	</item>
	</channel>
</rss>
