<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

  <title><![CDATA[Chris L Keller...]]></title>
  
  <link href="http://blog.chrislkeller.com/" />
  <updated>2013-05-15T20:46:38-07:00</updated>
  <id>http://blog.chrislkeller.com/</id>
  <author>
    <name><![CDATA[Chris Keller]]></name>
    <email><![CDATA[christopherlawrencekeller@gmail.com]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ChrisLKeller" /><feedburner:info uri="chrislkeller" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title type="html"><![CDATA[Automating crowdsourced maps with apps scripts]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/H2uqGk3iR8k/" />
    <updated>2013-05-15T12:00:00-07:00</updated>
    <id>http://blog.chrislkeller.com/automating-crowdsourced-maps-with-apps-scripts</id>
    <content type="html">&lt;p&gt;Back in November, on my second day at &lt;a href="http://www.scpr.org/"&gt;KPCC&lt;/a&gt;, I collaborated with &lt;a href="http://twitter.com/kimbui"&gt;Kim Bui&lt;/a&gt; on a &lt;a href="http://www.scpr.org/blogs/politics/2012/11/06/10919/you-voted-today-what-was-it/"&gt;crowd-sourced map&lt;/a&gt; that displayed the experience that voters had at the polls.&lt;/p&gt;

&lt;p&gt;The map &amp;#8211; powered using a Google Form to submit data to a spreadsheet which was then uploaded to &lt;a href="http://www.google.com/drive/apps.html#fusiontables"&gt;Fusion Tables&lt;/a&gt; &amp;#8211; required some hand-holding on my part. OK alot. I had to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure the address was geocoded properly.&lt;/li&gt;
&lt;li&gt;Make sure we added the correct marker based on the experience.&lt;/li&gt;
&lt;li&gt;Sync the data to Fusion Tables using a handy script.&lt;/li&gt;
&lt;li&gt;Make sure the map markers appear correctly.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;But it was my second day, and I didn&amp;#8217;t have much on my plate, though I know it could go better.&lt;/p&gt;

&lt;p&gt;Some six months later I&amp;#8217;ve become more comfortable here, and more comfortable with &lt;a href="https://developers.google.com/apps-script/"&gt;Google Apps Scripts&lt;/a&gt; thanks to some &lt;a href="http://blog.apps.chicagotribune.com/2013/02/15/using-google-docs-to-send-email/"&gt;great examples&lt;/a&gt; from &lt;a href="http://project.wnyc.org/smelendez-nicar12/"&gt;others&lt;/a&gt;. So for a map for Tuesday&amp;#8217;s election that will &lt;a href="http://projects.scpr.org/static/maps/election-day-voting-issues/"&gt;allow voters to submit their experience at the polls&lt;/a&gt; I&amp;#8217;ve been able to automate a lot of the process. I&amp;#8217;ll still hold its hand &amp;#8211; cause that only makes sense &amp;#8211; but a lot of the manual tweaking should be unnecessary.&lt;/p&gt;

&lt;p&gt;Here are some of the scripts I&amp;#8217;m using.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do something when a form is submitted&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    function onFormSubmit(e) {
        var emailToAddress = 'ckeller@scpr.org';
        var submissionTimeStamp = e.values[0];
        var submissionPollingPlace = e.values[1]; 
        var submissionExperience = e.values[6];
        var submissionNarrative = e.values[2];
        var submissionFullName = e.values[3];
        var emailSubject = 'Voter issues map submission from' + submissionPollingPlace;
        var emailBody = submissionTimeStamp + '\n' +   
            'Voting at ' + submissionPollingPlace + 
            ' was ' + submissionExperience + '.\n' + submissionNarrative +
            ' -- submitted by' + submissionFullName;
        MailApp.sendEmail(emailToAddress, emailSubject, emailBody);

        // run the data processing functions
        runSpreadsheetFunctions();
    };
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&amp;#8217;m still using a Google form to populate a spreadsheet, but I&amp;#8217;m using an a script to trigger some additional functions when the submit button is pressed. This one &amp;#8211; cribbed from an &lt;a href="http://blog.apps.chicagotribune.com/2013/02/15/using-google-docs-to-send-email/"&gt;Andy Boyle walkthrough&lt;/a&gt; &amp;#8211; will send an email with tje information that was just submitted. The script sets each column to a varible; &lt;code&gt;e.values[0]&lt;/code&gt; in this case represents the first column in the spreadsheet&amp;#8230;&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve also piggybacked a generic &lt;code&gt;runSpreadsheetFunctions()&lt;/code&gt; function, so that when a form is submitted, a whole host of actions take place. Among them:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Geocode a user-submitted address&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    function geocodeAddressFromCell(){
        var sss = SpreadsheetApp.openById(spreadsheetID);
        var ss = sss.getSheetByName(workingSheetID);
        var lastRow = ss.getLastRow();
        var addressCellData = ss.getRange(lastRow, 2).getValue();
        var results = Maps.newGeocoder().geocode(addressCellData);
        if (results.status == 'OK') {
            var bestResult = results.results[0];
            var lat = bestResult.geometry.location.lat;
            var lng = bestResult.geometry.location.lng;
            var latLng = lat + ',' + lng;
            var addressTargetCellData = ss.getRange(lastRow, 9).setValue(latLng);
        } else {
            Logger.log(results.status);
            return '0,0';
        }  
    };
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This script will find a column in the last row of the spreadsheet &amp;#8211; &lt;code&gt;var addressCellData = ss.getRange(lastRow, 2).getValue();&lt;/code&gt; &amp;#8211; and run that value through Google&amp;#8217;s geocoder and output a latitude/longitude pair &amp;#8211; &lt;code&gt;var latLng = lat + ',' + lng;&lt;/code&gt;. That latitude/longitude pair is assigned to a variable and added to &amp;#8220;geocoded_address&amp;#8221; column in that last row &amp;#8211; &lt;code&gt;var addressTargetCellData = ss.getRange(lastRow, 9).setValue(latLng);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add a function to a cell&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    function evaluateVotingExperience(){
        var sss = SpreadsheetApp.openById(spreadsheetID);
        var ss = sss.getSheetByName(workingSheetID);    
        var projectTypeColumn = "G";
        var projectMarkerIdColumn = "H";
        var lastRow = ss.getLastRow();
        var projectTypeCell = projectTypeColumn + lastRow;
        var projectMarkerIdCell = projectMarkerIdColumn + lastRow;
        var projectMarkerIdFormula = "=IF(" + projectTypeCell + "=\"Negative\", \"large_red\", IF(" + projectTypeCell + "=\"Positive\", \"large_green\"))";
        var ssCellToGetFormula = ss.getRange(projectMarkerIdCell);
        ssCellToGetFormula.setFormula(projectMarkerIdFormula);
    };
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This script is similar to the &lt;code&gt;geocodeAddressFromCell()&lt;/code&gt; function in that it finds a value in a specific column in the last row of a spreadsheet. But instead of geocoding the value, it will insert an IF formula into the cell to evaluate whether the voter&amp;#8217;s experience was positive of negative and add a map marker type depending on the result.&lt;/p&gt;

&lt;p&gt;Then of course there is the &lt;a href="https://gist.github.com/chrislkeller/3013360#file-spreadsheet-to-fusion-tables"&gt;series of functions&lt;/a&gt; that allows you to sync a &lt;a href="http://blog.chrislkeller.com/google-group-user-john-m-posts-script-that-br/"&gt;Google spreadsheet with a Fusion Table&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tie it all together&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The update script is incorporated into &lt;code&gt;runSpreadsheetFunctions()&lt;/code&gt;, and which is run when a form is submitted, so the Fusion Table is updated automatically when a voter clicks the submit button.&lt;/p&gt;

&lt;p&gt;To be safe, I set a &amp;#8220;timeout&amp;#8221; to make sure the previous functions have run before the Fusion Table is updated.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    // run functions that will process the data
    function runSpreadsheetFunctions(){

        geocodeAddressFromCell();
        Utilities.sleep(1000);

        evaluateVotingExperience();
        Utilities.sleep(1000);

        updateFusion();
        Utilities.sleep(1000);
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/H2uqGk3iR8k" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/automating-crowdsourced-maps-with-apps-scripts/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Link: Merging Datasets with Common Columns in Google Refine]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/YutDluKz708/" />
    <updated>2013-04-28T12:38:00-07:00</updated>
    <id>http://blog.chrislkeller.com/link-merging-datasets-with-common-columns-in-google-refine</id>
    <content type="html">&lt;blockquote&gt;&lt;p&gt;It’s an often encountered situation, but one that can be a pain to address – merging data from two sources around a common column. Here’s a way of doing it in &lt;a href="https://github.com/OpenRefine"&gt;Google Refine&lt;/a&gt;…&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;via &lt;a href="http://blog.ouseful.info/2011/05/06/merging-datesets-with-common-columns-in-google-refine/"&gt;OUseful.Info&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/YutDluKz708" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/link-merging-datasets-with-common-columns-in-google-refine/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Link: Meetings Are Toxic]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/yhj63q1gPCc/" />
    <updated>2013-04-28T12:18:00-07:00</updated>
    <id>http://blog.chrislkeller.com/link-meetings-are-toxic</id>
    <content type="html">&lt;p&gt;A NICAR thread about methods of project management and product development led me to some posts on &lt;a href="http://crunchberry.org/tag/agile/"&gt;Agile development&lt;/a&gt; which led me to find this gem. Like any piece of knowledge that could be deemed as inherent in some people, it&amp;#8217;s always good to be reminded of proper meeting rules.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;For those times when you absolutely must have a meeting (this should be a rare event), stick to these simple rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set a 30 minute timer. When it rings, meeting&amp;#8217;s over. Period.&lt;/li&gt;
&lt;li&gt;Invite as few people as possible.&lt;/li&gt;
&lt;li&gt;Never have a meeting without a clear agenda.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;via &lt;a href="http://gettingreal.37signals.com/ch07_Meetings_Are_Toxic.php"&gt;Getting Real&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/yhj63q1gPCc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/link-meetings-are-toxic/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Fresh from Posterous]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/OrW-qbo2FlE/" />
    <updated>2013-02-16T09:42:00-08:00</updated>
    <id>http://blog.chrislkeller.com/fresh-from-posterous</id>
    <content type="html">&lt;p&gt;This is my first post using Octopress, which comes after folks finally decided to pull the plug on Posterous. It was announced yesterday that it will be &lt;a href="http://blog.posterous.com/thanks-from-posterous"&gt;shutting down on April 30&lt;/a&gt;, some 13 months after Twitter acquired the platform, or rather the talent that built the platform.&lt;/p&gt;

&lt;p&gt;As I wrote in my last post on Posterous, I enoyed using it because it stayed out of my way… I didn&amp;#8217;t feel the need to fiddle with the layout, or adjust the admin or mess around with plugins. It let me just write posts… Maybe not as many as I&amp;#8217;d like to, but posts nonetheless. And I stuck with it to a certain degree.&lt;/p&gt;

&lt;p&gt;I spent some time considering going back to Tumblr, and I found this promising platform called Snipt. Heck I even installed WordPress for spell.&lt;/p&gt;

&lt;p&gt;But all in all I like the idea of Octopress, of something that will continue to stay out of my way and just let me write, of something that will lets write in markdown which is then compiled into static HTML.&lt;/p&gt;

&lt;p&gt;Time will tell.&lt;/p&gt;

&lt;p&gt;I can say Posterous served me well at a certain point in my life, a time when I was learning to learn, code, program and teach/show others, and I&amp;#8217;ll have &lt;a href="http://archives.chrislkeller.com/"&gt;an archive&lt;/a&gt; of that. Now it&amp;#8217;s time to find something new.&lt;/p&gt;

&lt;p&gt;I did take some steps to prepare for a day I figured was coming.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I moved my &lt;a href="http://projects.chrislkeller.com/"&gt;projects page&lt;/a&gt; away from Posterous and organized it bit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I grabbed an export of all of my content that Posterous housed and moved it to &lt;a href="http://blog.chrislkeller.com/archives"&gt;an archive&lt;/a&gt;. &lt;del&gt;Now I have some time to figure out how to deal with links that will be broken&lt;/del&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I started to move some &lt;a href="https://github.com/chrislkeller/documenting-learning"&gt;learning resources and tutorials&lt;/a&gt; to &lt;a href="https://github.com/chrislkeller"&gt;Github&lt;/a&gt; and &lt;a href="https://gist.github.com/chrislkeller"&gt;Gists&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/OrW-qbo2FlE" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/fresh-from-posterous/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Last Posterous post... time to find a new method...]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/TmhqyFjt1Vc/" />
    <updated>2013-02-15T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/last-posterous-post-time-to-find-a-new-method</id>
    <content type="html">&lt;p&gt;Looks like folks finally decided to pull the plug on Posterous. &lt;a href="http://blog.posterous.com/thanks-from-posterous"&gt;It will be shutting down on April 30&lt;/a&gt;, some 13 months after Twitter acquired the platform, or rather the talent that built the platform.&lt;/p&gt;
&lt;p&gt;I enjoyed using Posterous because it stayed out of my way&amp;hellip; I didn&amp;#8217;t feel the need to fiddle with the layout, or adjust the admin or mess around with plugins. It let me just write posts&amp;hellip; Maybe not as many as I&amp;#8217;d like to, but posts nonetheless. And I stuck with it to a certain degree.&lt;/p&gt;
&lt;p&gt;Sadly, along with the blogging platform being gone, seems any Google juice I accumulated for things like &lt;a href="http://www.chrislkeller.com/tag/fusiontables"&gt;Fusion Tables walkthroughs and examples&lt;/a&gt; will be gone as well&amp;hellip; or at least pointing to dead links.&lt;/p&gt;
&lt;p&gt;But then that might be for the better. I can say Posterous served me well at a certain point in my life, a time when I was learning to learn, code, program and teach/show others, and I&amp;#8217;ll have &lt;a href="http://archives.chrislkeller.com/"&gt;an archive&lt;/a&gt; of that. Now it&amp;#8217;s time to find something new.&lt;/p&gt;
&lt;p&gt;I did take some steps to prepare for a day I figured was coming.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I formatted my &lt;a href="http://projects.chrislkeller.com/"&gt;projects page&lt;/a&gt; a bit so it&amp;#8217;s a little more organized.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I grabbed an export of all of &lt;a href="http://archives.chrislkeller.com/"&gt;my content&lt;/a&gt; that Posterous housed. The Posterous backup made is really easy for me, and I think they way the structured the export should be a model for all content platform companies when they shutdown &amp;#8211; ahem, Everyblock.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I started to move some &lt;a href="https://github.com/chrislkeller/documenting-learning"&gt;learning resources and tutorials&lt;/a&gt; to &lt;a href="https://github.com/chrislkeller"&gt;Github&lt;/a&gt; and &lt;a href="https://gist.github.com/chrislkeller"&gt;Gists&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;And I started to research some other potential platforms. Wordpress is always there, but it&amp;#8217;s too easy for me to get bogged down in how the site looks. Again, more writing and less fuss. &lt;a href="https://twitter.com/gotoplanb"&gt;Dave Stanton&lt;/a&gt; &amp;amp; &lt;a href="https://twitter.com/webjournalist"&gt;Robert Hernandez&lt;/a&gt; just turned me on to &lt;a href="https://chrislkeller.snipt.net/"&gt;Snipt&lt;/a&gt;, which looks promising as well.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/TmhqyFjt1Vc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/last-posterous-post-time-to-find-a-new-method/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Ever want to be a fly on the wall while interesting ideas and topics are being discussed?]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/jpnpzMh5xSw/" />
    <updated>2013-02-09T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/ever-want-to-be-a-fly-on-the-wall-while-inter</id>
    <content type="html">&lt;p&gt;On Wednesday, thankfully before breaking news shifted my focus entirely, I had the pleasure of listening to some great minds in the area of technology and journalism share their thoughts on everything from data visualization to the pitfalls of throwing everything on a map.&lt;/p&gt;
&lt;p&gt;O&amp;#8217;Reilly&amp;#8217;s Alex Howard hosted a &lt;a href="https://plus.google.com/u/0/+AlexanderHoward/posts/Mh4s3cq3Srq"&gt;Google Hangout&lt;/a&gt; on the topic of data journalism. Present were O&amp;rsquo;Reilly&amp;#8217;s &lt;a href="https://twitter.com/macslocum" target="_blank"&gt;Mac Slocum&lt;/a&gt;, USA Today&amp;#8217;s &lt;a href="https://twitter.com/AnthonyDB" target="_blank"&gt;Anthony DeBarros&lt;/a&gt;, NPR&amp;#8217;s &lt;a href="https://twitter.com/brianboyer"&gt;Brian Boyer&lt;/a&gt;, &lt;a href="https://twitter.com/gotoplanb"&gt;Dave Stanton&lt;/a&gt; from SmartMedia Creative, &lt;a href="https://twitter.com/michelleminkoff"&gt;Michelle Minkoff&lt;/a&gt; from The Associated Press, &lt;a href="https://twitter.com/tkb"&gt;Tariq Kokhar&lt;/a&gt; from the World Bank, &lt;a href="https://twitter.com/smfrogers"&gt;Simon Rogers&lt;/a&gt; from The Guardian and myself.&lt;/p&gt;
&lt;p&gt;&lt;iframe src="http://www.youtube.com/embed/haOc54NmP0k?list=UUSaNIkarwOScjXdbQ6uTx0A" frameborder="0" height="281" width="500"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/jpnpzMh5xSw" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/ever-want-to-be-a-fly-on-the-wall-while-inter/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Some thoughts after a couple months with tabletop and handlebars]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/urPT-7N8gIM/" />
    <updated>2013-02-02T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/some-thoughts-after-a-couple-months-with-tabl</id>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; - Learning how I can use tabletop.js &amp;amp; handlebars.js together has opened up some really cool custom mini-CMS possibilities and ways to manage data projects.&lt;/p&gt;
&lt;p&gt;But thanks to the &lt;a href="https://twitter.com/brianboyer/status/233201509842710528"&gt;experiments of others&lt;/a&gt;, I have learned that flat json files can be better to use in production, especially for small one-off projects.&lt;/p&gt;
&lt;p&gt;While I&amp;#8217;d like to eventually write a script to take the tabletop object and write it to a flat file, I made some adjustments to some python code so I can take a csv, create a flat json file from it and drop that file into a &lt;a href="https://gist.github.com/3230081"&gt;handlebars function&lt;/a&gt; with minimal effort.&lt;/p&gt;
&lt;p&gt;While it works for me, I&amp;#8217;m curious to know if it works for others&amp;hellip;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.chrislkeller.com/some-thoughts-after-a-couple-months-with-tabl"&gt;Blog Post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/4700210"&gt;Repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;I&amp;#8217;m happy to say that I still have access to some gray days since moving to Southern California, and on a recent one I set about streamlining some project structures, code snippets &amp;amp; templates for two code libraries that I&amp;#8217;ve been using more and more since coming to &lt;a href="http://www.scpr.org/"&gt;Southern California Public Radio&lt;/a&gt;: &lt;a href="https://github.com/jsoma/tabletop"&gt;tabletop.js&lt;/a&gt; and &lt;a href="http://handlebarsjs.com/"&gt;handlebars.js&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m only now getting back to the write up and posting code.&lt;/p&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;tabletop.js allows you to use a Google spreadsheet as a data backend. By simply publishing the spreadsheet and adding its key to a tabletop javascript function you can retrieve an an array of objects to be used on a webpage or in a web application. The library was released back in February &amp;#8211; right around the time of NICAR &amp;#8211; thanks to work by &lt;a href="http://datanews.tumblr.com/"&gt;WNYC&lt;/a&gt; and &lt;a href="http://www.builtbybalance.com/"&gt;Balance Media&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;handlebars.js is a templating library &amp;#8211; much like mustache.js &amp;#8211; that &amp;#8220;provides the power necessary to let you build semantic templates&amp;#8221; based on data that is formatted as &amp;#8211; get this &amp;#8211; javascript objects. Using an example from the handlebar.js website, the library allows you to do things like this&amp;#8230;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;div class=&amp;quot;entry&amp;quot;&amp;gt;
    &amp;lt;h1&amp;gt;&amp;lt;/h1&amp;gt;
    &amp;lt;div class=&amp;quot;body&amp;quot;&amp;gt;
        
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;hellip; where  and  represents information stored in an object like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;var context = {title: &amp;quot;My New Post&amp;quot;, body: &amp;quot;This is my first post!&amp;quot;}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Practical Applications&lt;/h2&gt;
&lt;p&gt;Learning how these libraries can work with each other has been a lot of fun, especially in the context of a &lt;a href="http://www.scpr.org/about/people/staff/chris-keller"&gt;newly-created position&lt;/a&gt; at a &lt;a href="http://www.scpr.org/"&gt;new-to-me news organization&lt;/a&gt; where I have had a role to play in building a foundation for the presentation of data projects.&lt;/p&gt;
&lt;p&gt;For instance, using handlebars.js ability to load precompiled handlebars templates from file we&amp;#8217;ve been able to construct a basic project wrapper that can live outside CMS, minimizes the amount of code that needs to be changed at any given time and allows us to manage a single header and one footer file. DRY FTW.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve also been able to use the combination of these libraries to come to having a custom mini-CMS that can run some of these projects, which can then be updated by anyone that can use a spreadsheet.&lt;/p&gt;
&lt;p&gt;For instance, one of my first collaborations was with our business and economy reporter &lt;a href="http://www.scpr.org/about/people/staff/matthew-debord"&gt;Matt DeBord&lt;/a&gt; on this project for &lt;a href="http://www.scpr.org/blogs/economy/2012/12/07/11444/november-job-report/"&gt;Explaining the Monthly Jobs Report&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This project combines tabletop.js with handlebars.js &amp;#8211; and some &lt;a href="http://www.highcharts.com/"&gt;highcharts.js&lt;/a&gt; for good measure &amp;#8211; to show the differences between &amp;#8220;Initial,&amp;#8221; &amp;#8220;Revised,&amp;#8221; and Final monthly jobs numbers released by the U.S. Bureau of Labor Statistics.&lt;/p&gt;
&lt;p&gt;While my &amp;#8220;design&amp;#8221; judgement and sensibilities continue to evolve, for my money, the magic is in the fact that Matt can update this presentation for our audience by opening a Google spreadsheet and adding the new numbers. Lightweight, custom mini-CMS!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/tasneemraja"&gt;Tasneem Raja&lt;/a&gt;, the Interactive Editor at Mother Jones, has written a &lt;a href="http://www.ire.org/blog/on-the-road/2012/09/21/behind-story-mother-jones-and-47-percent/"&gt;solid explainer&lt;/a&gt; on how the magazine has leveraged tabletop.js and a &lt;a href="https://docs.google.com/spreadsheet/ccc?key=0AiK02J6OppqxdFVxTEJBLXpqcWZKNVJsRFFZdkNESGc#gid=0"&gt;Google spreadhseet&lt;/a&gt; for collaborative projects such as their &lt;a href="http://www.motherjones.com/politics/2012/09/charts-47-percent-romney-tax-data"&gt;You Might Be the 47 Percent If&amp;hellip;&lt;/a&gt; scoop.&lt;/p&gt;
&lt;p&gt;Some of the projects I&amp;#8217;ve worked on over the past couple months that use tabletop.js and handlebars.js include a presentation on the purchasing of &lt;a href="http://projects.scpr.org/static/interactives/capital-appreciation-bonds/"&gt;Capital Appreciation Bonds&lt;/a&gt; by local school districts, a &amp;#8220;By The Numbers&amp;#8221; look at the impact of the so-called &lt;a href="http://projects.scpr.org/static/interactives/unemployment-compensation/"&gt;fiscal cliff on Emergency Unemployment Compensation benefits&lt;/a&gt; and a comparison of &lt;a href="http://projects.scpr.org/static/charts/gun-laws/"&gt;California and federal gun laws&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But a &lt;a href="http://newsbeastlabs.tumblr.com/post/37641296435/google-docs-miso-powered-apps-a-note-on"&gt;post on NewsBeast Labs&lt;/a&gt; I found while writing this pointing to a post from Jeremy Singer-Vine  &amp;#8211; appropriately titled &lt;a href="https://gist.github.com/3295633"&gt;&amp;#8220;Why I love Tabletop.js but don&amp;#8217;t use it in production&amp;#8221;&lt;/a&gt; &amp;#8211; and some words from &lt;a href="https://twitter.com/maboa"&gt;Mark Boas&lt;/a&gt; on an &lt;a href="http://www.mozillaopennews.org/"&gt;Open News&lt;/a&gt; call a couple weeks ago reminded me of potential obstacles and issues with relying too much on tabletop.js for projects.&lt;/p&gt;
&lt;p&gt;And a tweet &lt;del&gt;this week&lt;/del&gt; &lt;a href="https://twitter.com/aboutaaron/status/289469005008338945"&gt;a few weeks back&lt;/a&gt; from &lt;a href="https://twitter.com/aboutaaron"&gt;Aaron Williams&lt;/a&gt;, and &lt;a href="https://twitter.com/mattwaite/status/297870209807704064"&gt;one today&lt;/a&gt; from &lt;a href="https://twitter.com/mattwaite"&gt;Matt Waite&lt;/a&gt;, reminded me I have to finish this post you are reading.&lt;/p&gt;
&lt;p&gt;All of the issues that Jeremy listed are real, and Aaron&amp;#8217;s experience is real. Thinking about the projects I listed above, none of them really require the kind of dynamic data display that tabletop.js can pull off. It&amp;#8217;s a nice feature to have available on the monthly jobs report, but it isn&amp;#8217;t crucial, and certainly isn&amp;#8217;t required on the others.&lt;/p&gt;
&lt;p&gt;A flat file &lt;a href="https://docs.google.com/presentation/embed?id=1IybYcc0eVL-Rchm7lEQNwrM-AHRfr_M8ewfGYYNjeu8&amp;amp;start=false&amp;amp;loop=false&amp;amp;delayms=3000#slide=id.p"&gt;very much&lt;/a&gt; would work just fine.&lt;/p&gt;
&lt;p&gt;And so I went about finding a way to create a flat json file from a Google spreadsheet that I could use in a handlebars.js template.&lt;/p&gt;
&lt;h2&gt;My Workaround&lt;/h2&gt;
&lt;p&gt;I already had &lt;a href="https://twitter.com/andymboyle"&gt;Andy Boyle&amp;#8217;s&lt;/a&gt; python &lt;a href="http://www.andymboyle.com/2011/11/02/quick-csv-to-json-parser-in-python/"&gt;script&lt;/a&gt; from a year ago that creates json from a csv. And I noticed in the comments section on Andy&amp;#8217;s post that &lt;a href="https://twitter.com/onyxfish"&gt;Christopher Groskopf&amp;#8217;s&lt;/a&gt; &lt;a href="http://csvkit.readthedocs.org/en/latest/"&gt;csvkit&lt;/a&gt; has a &lt;a href="http://csvkit.readthedocs.org/en/latest/scripts/csvjson.html"&gt;csvjson utility&lt;/a&gt; that can also convert a csv to a json file.&lt;/p&gt;
&lt;p&gt;After flirting with the idea of adding a custom argument to the csvjson utility to allow me to specify a key, I &lt;a href="https://gist.github.com/4700210#file-handlebars-json-py"&gt;adjusted Andy&amp;#8217;s script&lt;/a&gt; to create a file that looks like this&amp;hellip;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;{&amp;quot;objects&amp;quot;: [{&amp;quot;Source&amp;quot;: &amp;quot;National Employment Law Project&amp;quot;, &amp;quot;DataOrder&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;SourceLink&amp;quot;: &amp;quot;http://www.nelp.org/&amp;quot;, &amp;quot;Data&amp;quot;: &amp;quot;12.29.2012&amp;quot;, &amp;quot;Title&amp;quot;: &amp;quot;The last day anyone will receive benefits from the Emergency Unemployment Compensation program unless Congress acts to renew it.&amp;quot;}, {&amp;quot;Source&amp;quot;: &amp;quot;Congressional Budget Office&amp;quot;, &amp;quot;DataOrder&amp;quot;: &amp;quot;2&amp;quot;, &amp;quot;SourceLink&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;Data&amp;quot;: &amp;quot;$30,000,000,000&amp;quot;, &amp;quot;Title&amp;quot;: &amp;quot;Estimated cost to renew the Emergency Unemployment Compensation program through the end of 2013.&amp;quot;}, {&amp;quot;Source&amp;quot;: &amp;quot;National Employment Law Project&amp;quot;, &amp;quot;DataOrder&amp;quot;: &amp;quot;3&amp;quot;, &amp;quot;SourceLink&amp;quot;: &amp;quot;http://www.nelp.org/&amp;quot;, &amp;quot;Data&amp;quot;: &amp;quot;400,000&amp;quot;, &amp;quot;Title&amp;quot;: &amp;quot;Estimated number of Californians receiving benefits from the Emergency Unemployment Compensation program, which is set to expire Jan. 2.&amp;quot;}, {&amp;quot;Source&amp;quot;: &amp;quot;National Employment Law Project&amp;quot;, &amp;quot;DataOrder&amp;quot;: &amp;quot;4&amp;quot;, &amp;quot;SourceLink&amp;quot;: &amp;quot;http://www.nelp.org/&amp;quot;, &amp;quot;Data&amp;quot;: &amp;quot;2,100,000&amp;quot;, &amp;quot;Title&amp;quot;: &amp;quot;Estimated number of Americans receiving benefits under the Emergency Unemployment Compensation program that would lose their unemployment benefits come January if Congress doesn\u2019t act.&amp;quot;}]&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;hellip; which is something that allows me to plug my new file name into a variable in &lt;a href="https://gist.github.com/raw/3230081/31abdbfb3f4746f8fb761d196dcfa81cdd38184d/data-script.js"&gt;this script&lt;/a&gt; and fly.&lt;/p&gt;
&lt;h2&gt;Snags&lt;/h2&gt;
&lt;p&gt;Now, admittedly it works because most of my handlebars work thus far has used simple data structures &amp;#8211; largely an object that contains an array of objects &amp;#8211; but my workflow might fall apart quickly should I need to access multiple data streams, etc. (UPDATE: This has already happened!)&lt;/p&gt;
&lt;p&gt;One thing I have noticed through this experiment is tabletop.js strips uppercase letters and underscores from object keys, while the csv to json version doesn&amp;#8217;t. So that&amp;#8217;s a thing as it&amp;#8217;s the difference between a handlebars.js template that uses&amp;hellip;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;//what tabletop brings
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;and&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;// created from a csv to json method
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Another thing I&amp;#8217;ve noticed is the python script that converts the csv to json renders everything as a string, which has caused some issues when using something like highcharts, which requires is data objects to be integers. So I continue to explore a way to fix this.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/urPT-7N8gIM" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/some-thoughts-after-a-couple-months-with-tabl/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Here's a simple script to generate a boilerplate FOIA-letter type thing that I cobbled together... ]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/l0psbpLsqOw/" />
    <updated>2013-01-29T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/heres-a-foia-letter-creator-script-i-cobbled</id>
    <content type="html">&lt;p&gt;This is a &lt;a href="https://gist.github.com/4668929" target="_blank"&gt;super simple shell script&lt;/a&gt; that takes boilerplate FOIA language and creates a &lt;a href="http://daringfireball.net/projects/markdown/" target="_blank"&gt;markdown&lt;/a&gt; file that can be addressed to a particular agency.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s tailored to California, but you can adjust it to your liking.&lt;/p&gt;
&lt;p&gt;You will still have to add the address, city, state and zip code of the agency, and the type of data being requested, but this is a step up from having a file that I copy and paste from.&lt;/p&gt;
&lt;p&gt;The script takes a filename as an argument. That filename will have the date prepended to it so you can see at a glance which were sent out when.&lt;/p&gt;
&lt;p&gt;I haven&amp;#8217;t decided yet to allow for the address and other potential variables to be passed into the script. At certain points you want to allow for mistakes, and most folks are bound to make mistakes when entering information in on the command line.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;#!/bin/bash

    # date variable
    DATE=&amp;quot;$(date +&amp;quot;%m-%d-%y&amp;quot;)&amp;quot;

    # input for newfile
    NAME_OF_FOIA_LETTER=&amp;quot;$1&amp;quot;

    # name for newfile
    OUTPUT_FILE=&amp;quot;$DATE-$NAME_OF_FOIA_LETTER.md&amp;quot;

    # create markdown FOIA
    echo &amp;quot;Creating $NAME_OF_FOIA_LETTER FOIA letter&amp;quot;
    cat &amp;lt;&amp;lt;EOF &amp;gt;$OUTPUT_FILE
    **$DATE**

    ADDRESS  $line
    STREET  $line
    CITY, STATE, ZIP CODE  $line

    **RE**: Public records request for NAME OF RECORD

    **To Whom It May Concern**:

    Under the California Public Records Act (Government Code Section 6250 et seq.), I ask to obtain a copy of the following records or data sets which I understand to be held by your agency:

    &amp;gt;*DATA TO BE REQUESTED HERE*

    I ask for a determination on this request within 10 days of receipt, or sooner should you make a determination without review of the record(s) in question.

    If you determine that any or all or the information if exempt, I would like to know if the exemption is discretionary, if it's necessary to exercise discretion in this case and a signed notification citing the legal authorities used to determine the records are exempt.

    Should some -- but not all of the information -- be exempt from disclosure -- and you intend to withhold it -- I ask that you redact it for the time being and make the rest available as requested.

    Please notify me of any duplication costs that will exceed \$10.00. If I can provide any clarification or answer any questions, my contact information is below.

    Thanks in advance and take care.

    Sincerely:

    Chris Keller  $line
    Data Journalist/News Applications Developer  $line
    Southern California Public Radio  $line
    **Web**: scpr.org  $line
    **Email**: ckeller@scpr.org  $line
    **Desk**: (626) 583-5214  $line

    EOF

    open $OUTPUT_FILE&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/l0psbpLsqOw" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/heres-a-foia-letter-creator-script-i-cobbled/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Link: "TLDR" is unnecessary]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/o9RLBvgf7_8/" />
    <updated>2013-01-13T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/link-tldr-is-unnecessary</id>
    <content type="html">&lt;div class="posterous_bookmarklet_entry"&gt;
&lt;blockquote class="posterous_short_quote"&gt;If you summarize your idea in your first sentence, writing &amp;#8220;TLDR&amp;#8221; is superfluous.&lt;/blockquote&gt;
&lt;div class="posterous_quote_citation"&gt;via &lt;a href="http://douglastarr.com/tldr-is-unnecessary#comment"&gt;douglastarr.com&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;As a guy who has taken to adding a tl;dr nugget on the top of walkthroughs reading the above makes me want to whack myself upside the head&amp;#8230; But maybe what I have been trying to do has another name&amp;#8230; Maybe something along the lines of, &amp;#8220;You Will Accomplish&amp;#8221;&lt;/p&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/o9RLBvgf7_8" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/link-tldr-is-unnecessary/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Display data from a flat JSON file on a Handlebars.js template file rendered with AJAX]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/GoUUp__72UM/" />
    <updated>2013-01-12T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/display-data-from-a-flat-json-file-on-a-handl</id>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;: The README on the repo below gives a bit of a walkthrough and demonstration of the script I&amp;#8217;ve been using to display a flat data file on Handlebars templates rendered with AJAX, which has allowed me to learn to deploy interactive data projects fairly fast.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.chrislkeller.com/display-data-from-a-flat-json-file-on-a-handl"&gt;Blog Post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://projects.chrislkeller.com/snippets/ajax-handlebars/"&gt;Demo Page&lt;/a&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/3230081"&gt;Repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://handlebarsjs.com/"&gt;Handlebars.js&lt;/a&gt; is a templating library &amp;#8211; much like mustache.js &amp;#8211; that &amp;#8220;provides the power necessary to let you build semantic templates&amp;#8221; based on data that is formatted as &amp;#8211; get this &amp;#8211; javascript objects. Using an example from the handlebar.js website, the library allows you to do things like this&amp;#8230;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;div class=&amp;quot;entry&amp;quot;&amp;gt;
    &amp;lt;h1&amp;gt;&amp;lt;/h1&amp;gt;
    &amp;lt;div class=&amp;quot;body&amp;quot;&amp;gt;
        
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;hellip; where  and  represents information stored in an object like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;var context = {title: &amp;quot;My New Post&amp;quot;, body: &amp;quot;This is my first post!&amp;quot;}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;There are some really good resources out there for those who want to start using the Handlebars JavaScript template library. Here are some links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://handlebarsjs.com/"&gt;Handlebars site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/wycats/handlebars.js/"&gt;Handlebars GitHubRepo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://net.tutsplus.com/tutorials/javascript-ajax/introduction-to-handlebars/"&gt;NetTuts Handlebars Walkthrough&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Three-part series on using Handlebars: &lt;a href="http://blog.teamtreehouse.com/getting-started-with-handlebars-js"&gt;Part one&lt;/a&gt;; &lt;a href="http://blog.teamtreehouse.com/code/handlebars-js-part-2-partials-and-helpers/"&gt;Part two&lt;/a&gt;; &lt;a href="http://blog.teamtreehouse.com/handlebars-js-part-3-tips-and-tricks"&gt;Part three&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#8217;d like to demonstrate a bit of the script I&amp;#8217;ve been using to display a flat data file on Handlebars templates render with AJAX, and give a couple practical applications for using Handlebars in a newsroom environment in order to deploy interactive projects fairly fast.&lt;/p&gt;
&lt;h2&gt;Walkthrough&lt;/h2&gt;
&lt;p&gt;Coming across Handlebars.js after learning the basics of django templating, I really wanted a way to mimic some of that functionality and store Handlebars templates in &lt;a href="https://github.com/wycats/handlebars.js/issues/82"&gt;reusable, decoupled files that could be shared across projects&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thankfully this function based on &lt;a href="http://berzniz.com/post/24743062344/handling-handlebars-js-like-a-pro"&gt;code from here&lt;/a&gt; helps me to do exactly that.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;// render handlebars templates via ajax
function getTemplateAjax(path, callback) {
    var source, template;
    jqueryNoConflict.ajax({
        url: path,
        success: function (data) {
            source = data;
            template = Handlebars.compile(source);
            if (callback) callback(template);
        }
    });
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I then abstract out a function to display the compiled template, passing in the name of the template, the css selector I am targeting and the data I want to display.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;// function to compile handlebars template
    function renderHandlebarsTemplate(withTemplate,inElement,withData){
        getTemplateAjax(withTemplate, function(template) {
            jqueryNoConflict(inElement).html(template(withData));
        })
    };&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I can then call it like this, where dataDetailsTemplate.handlebars is the name of my template, and #data-details is the css selector I am targeting, and data is what I want to display.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;renderHandlebarsTemplate('dataDetailsTemplate.handlebars', '#data-details', data);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Let&amp;#8217;s go through the full &lt;a href="https://gist.github.com/raw/3230081/31abdbfb3f4746f8fb761d196dcfa81cdd38184d/data-script.js"&gt;data-script.js file&lt;/a&gt;, because there&amp;#8217;s a lot in there that I&amp;#8217;ve kind of picked up over the last several months.&lt;/p&gt;
&lt;p&gt;I don&amp;#8217;t really have an idea if it is &amp;#8220;correct&amp;#8221; to programmers out there, but I know that it works and doesn&amp;#8217;t throw me errors.&lt;/p&gt;
&lt;p&gt;In learning to use jQuery in the context of my previous CMS &amp;#8211; which used several jQuery libraries &amp;#8211; I found it just made sense to use a no conflict variable and it&amp;#8217;s something I&amp;#8217;ve just stuck with:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;var jqueryNoConflict = jQuery;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;When the DOM is ready I call the &lt;em&gt;retriveData()&lt;/em&gt; function which kind of starts the whole ball rolling:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;//begin main function
    jqueryNoConflict(document).ready(function(){
        retriveData();
    });
    //end main function&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;retriveData()&lt;/em&gt; looks for my flat JSON file, which set to a variable. It then uses jQuery&amp;#8217;s getJSON method to pull the data and run it through a function called &lt;em&gt;renderDataVisualsTemplate()&lt;/em&gt;. This is the function that will render my Handlebars template to the page with data in it.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;// grab data
    function retriveData() {
        var dataSource = 'working-data-file.json';
        jqueryNoConflict.getJSON(dataSource, renderDataVisualsTemplate);
    };&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;renderDataVisualsTemplate()&lt;/em&gt; gets an argument that represents my the data from my flat JSON file. This function runs my base handlebars template function using the name of my template (dataDetailsTemplate.handlebars), the css selector where I will inject my template (#data-details) and the data I will fill it with (data).&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;// render compiled handlebars template
    function renderDataVisualsTemplate(data){
        handlebarsDebugHelper();
        renderHandlebarsTemplate('dataDetailsTemplate.handlebars', '#data-details', data);
    };&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;After that, I have my function to pull my Handlebars template from an external file and compile it. I&amp;#8217;ve also included a Handlebars debugger, a &amp;#8220;helper&amp;#8221; function shows information about the data I am trying to work with.&lt;/p&gt;
&lt;p&gt;The base handlebars template function looks like this, and takes three parameters: the name of the template, the css selector and the data object:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;// function to compile handlebars template
    function renderHandlebarsTemplate(withTemplate,inElement,withData){
        getTemplateAjax(withTemplate, function(template) {
            jqueryNoConflict(inElement).html(template(withData));
        })
    };&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Let&amp;#8217;s take a look at the flat JSON file I am using to hold the data that will be rendered to the page. It&amp;#8217;s structured as it is in the Handlebars walkthrough.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;{&amp;quot;objects&amp;quot;: [{&amp;quot;Source&amp;quot;: &amp;quot;National Employment Law Project&amp;quot;, &amp;quot;DataOrder&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;SourceLink&amp;quot;: &amp;quot;http://www.nelp.org/&amp;quot;, &amp;quot;Data&amp;quot;: &amp;quot;12.29.2012&amp;quot;, &amp;quot;Title&amp;quot;: &amp;quot;The last day anyone will receive benefits from the Emergency Unemployment Compensation program unless Congress acts to renew it.&amp;quot;}, {&amp;quot;Source&amp;quot;: &amp;quot;Congressional Budget Office&amp;quot;, &amp;quot;DataOrder&amp;quot;: &amp;quot;2&amp;quot;, &amp;quot;SourceLink&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;Data&amp;quot;: &amp;quot;$30,000,000,000&amp;quot;, &amp;quot;Title&amp;quot;: &amp;quot;Estimated cost to renew the Emergency Unemployment Compensation program through the end of 2013.&amp;quot;}]}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;To render the data, the Handlebars template is structured just as it would be if it was inline on the index.html page, save for wrapping it in a script tag.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;div&amp;gt;
        
        &amp;lt;h2&amp;gt;Flat file data displayed on a handlebars.js template loaded with ajax&amp;lt;/h2&amp;gt;
        
            &amp;lt;p&amp;gt;: &amp;lt;strong&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;br /&amp;gt;
            -- &lt;a href="" target="_blank"&gt;&lt;em&gt;&lt;/em&gt;&lt;/a&gt;&amp;lt;/p&amp;gt;
        
    &amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In this case, I&amp;#8217;m asking that every instance of an object&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;

    &lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;be rendered to the page and structured in a certain way.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;p&amp;gt;: &amp;lt;strong&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;br /&amp;gt;
    -- &lt;a href="" target="_blank"&gt;&lt;em&gt;&lt;/em&gt;&lt;/a&gt;&amp;lt;/p&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;My HTML page isn&amp;#8217;t any special, other than have a div that will have all kinds of data injected into it thanks to Handlebars.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;div id=&amp;quot;data-details&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h3&gt;Practical Applications?&lt;/h3&gt;
&lt;p&gt;Your mileage might vary, but I&amp;#8217;ve found several practical applications of Handlebars.js just by looking at my needs.&lt;/p&gt;
&lt;p&gt;For instance, I came from shops that used a CMS where I could add html, css and JavaScript to a CMS &amp;#8220;asset&amp;#8221; which was then wrapped by the site header, rail and footer. Here at &lt;a href="http://www.scpr.org/"&gt;SCPR&lt;/a&gt;, I&amp;#8217;ve been lucky enough to have mentors who wanted to and helped to create something similar.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://projects.scpr.org/static/maps/pedestrian-safety/"&gt;This project&lt;/a&gt; is on a custom structure that lies outside of the CMS. The header and footer are each Handlebars templates, external files that I add to each new project. If I need to change a link in the footer I change it in one place and it&amp;#8217;s changed on all project pages using the template. Same goes for the header.&lt;/p&gt;
&lt;p&gt;You could easily recreate something similar. Let&amp;#8217;s say your template structure is something like:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;body&amp;gt;
        &amp;lt;div id=&amp;quot;data-header&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
            &amp;lt;div id=&amp;quot;data-container&amp;quot;&amp;gt;
                &amp;lt;div class=&amp;quot;row-fluid&amp;quot;&amp;gt;
                    &amp;lt;div class=&amp;quot;span4&amp;quot;&amp;gt;
                        &amp;lt;div id=&amp;quot;data-details&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div class=&amp;quot;span8&amp;quot;&amp;gt;
                        &amp;lt;div id=&amp;quot;data-visuals&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;div id=&amp;quot;data-footer&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/body&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You can probably spot some candidates for possible Handlebars templates now; data-header, data-details, data-visuals and data footer all make sense, where data-header and data-footer could be used on all projects.&lt;/p&gt;
&lt;p&gt;Or say you want to quickly create a table to display some information. Using the data file from my earlier example, I can create a Handlebars template to do just that:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;table class=&amp;quot;table&amp;quot;&amp;gt;
        &amp;lt;tbody&amp;gt;
            &amp;lt;tr&amp;gt;
                
                    &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
                    &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
                    &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
                
            &amp;lt;/tr&amp;gt;
        &amp;lt;/tbody&amp;gt;
    &amp;lt;/table&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Wrap up&lt;/h2&gt;
&lt;p&gt;As an intermediate beginner to the world of web development, and entering my fifth year of being an &amp;#8220;online guy&amp;#8221; in a newsroom, I&amp;#8217;ve found Handlebars to be a lot of fun. To increase that fun, there are all kinds of add ons and helper functions that you can use. &lt;a href="http://elving.github.com/swag/"&gt;swag.js&lt;/a&gt; might be the most fun thus far.&lt;/p&gt;
&lt;p&gt;See while Handlebars tried to keep logic out of the templates &amp;#8211; and I respect that &amp;#8211; there some things I&amp;#8217;d like to be able to do, and swag.js allows for some of that. For instance, if in my table example I wanted the title to be in all-caps I can do this with swag:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Or if I want to evaluate the data in my flat JSON file, I can run comparisons on my Handlebars templates.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
        
            &amp;lt;td&amp;gt;The Source is &amp;lt;/td&amp;gt;
        
            &amp;lt;td&amp;gt;No Source&amp;lt;/td&amp;gt;
        
    &lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/GoUUp__72UM" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/display-data-from-a-flat-json-file-on-a-handl/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[What I learned back at BuildMadison and in making CitySolver...]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/90a2akmMJrc/" />
    <updated>2012-12-31T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/what-i-learned-back-at-buildmadison-and-in-ma</id>
    <content type="html">&lt;p&gt;Back in September I had the chance to participate in an event called  &lt;a href="http://buildmadison.org/"&gt;Build Madison&lt;/a&gt;, a weekend event that brought tinkerers, hackers and idea people together to build things.&lt;/p&gt;
&lt;p&gt;At the event, myself and Paul Klemstine and another took up the challenge of building on a pitch to come up with a way to submit quality of life issues &amp;#8211; graffiti, potholes, sidewalks in need of repair &amp;#8211; to the city of Madison from a mobile device. Pictures were a must, as was the ability to add a user&amp;#8217;s location.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://archives.chrislkeller.com/blog-images/2012/12/city_solver_incident.png" /&gt;&lt;/p&gt;
&lt;p&gt;The Build Madison pitch also positioned this project as something that would tie in with the city&amp;#8217;s existing &amp;#8221;&lt;a href="https://www.cityofmadison.com/reportaproblem/index.cfm?"&gt;Report a Problem&lt;/a&gt;&amp;#8221; infrastructure.&lt;/p&gt;
&lt;p&gt;Paul and I developed had a good time hacking together a project we called &lt;a href="https://github.com/chrislkeller/CitySolver"&gt;City Solver&lt;/a&gt;&amp;hellip; It could aspire to be more &amp;#8211; a foundation for an open-source &lt;a href="http://seeclickfix.com/"&gt;See, Click, Fix&lt;/a&gt; or a tool for smaller municipalities &amp;#8211; or less and left to lessons learned, of which there were many that apply to many things I find myself involved in on a daily basis.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;From different angles and perspectives keep asking, &amp;#8220;Is this a problem that needs to be solved?&amp;#8221;&lt;/p&gt;
&lt;p&gt;The original pitch wanted to tie an application into the city of Madison &amp;#8220;Report a Problem&amp;#8221; system. Needless to say that is an exponentially difficult task, and one not easily tackled by a hackathon team with 24 hours to work with.&lt;/p&gt;
&lt;p&gt;And nevermind that the city of Madison has a comprehensive website that city residents can use to report specific issues and wasn&amp;#8217;t looking to extend the system in the manner the pitch stated.&lt;/p&gt;
&lt;p&gt;Finally, I knew that Open Data was on the horizon in the city, as the city council had recently passed an ordinance that would let information start following for developers to use.&lt;/p&gt;
&lt;p&gt;In the end, our project ended up with a couple prizes from the event, and I had the chance to meet with city officials on two occassions to discuss CitySolver courtesy of Eve Galanter,  a former city council member who pitched the project.&lt;/p&gt;
&lt;p&gt;The conversation were fruitful as we were able to gain some insight into future city plans in this &amp;#8220;Report a Problem&amp;#8221; arena, some of which include mobile access and user feedback that we had in mind.&lt;/p&gt;
&lt;p&gt;And as soon as the Open Data starts following, real problems might be made available to develop around.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Know who else has &amp;#8220;solved&amp;#8221; or attempted to &amp;#8220;solve&amp;#8221; this problem.&lt;/p&gt;
&lt;p&gt;Had in been better in touch with the work being done by Code For America, I would have known that developers have open-sourced similar &lt;a href="http://brigade.codeforamerica.org/applications/1"&gt;crowd-sourcing applications&lt;/a&gt; and made code available that we could have built upon.&lt;/p&gt;
&lt;p&gt;That said, as an intermediate beginner, building something myself was very fufilling and helped increase my confidence about what I was capable of learning.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spend more time on knowing the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Who are your users?&lt;/li&gt;
&lt;li&gt;What are their needs?&lt;/li&gt;
&lt;li&gt;What can we do for them?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some advice from &lt;a href="http://codeforamerica.org/author/kevin/"&gt;Code For America&amp;#8217;s Kevin Curry&lt;/a&gt; helped focus ideas on this project further, when he suggested the following after I posted to a Google Group:&lt;/p&gt;
&lt;blockquote class="posterous_medium_quote"&gt;
&lt;p&gt;The key element of your plan is residents working together to close their own tickets. That&amp;#8217;s significant. I think you should base everything off of that and make it totally obvious this is not a tool for reporting problems about the city that only the city can fix.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To Kevin&amp;#8217;s point, after thinking more about this project as something &amp;#8220;long-term&amp;#8221; I was able to come up with the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;City residents have the power, know-how and &amp;#8211; I believe &amp;#8211; a want to work together to solve some common problems.&lt;/li&gt;
&lt;li&gt;That said, that power and ability is limited when a distinction is made between a resident&amp;#8217;s fence that is in disrepair, a street with potholes and a malfunctioning street light.&lt;/li&gt;
&lt;li&gt;Success in building a coalition-based platform might best come if based around a &lt;a href="https://neighborland.com/" target="_blank"&gt;singular idea&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Privacy is a real concern and offers a very real hurdle to overcome when considering the idea of neighbors reporting on issues with neighbors.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;That last one is a biggie, hence even if everything at this point is coming up roses, would anyone use this thing?&lt;/p&gt;
&lt;p&gt;There are privacy aspects to keep in mind, and very real hurdles to overcome when considering the idea of neighbors reporting on issues with neighbors. For instance, &amp;#8220;Thank you, I&amp;#8217;d like to repair my broken fence, but I&amp;#8217;m without work and my wife is sick and I haven&amp;#8217;t made the time, so thank you for posting a photo of it online with your brutish comment.&amp;#8221;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All that said, what follows are the bullet points from the BuildMadison presentation.&lt;/p&gt;
&lt;h3&gt;Build Madison Presentation Bullet Points&lt;/h3&gt;
&lt;p&gt;&lt;img src="http://archives.chrislkeller.com/blog-images/2012/12/city_solver_web.png" alt="CitySolver" width="100%" /&gt;&lt;/p&gt;
&lt;p&gt;City Solver is a multi-device platform that allows everyday citizens to submit information about quality of life issues and problems they feel a municipality could or should address.&lt;/p&gt;
&lt;p&gt;Whether using a web app, a native Android app, or their laptop, desktop computer or tablet, city residents could send images and descriptions of these issues and opportunities.&lt;/p&gt;
&lt;p&gt;A rating system is Phase One of furthering the platform to allow neighborhood residents to band together to solve issues or to clean up the neighborhood.&lt;/p&gt;
&lt;h4&gt;Features&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Native Android app pulls geolocation and user information to auto-populate data fields, and sends photo and photo location to a database.&lt;/li&gt;
&lt;li&gt;Thumbs up and thumbs down ranking of issues to gauge interest from others.&lt;/li&gt;
&lt;li&gt;Interface thats works on devices and browsers.&lt;/li&gt;
&lt;li&gt;Photo uploads work on Android and laptop, desktop web browsers. Photo uploads will be possible for users on iOS 6 Safari.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="http://archives.chrislkeller.com/blog-images/2012/12/city_solver_mobile.png" alt="CitySolver" width="100%" /&gt;&lt;/p&gt;
&lt;h4&gt;Wishlist&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Coalition building. Sign up to band together to fix this problem.&lt;/li&gt;
&lt;li&gt;Use geolocation of an issue to query against aldermanic districts to add more context, or partner with OpenBallotBox?&lt;/li&gt;
&lt;li&gt;Allow user to submit information via SMS&lt;/li&gt;
&lt;li&gt;Use email to submit information.&lt;/li&gt;
&lt;li&gt;Full screen map with geolocation to find issues near you.&lt;/li&gt;
&lt;li&gt;Filtering &amp;amp; Search.&lt;/li&gt;
&lt;li&gt;Admin view of database to assign issues, mark as resolved or not feasible and communicate back with user if needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/90a2akmMJrc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/what-i-learned-back-at-buildmadison-and-in-ma/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Quick snippets from building off LA's most dangerous intersections map]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/wFtCmviNLsQ/" />
    <updated>2012-12-30T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/quick-snippets-from-building-off-las-most-dan</id>
    <content type="html">&lt;p&gt;tl;dr - Google offers a &lt;a href="https://developers.google.com/maps/documentation/streetview/"&gt;Streetview static image API&lt;/a&gt;, which will render a streetview image &amp;#8211; if it exists &amp;#8211; when given a latitude/longitude pair. Using this feature seemed like a good add on this map app of &amp;#8221;&lt;a href="http://projects.scpr.org/static/maps/pedestrian-safety/"&gt;dangerous intersections&lt;/a&gt;,&amp;#8221; which is on a new responsive project template developed by &lt;a href="https://github.com/organizations/SCPR"&gt;SCPR&amp;#8217;s&lt;/a&gt; Sean Dillingham. We also found a code snippet that will keep the centerpoint of the map when the viewport is resized.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Back in October &amp;#8211; before I started at &lt;a href="http://www.scpr.org/"&gt;Southern California Public Radio&lt;/a&gt; &amp;#8211; &lt;a href="http://www.scpr.org/about/people/staff/kim-bui"&gt;Kim Bui&lt;/a&gt; began asking the audience what they viewed as the &lt;a href="http://www.scpr.org/news/2012/10/02/34497/help-us-map-los-angeles-most-dangerous-areas-bicyc/" target="_blank"&gt;area&amp;#8217;s most dangerous intersections&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To date, the map has pulled in more than 140 submissions from across the Los Angeles Metropolitian area, including more than 100 in the maps first week of existence.&lt;/p&gt;
&lt;p&gt;Kim and I were able to breathe some &lt;a href="http://projects.scpr.org/static/maps/pedestrian-safety/" target="_blank"&gt;new life into the presentation&lt;/a&gt; when &amp;#8211; a couple weeks back &amp;#8211; the city of Los Angeles began to take steps to &lt;a href="http://blogdowntown.com/2012/12/7093-new-zebra-crossings-aim-to-make-53-la-intersection" target="_blank"&gt;make 53 intersections&lt;/a&gt; it identified as &amp;#8220;dangerous,&amp;#8221; safer for pedestrians.&lt;/p&gt;
&lt;p&gt;I took the newspeg and new information as an opporunity to move the map away from a Fusion Tables embedded iframe map to a &amp;#8220;new for SCPR in the last month&amp;#8221; project template that is responsive. While we&amp;#8217;ve been able to kind of get an idea if the audience and the city are on the same page when it comes to the dangerous intersections, I think we&amp;#8217;re still exploring the possibilities here.&lt;/p&gt;
&lt;p&gt;&lt;img title="Most dangerous intersections in Los Angeles" src="http://www.projects.chrislkeller.com/static-files/images/project-images/most-dangerous-intersections-la.png" alt="Most dangerous intersections in Los Angeles" width="100%" /&gt;&lt;/p&gt;
&lt;p&gt;Looking at the map now, I think adding the ability to guide the user through the city&amp;#8217;s ranking of intersection would be a helpful enhancement for the user, where through a table or a slider or simply links in a div. I also need to get better at where and how information is presented. Most of my data map mashups &amp;#8211; indeed most of all data map mashups I guess &amp;#8211; follow a similar pattern, so there&amp;#8217;s also some room to play and learn there. And I&amp;#8217;d like to create a re-usable style for the Google form on which we gather user submissions.&lt;/p&gt;
&lt;p&gt;A couple fun experiments with this map did lead to some learning however. For instance, I didn&amp;#8217;t realize Google offered a &lt;a href="https://developers.google.com/maps/documentation/streetview/"&gt;Streetview static image API&lt;/a&gt;, which will render a streetview image &amp;#8211; if it exists &amp;#8211; when given a latitude/longitude pair.  On advice from &lt;a href="http://www.scpr.org/about/people/staff/eric-zassenhaus"&gt;Eric Zassenhaus&lt;/a&gt; we added this to the map presentation, so that when a marker is clicked, an image approximate to that intersection is returned. Not all work as well as others, but more is added than subtracted I suppose.&lt;/p&gt;
&lt;p&gt;Using the API is pretty straightforward; it&amp;#8217;s just an encoded URL string inside an image tag, which makes it easy to manipulate and added data from user input or from a dataset.&lt;/p&gt;
&lt;p&gt;When combined with a Fusion Tables layer click event in the Maps API like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;google.maps.event.addListener(cityCrosswalkLayer, 'click', function(e) {
        jqueryNoConflict('#toBeRemoved').html(
            '&amp;lt;img src=\&amp;quot;http://maps.googleapis.com/maps/api/streetview?size=300x300&amp;amp;location=' + e.row['Lat'].value + ',%20' + e.row['Long'].value + '&amp;amp;fov=90&amp;amp;heading=235&amp;amp;pitch=10&amp;amp;sensor=false\&amp;quot; /&amp;gt;');
    });&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You&amp;#8217;ll get something like this when the user clicks a map marker:&lt;/p&gt;
&lt;p&gt;&lt;img title="W 8th St &amp;amp; S Alvarado St in Los Angeles using Google Streetview static image API" src="http://maps.googleapis.com/maps/api/streetview?size=300x300&amp;amp;location=34.054846,%20-118.277846&amp;amp;fov=90&amp;amp;heading=235&amp;amp;pitch=10&amp;amp;sensor=false" alt="W 8th St &amp;amp; S Alvarado St in Los Angeles" /&gt;&lt;/p&gt;
&lt;p&gt;This presentation also includes a &lt;a href="http://stackoverflow.com/questions/8792676/center-google-maps-v3-on-browser-resize-responsive"&gt;short little code snippet I found&lt;/a&gt; that will true the map&amp;#8217;s centerpoint as the window is resized. Minor stuff I know, because with responsive design the centerpoint is set when the page loads and screen size is determined, but should a user flip from landscape to portrait &amp;#8211; or vice versa &amp;#8211; this can keep a thing from becoming a thing.&lt;/p&gt;
&lt;p&gt;Including this is ultra simple. The function is simply:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;// function to maintain center point of map
function calculateCenter(){
    center = map.getCenter();
};&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The function can then be called in the same function that creates the map:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;google.maps.event.addDomListener(map, 'idle', function() {
  calculateCenter();
});

google.maps.event.addDomListener(window, 'resize', function() {
  map.setCenter(centerLosAngeles);
});&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In this case, centerLosAngeles is a variable for my starting centerpoint specified in my map options.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/wFtCmviNLsQ" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/quick-snippets-from-building-off-las-most-dan/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Link: Sunlight from the Command Line]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/Z5qsbPmnNnw/" />
    <updated>2012-12-30T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/link-sunlight-from-the-command-line</id>
    <content type="html">&lt;blockquote class="posterous_long_quote"&gt;Are you as big of a fan of &lt;a href="http://sunlightfoundation.com/people/ptagliamonte/"&gt;Paul Tagliamonte&lt;/a&gt; as I am? If so, then you are well aware of &lt;a href="https://github.com/sunlightlabs/python-sunlight"&gt;python-sunlight&lt;/a&gt;, his awesome, comprehensive Python API client for &lt;a href="http://services.sunlightlabs.com/"&gt;Sunlight&amp;#8217;s APIs&lt;/a&gt;. The latest release includes a command line interface, or CLI, so you can interact with the Sunlight APIs directly from the shell.&lt;/blockquote&gt;
&lt;p&gt;via sunlightlabs.com&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/Z5qsbPmnNnw" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/link-sunlight-from-the-command-line/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[As a beginner I see so much advice in this simple statement...]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/uDSl2Iayo3k/" />
    <updated>2012-12-30T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/as-a-beginner-so-much-advice-in-this-simple-s</id>
    <content type="html">&lt;blockquote class="twitter-tweet"&gt;
&lt;p&gt;Code linting is your first unit test!&lt;/p&gt;
&amp;mdash; Eric Sorenson (@dubharmonic) &lt;a href="https://twitter.com/dubharmonic/status/285535430827458560"&gt;December 30, 2012&lt;/a&gt;&lt;/blockquote&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/uDSl2Iayo3k" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/as-a-beginner-so-much-advice-in-this-simple-s/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Mother Jones, Slate open up a couple stunning datasets related to gun violence]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/0tvGUomi7O4/" />
    <updated>2012-12-29T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/mother-jones-slate-open-up-a-couple-stunning</id>
    <content type="html">&lt;p&gt;In the wake of mass shootings this year, and the journalism that followed, &lt;a href="http://www.motherjones.com/"&gt;Mother Jones&lt;/a&gt; has opened up a dataset of mass shootings in the U.S. between 1982 and 2012. Included are a spreadsheet of the incidents, and a spreadsheet of the weapons used. You can read more about it &lt;a href="http://www.motherjones.com/politics/2012/12/mass-shootings-mother-jones-full-data"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Meanwhile, &lt;a href="http://www.npr.org/blogs/thetwo-way/2012/12/28/168204661/tracking-gun-related-deaths-one-tweet-at-a-time"&gt;Slate has partnered&lt;/a&gt; with the Twitter account &lt;a href="https://twitter.com/GunDeaths" target="_blank"&gt;@GunDeaths&lt;/a&gt; to create &amp;#8220;an &lt;a href="http://www.slate.com/articles/news_and_politics/crime/2012/12/gun_death_tally_every_american_gun_death_since_newtown_sandy_hook_shooting.html"&gt;interactive, crowdsourced tally&lt;/a&gt; of the toll firearms have taken since Dec. 14&amp;#8221; &amp;#8211; the date of the mass shooting in Newtown, Conn. that left 26 dead.&lt;/p&gt;
&lt;blockquote class="posterous_medium_quote"&gt;
&lt;p&gt;Of course, this data is incomplete. Not all reports get caught by @GunDeaths&amp;rsquo; news alerts or his followers. Suicides, which are estimated to make up as much as 60 percent of gun deaths, typically go unreported. Nevertheless, we at Slate want to assemble this data as best we can.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Slate too has opened up the data and made it available for &lt;a href="https://docs.google.com/spreadsheet/pub?key=0AmjG42aUKrlodEhxVkxhaFI1OEM2anUyd20ySWFnS2c&amp;amp;output=csv"&gt;download&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/0tvGUomi7O4" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/mother-jones-slate-open-up-a-couple-stunning/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Link: Anyone can do it. Data journalism is the new punk]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/pSEH-UmKwHw/" />
    <updated>2012-12-14T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/link-anyone-can-do-it-data-journalism-is-the</id>
    <content type="html">&lt;div class="posterous_bookmarklet_entry"&gt;
&lt;blockquote class="posterous_long_quote"&gt;
&lt;p&gt;&lt;strong&gt;1) &lt;a href="https://docs.google.com/spreadsheet/ccc?key=0AonYZs4MzlZbcGhOdG0zTG1EWkVNdTNTRkE2N2ZiVFE"&gt;This is a dataset&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2) &lt;a href="https://docs.google.com/spreadsheet/ccc?key=0AonYZs4MzlZbdC1fandTcXJ0OG9WYW5mZ1NOT1VaTHc#gid=0"&gt;Here&amp;#8217;s another&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3) &lt;a href="http://www.guardian.co.uk/news/datablog/2012/mar/28/data-visualisation-tools-free"&gt;Here are some free tools&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOW BE A DATA JOURNALIST&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;OK, it lacks a certain 1976 grittiness, but the theory is there. You don&amp;#8217;t have to be a developer or a coder to be a data journalist.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="posterous_quote_citation"&gt;via &lt;a href="http://www.guardian.co.uk/news/datablog/2012/may/24/data-journalism-punk"&gt;guardian.co.uk&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When I first read this back in May I thought I was reminded of a &lt;a href="http://www.greglinch.com/2012/03/music-and-code-great-insights-from-david-johnson-zed-shaw-and-others.html"&gt;Greg Linch post&lt;/a&gt;, or &amp;#8220;three-chord song for journalists,&amp;#8221; a phrase I used in a &lt;a href="http://youtu.be/F7vi1I9WG9w"&gt;project pitched&lt;/a&gt; during last summer&amp;#8217;s &lt;a href="http://www.chrislkeller.com/tag/mozillaknightjournalismlearninglab"&gt;Knight-Mozilla Journalism Learning Lab&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I certainly didn&amp;#8217;t think for one second that I was less than three months away from being approached about, interviewed for and offered a position as a &lt;a href="http://www.scpr.org/about/people/staff/chris-keller"&gt;data journalist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Reading it now, and in combination with this thought-starter from &lt;a href="https://twitter.com/hbillings" target="_blank"&gt;Heather Billings&lt;/a&gt; and the resulting conversation&amp;#8230;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote class="twitter-tweet"&gt;
&lt;p&gt;When a guy&amp;#8217;s dev skills fall short, does he have &amp;#8220;I don&amp;#8217;t deserve this job&amp;#8221; thoughts? I&amp;#8217;ve only observed it in myself+female coder friends.&lt;/p&gt;
&amp;mdash; Heather Billings (@hbillings) &lt;a href="https://twitter.com/hbillings/status/279723319656321024"&gt;December 14, 2012&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;#8230;I am more convinced than ever that while I have learned that I can learn how to find solutions to some elementary things, in order to &amp;#8220;graduate&amp;#8221; into someone who practices a &amp;#8220;craft&amp;#8221; in this field I will need to double down on time and practice and time and practice.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/pSEH-UmKwHw" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/link-anyone-can-do-it-data-journalism-is-the/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Link: John Keefe on Designing a Course in Data Journalism]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/Pi3hEmKQtVQ/" />
    <updated>2012-11-26T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/link-designing-a-course-in-data-journalism</id>
    <content type="html">&lt;div class="posterous_bookmarklet_entry"&gt;
&lt;blockquote class="posterous_long_quote"&gt;When asked what such a course might look like, I point folks to Brian Boyer&amp;#8217;s theoretical and amazing &lt;a href="http://www.niemanlab.org/2012/09/brian-boyer-welcome-to-hacker-journalism-101-take-your-seats/"&gt;Hacker Journalism 101&lt;/a&gt;. Journalism needs more journalists who can code, and this is a great way to get there. &amp;#8230;
&lt;p&gt;In addition to programming, here are some of my favorite topics for classes, readings or workshops:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Finding data for your stories&lt;/li&gt;
&lt;li&gt;Finding stories in your data&lt;/li&gt;
&lt;li&gt;How to tell one story well&lt;/li&gt;
&lt;li&gt;All data is dirty &amp;#8230; and what to do about that&lt;/li&gt;
&lt;li&gt;Basic stats&lt;/li&gt;
&lt;li&gt;Percentage points for journalists&lt;/li&gt;
&lt;li&gt;Mapmaking made easy&lt;/li&gt;
&lt;li&gt;Lying and truthing with easily-made maps&lt;/li&gt;
&lt;li&gt;When maps shouldn&amp;#8217;t be maps&lt;/li&gt;
&lt;li&gt;Basic chartbuilding&lt;/li&gt;
&lt;li&gt;Lying and truthing with charts and graphs&lt;/li&gt;
&lt;li&gt;Did I mention programming?&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div class="posterous_quote_citation"&gt;via &lt;a href="http://johnkeefe.net/designing-a-course-in-data-journalism"&gt;johnkeefe.net&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s up to the individual to find what works for them, but that said, what worked for me was to first learn code to visualize data followed by learn code to gather data.&lt;/p&gt;
&lt;p&gt;Now I need to learn code to analyze data while refining and bettering my skills in the first two areas, especially developing a &lt;a href="http://knightcenter.utexas.edu/blog/00-12180-knight-center-offers-second-massive-online-course-introduction-infographics-and-data-v" target="_blank"&gt;better eye for visualization&lt;/a&gt;&amp;nbsp;and when not to use &lt;a href="http://en.wikipedia.org/wiki/Law_of_the_instrument" target="_blank"&gt;the hammers&lt;/a&gt; I&amp;#8217;ve acquired&amp;#8230;&lt;/p&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/Pi3hEmKQtVQ" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/link-designing-a-course-in-data-journalism/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Using csvkit and PostgreSQL to mimic a bit of Microsoft Access]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/VtALEAgghE0/" />
    <updated>2012-11-25T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/using-csvkit-and-postgresql-to-mimic-a-bit-of</id>
    <content type="html">&lt;p&gt;Over the last couple weeks I had the first real chance to take a really large dataset and explore it using tools like &lt;a href="http://csvkit.readthedocs.org/en/latest/"&gt;csvkit&lt;/a&gt; and &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Needless to say I learned a lot, and with that learning came a bit of backtracking. But something I have learned to do as a matter of course now is to document every step of a project &amp;#8211; whether coding or writing. The extra effort not only comes in handy when creating a workflow, but offers plenty of advice and ideas for others who are also learning. What follows are an edited/revised version of the notes from my scratchpad file.&lt;/p&gt;
&lt;p&gt;This dataset came in 15 text files &amp;#8211; five main files and two sets of five text files related to the main set through a common ID. In total there were some 125,000 rows. I also received a &amp;#8220;column key&amp;#8221; describing the name of each field, the data types for each filed and what designations stood for.&lt;/p&gt;
&lt;p&gt;Without access to Access, and after several attempts to use LibreOffice Base to create three tables in a database and JOIN them based on common ID &amp;#8211; crash, crash, crash &amp;#8211; I sucked it up and learned how to use csvkit and PostgreSQL. Boy am I glad I did. And boy am I thankful for &lt;a href="https://twitter.com/onyxfish"&gt;Christopher Groskopf&amp;#8217;s&lt;/a&gt; &lt;a href="http://csvkit.readthedocs.org/en/latest/"&gt;csvkit&lt;/a&gt; and his imagination about what is possible, and the ability to progam it.&lt;/p&gt;
&lt;p&gt;Thinking about it now reminds me of something &lt;a href="https://twitter.com/markng"&gt;Mark Ng&lt;/a&gt; said duing #NICAR12 regarding Chris: &amp;#8220;He&amp;#8217;s from the future&amp;#8221;&lt;/p&gt;
&lt;p&gt;As I mentioned, I attempted to document each step, query, failure, success and learning moment, so while this is very much a how to, it is also very long, winding and potentially confusing to some. That said, if you like journo-tech-nerdery &amp;#8211; or what to offer some tips &amp;#8211; please enjoy.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Getting started with some tools&lt;/h4&gt;
&lt;p&gt;csvkit is a command-line toolset to explore CSV files. It can be installed into a virtual environment which isolates it from key system packages:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;sudo pip install virtualenv
virtualenv venv
source venv/bin/activate
pip install csvkit&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;It can also be installed globally:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;sudo pip install csvkit&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If you&amp;#8217;re beginning on the command line, on the suggestion of Joe Germuska, &lt;a href="http://cli.learncodethehardway.org/book/"&gt;this&lt;/a&gt; is a great resource to learn from.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Preparing the data for exploration&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;After importing into Google Docs failed &amp;#8211; the dataset was too larger &amp;#8211; I opened one of the main text files in LibreOffice to see what I was working with.&lt;/li&gt;
&lt;li&gt;The file came without headers so I pulled the first few rows into a new CSV file, imported that into a Google spreadsheet &amp;#8211; easier to type in &amp;#8211; and used the accompanying key to enter in column information.&lt;/li&gt;
&lt;li&gt;I then exported the header row as new file, opened each of the data files in a text editor, pasted the header to the top of the file and saved as CSV. I repeated this step for all 15 files. (There&amp;#8217;s a time savings to be found here!)&lt;/li&gt;
&lt;li&gt;I fired up csvkit and ran &lt;a href="http://csvkit.readthedocs.org/en/latest/scripts/csvclean.html"&gt;csvclean&lt;/a&gt; on each of the 15 files to look for syntax errors or bad rows.&lt;/li&gt;
&lt;li&gt;I tried to use csvstack to combine the files, but I ran into errors. That I couldn&amp;#8217;t decipher. So instead I manually combined each of the CSV files into one large CSV file with one row of headers. (More time savings to be found!)&lt;/li&gt;
&lt;li&gt;I dropped the three combined CSV files into my &amp;#8220;data_inbox&amp;#8221; and fired up a script based on one authored by &lt;a href="http://twitter.com/jsguntzel"&gt;Jeff Severns Guntzel&lt;/a&gt; that:
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Makes a backup of the data files.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Creates a new project directory with a specified folder structure.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Audits the CSV using csvkit&amp;#8217;s &lt;a href="http://csvkit.readthedocs.org/en/latest/scripts/csvstat.html"&gt;csvstat&lt;/a&gt; function and creates a &lt;a href="https://github.com/chrislkeller/csv_audit_and_backup/blob/master/sample_abstract.md"&gt;data-abstract file&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Moves all of the files into the new project directory.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then I opened up my data-abstract-file to see what I had. Here&amp;#8217;s an example of what I was able to see at a glance:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;47. type_of_collision
     &amp;lt;type 'unicode'&amp;gt;
     Nulls: False
     Unique values: 10
     5 most frequent values:
         B:  50090
         C:  33952
         E:  16700
         D:  13184
         F:  3913
     Max length: 1&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In this case, B, C, E, D and F correspond to a specific value in the column key. Thanks to some magic from Chris and Jeff, at a quick glance I was able to decipher values in every column of the data file and pass information on to the editor for this story.&lt;/p&gt;
&lt;p&gt;You can use a csvkit function to do this on an individual column as well, substituting the column_number and file_name in the example command below.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;csvstat -c **column_number** --freq **file_name**&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;hr /&gt;
&lt;h4&gt;Making the deep dive&lt;/h4&gt;
&lt;p&gt;Once I learned we wanted to focus on a specific type of record I used csvkit&amp;#8217;s csvgrep (search) function to search the rows for that value and output the results to a new file which was only about 4,000 odd rows or so.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;csvgrep -c 48 -m &amp;quot;A&amp;quot; **file_name** &amp;gt; **output_file_name**&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I then double-checked my work to make sure I had the expected number of rows.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;csvstat **output_file_name**&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The number of rows matched up, but something had changed that would impact my later efforts which I&amp;#8217;ll come back to.&lt;/p&gt;
&lt;p&gt;Primary in my mind was figuring out a way to JOIN the three datasets together based on their common ID. This is the part where I googled for open source access and LibreOffice Base How-To and struggled to make it work as the application continued to crash when I tried to import the larger secondary file.&lt;/p&gt;
&lt;p&gt;Creating django models and relating the data that way came to mind, and then it dawned me that I have mySQL and postgreSql installed in my local development environment and I might as well use them for what they&amp;#8217;re supposed to be used for.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Tools revisited&lt;/h4&gt;
&lt;p&gt;Some kind folks at Heroku have created a &lt;a href="http://postgresapp.com/"&gt;one-click installer&lt;/a&gt; for &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt; on a Mac. I had gone through the &lt;a href="https://gist.github.com/2280659"&gt;Homebrew route&lt;/a&gt;, and while I eventually made it work, the one-click installer worked really well. Just had to open my .bashprofile and set the correct $PATH.&lt;/p&gt;
&lt;p&gt;There is great PostgreSQL &lt;a&gt;documentation&lt;/a&gt; that walks through the basic use, and I also installed &lt;a href="http://www.pgadmin.org/download/"&gt;pgAdmin III&lt;/a&gt; which is a GUI to explore the databases, which is good for a noob like me.&lt;/p&gt;
&lt;p&gt;To get started creating a new database in my &lt;a href="http://od-eon.com/blogs/calvin/postgresql-cheat-sheet-beginners/"&gt;local PostgreSQL install&lt;/a&gt; I:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Created a new user.&lt;/li&gt;
&lt;li&gt;Created a new database for the user.&lt;/li&gt;
&lt;li&gt;And then logged into the database I made using the PostgreSQL command line application.&lt;/li&gt;
&lt;li&gt;Along the way I learned some additional commands in the PostgreSQL command line application.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Activate PostgreSQL&lt;/strong&gt;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;psql&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;List databases&lt;/strong&gt;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;\list&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;See if table has been created&lt;/strong&gt;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;\dt&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Drop table&lt;/strong&gt;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;DROP TABLE **name of table**&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Quit psql&lt;/strong&gt;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;\q&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I then connected pgAdmin III to my local PostgreSQL instance by specifying the user and leaving the &lt;a href="http://www.pgadmin.org/docs/1.8/connect.html"&gt;server address blank&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And then the fun began&amp;#8230;&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Using PostgreSQL like Access&lt;/h4&gt;
&lt;p&gt;So the goal of the project from the beginning was to take the three data sets and JOIN them together based on the common ID. Forgoing Access and using PostgreSQL meant I had to craft CREATE TABLE statements. Little did I know at the time, someone had already thought of this and developed a crafty solution.&lt;/p&gt;
&lt;p&gt;But I&amp;#8217;ll come back to that as well. To create the statements I grabbed the header rows from the three files, added data types and crafted a &lt;a href="http://www.postgresql.org/docs/9.2/static/tutorial-table.html"&gt;CREATE TABLE&lt;/a&gt; statement. So still in the the PostgreSQL command line application I added something like this following:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;CREATE TABLE **table_name** (case_id integer, special_information_1 text, special_information_2 text, special_information_3 text);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;pgAdmin III told me it wanted each table to have a primary key before I could edit them, so I spent some time figuring out how to do &lt;a href="http://stackoverflow.com/questions/9726535/primary-foreign-keys-in-pgadmin"&gt;that on a table&lt;/a&gt; using something called a &lt;a href="http://www.postgresql.org/docs/9.2/static/sql-createsequence.html"&gt;sequence&lt;/a&gt;.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;ALTER TABLE **table_name** ADD COLUMN record_id serial PRIMARY KEY;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Then I wanted to upload my CSV files into the PostgreSQL Database table. I found a couple methods &amp;#8211; I liked &lt;a href="http://www.ensode.net/postgresql_csv_import.html"&gt;this one&lt;/a&gt;.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;COPY **table_name** '**path_to_file/**file_name**' DELIMITERS ',' CSV;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Then I learned an important fact:&lt;/p&gt;
&lt;blockquote class="posterous_short_quote"&gt;
&lt;p&gt;&amp;#8220;If you don&amp;#8217;t have access to the server, you can use psql&amp;#8217;s \COPY command which is very similar to COPY FROM but works with local files. See the manual for details.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;\COPY **table_name** '**path_to_file/**file_name**' DELIMITERS ',' CSV;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And then that didn&amp;#8217;t work either. I later learned another important fact: that if your csv file has a header row, well you need to tell PostgreSQL that, hence this command:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;\COPY **table_name** '**path_to_file/**file_name**' DELIMITERS ',' CSV HEADER;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;That worked&amp;hellip; because the CSV HEADER designation told PostgreSQL that the CSV file had a header row.&lt;/p&gt;
&lt;p&gt;And then I learned that csvkit &amp;#8211; wonder of wonders &amp;#8211; can not only generate CREATE TABLE statements from a CSV, but it can freaking create a database and upload a CSV to a new table in that database with a simple command. Heck, it can take a whole folder of CSV files and create tables from them. Back to Mark Ng: &amp;#8220;From the Future.&amp;#8221;&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Using csvkit with PostgreSQL (1)&lt;/h4&gt;
&lt;p&gt;So in learning that I can use several csvkit to do what I had done above, I set out to create the project again using only the utility. My notes are also more streamlined as I have a better idea of how to achieve my end result.&lt;/p&gt;
&lt;p&gt;With PostgreSQL up and running, you can use &lt;a href="http://csvkit.readthedocs.org/en/latest/scripts/csvsql.html"&gt;csvkit&lt;/a&gt; to create a database.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;createdb **name_of_database**&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;From there, you can use csvkit&amp;#8217;s &lt;a href="http://csvkit.readthedocs.org/en/latest/scripts/csvsql.html"&gt;csvsql&lt;/a&gt; command to generate a CREATE TABLE statement based on your CSV file.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;csvsql -i postgresql  **file_name**&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Running the above command in the terminal left me with something like this that I can use in the PostgreSQL application:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;CREATE TABLE &amp;quot;**name_of_table**&amp;quot; (
        case_id INTEGER NOT NULL,
        special_information_1 VARCHAR(1) NOT NULL,
        special_information_2 VARCHAR(1) NOT NULL,
        special_information_3 VARCHAR(1) NOT NULL,
        other_associated_factor_1 VARCHAR(1) NOT NULL,
        other_associated_factor_2 VARCHAR(1) NOT NULL,
);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;But you can also use &lt;a href="http://csvkit.readthedocs.org/en/latest/scripts/csvsql.html"&gt;csvsql&lt;/a&gt; to create the database and import data from a CSV directly into PostgreSQL. Make sure your virtual environment has psycopg2 or MySQL-python installed depending on your choice of database. Use pip install psycopg2 or pip install MySQL-python&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;createdb *name_of_database*
csvsql --db postgresql:///*name_of_database* --insert *name_of_file*
csvsql --db postgresql:///*name_of_database* --insert *name_of_file*
csvsql --db postgresql:///*name_of_database* --insert *name_of_file*&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And best of all, you can use &lt;a href="http://csvkit.readthedocs.org/en/latest/scripts/csvsql.html"&gt;csvsql&lt;/a&gt; to create tables for an entire folder of CSV files and create PostgreSQL tables based on those files.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;createdb *name_of_database*
csvsql --db postgresql:///*name-of-database* --insert *path-to-file*/*name-of-file*.csv&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Log into PostgreSQL application from the command line and add primary keys to the tables after they are created per pgAdmin III.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;psql *name_of_database*
ALTER TABLE *name_of_table1* ADD COLUMN record_id serial PRIMARY KEY;
ALTER TABLE *name_of_table2* ADD COLUMN record_id serial PRIMARY KEY;
ALTER TABLE *name_of_table3* ADD COLUMN record_id serial PRIMARY KEY;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Learn to create a join on two tables using case_id. Great visual guide is &lt;a href="http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;SELECT * FROM *name_of_table1*; (4662 rows)
SELECT * FROM *name_of_table2*; (95716 rows)
SELECT * FROM *name_of_table3*; (257333 rows)
SELECT name_of_table1.*, name_of_table2.* FROM name_of_table1, name_of_table2 WHERE name_of_table1.case_id = name_of_table2.case_id; (5906 rows)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Export to a new file, I&amp;#8217;ll call it joined_new_file.csv.&lt;/p&gt;
&lt;p&gt;Load file as new table&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;csvsql --db postgresql:///*name-of-database* --insert *joined_new_file.csv*&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Test various JOIN methods to get proper matching of records. This case records in Table 1 could have several corresponding records in Table 2. So I went with a LEFT OUTER JOIN.&lt;/p&gt;
&lt;p&gt;It was about this time that I learned that the data type of a column in my table had changed from  to . I was able to trace the changce back to something that happened when I used csvstat.&lt;/p&gt;
&lt;p&gt;I filtered the file to give me all the rows with a single value. In this case it was the letter &amp;#8220;A&amp;#8221;. When I created a new table based on that filter I got the . Some helpful advice from &lt;a href="http://twitter.com/adamhooper"&gt;Adam Hooper&lt;/a&gt; on the NICAR listserv gave me the how&amp;#8217;s and why&amp;#8217;s.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In CSV, &lt;em&gt;every&lt;/em&gt; value is a string&amp;#8211;no exceptions. csvkit &amp;#8220;intelligently&amp;#8221; guesses at a column type by looking at every string value and seeing if they all follow the same pattern.&lt;/p&gt;
&lt;p&gt;For instance, if every value looks like &amp;#8220;12:23:31&amp;#8221;, it&amp;#8217;ll pick a time format.&lt;/p&gt;
&lt;p&gt;If you have 200,000 rows, and &lt;em&gt;one&lt;/em&gt; row has a value that isn&amp;#8217;t a time format, csvkit will (correctly) call it a &amp;#8220;string&amp;#8221;. But if you remove the row that isn&amp;#8217;t formatted like a time, then csvkit will (correctly) call the column &amp;#8220;time&amp;#8221; in the resulting CSV.&lt;/p&gt;
&lt;p&gt;I suppose you&amp;#8217;ve read this far and gone, &amp;#8220;yes, but why would it think &amp;#8216;A&amp;#8217; is a datetime?&amp;#8221; And the answer is &amp;#8230; (wait for it) &amp;#8230; &amp;#8220;A&amp;#8221; is a time value! &amp;#8220;A&amp;#8221; is short for &amp;#8220;AM&amp;#8221;, so it gets parsed as 12:00 a.m. on the morning the program is executed. (The same trick doesn&amp;#8217;t work for &amp;#8220;P&amp;#8221;, because of a bug in the &amp;#8220;dateutil&amp;#8221; library csvkit depends on.)&lt;/p&gt;
&lt;p&gt;And since &lt;em&gt;every&lt;/em&gt; value in column 48 is now &amp;#8216;A&amp;#8217;, &lt;em&gt;every&lt;/em&gt; value is a datetime &amp;#8211; meaning the entire column is a datetime column. (This wasn&amp;#8217;t the case before, because there were non-&amp;#8220;A&amp;#8221; values in column 48, so csvkit didn&amp;#8217;t interpret it as a datetime.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And for my purposes I didn&amp;#8217;t really need column 48 to be the correct data type. In this case, the data was all of the same record. But because it had changed on me I began to wonder what else might have changed on me.&lt;/p&gt;
&lt;p&gt;Regardless, I figured I&amp;#8217;d give it another go just to streamline things a bit.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Using csvkit with PostgreSQL (2)&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Run csvstat to make sure data types are intact.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="http://csvkit.readthedocs.org/en/latest/scripts/csvsql.html"&gt;csvkit&lt;/a&gt; to create PostgreSQL database and tables from an entire folder of CSVs.&lt;/li&gt;
&lt;li&gt;Query working_accidents.csv for rows in which motor_vehicle_involved_with = non-collision and save as working_non_collisions.csv.&lt;/li&gt;
&lt;li&gt;Generate CREATE statement for working_non_collisions.csv to upload into PostgreSQL.&lt;/li&gt;
&lt;li&gt;Add data from csv into the working_non_collisions table. The CSV HEADER designation says its a CSV file with a header row.&lt;/li&gt;
&lt;li&gt;Query for the related records on working_non_collisions and working_party tables to get expected output.&lt;/li&gt;
&lt;li&gt;Run INNER JOIN to see of same result occurs.&lt;/li&gt;
&lt;li&gt;Export as accidents_non_collisions_and_parties.csv. Open in LibreOffice and delete the duplicate case_id column.&lt;/li&gt;
&lt;li&gt;Generate CREATE statement for accidents_non_collisions_and_parties.csv to upload into PostgreSQL. In this instance there was a duplicate column for case_id that happened when I ran the select statement. Also changed motor_vehicle_involved_with to VARCHAR(1) and oaf_violation_code VARCHAR(4).&lt;/li&gt;
&lt;li&gt;Add data from csv into the accidents_non_collisions_and_parties table. The CSV HEADER designation says its a CSV file with a header row.&lt;/li&gt;
&lt;li&gt;Query on connections between accident &amp;amp; parties and victims. But then I realized this ignores accidents in which there was no victim.&lt;/li&gt;
&lt;li&gt;Test various JOIN methods to see different results. I want all records from accidents_non_collisions_and_parties and any that match in working_victim, which I learned is a LEFT OUTER JOIN.&lt;/li&gt;
&lt;li&gt;Export as joined_accidents_non_collisions.csv. Open in LibreOffice and delete the duplicate case_id columns.&lt;/li&gt;
&lt;li&gt;Doublecheck to see that motor_vehicle_involved_with column hasn&amp;#8217;t changed to date-time type.&lt;/li&gt;
&lt;li&gt;Generate CREATE statement for working_non_collisions.csv to upload into PostgreSQL.&lt;/li&gt;
&lt;li&gt;Run various queries from within pgAdmin III&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/VtALEAgghE0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/using-csvkit-and-postgresql-to-mimic-a-bit-of/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[California dreams... they're a bit crazy...]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/BZ4yheDR0EQ/" />
    <updated>2012-11-16T00:00:00-08:00</updated>
    <id>http://blog.chrislkeller.com/california-dreams-theyre-a-bit-crazy</id>
    <content type="html">&lt;p&gt;Been having the craziest dreams since moving out west&amp;#8230;&lt;/p&gt;
&lt;p&gt;So last night in my dreams they were releasing Halo 27 or something like that, and all day people were getting ready for it, including our ex-landlords who were packing up their house.&lt;/p&gt;
&lt;p&gt;And as a part of it video game release they had a live TV special to celebrate it, and some guy in a suit was talking about the video game and then he opened this huge door and from far away you saw this figure that looked like the character in the Lord of the Rings: The Two Towers &amp;#8211; the guy running towards the Deeping Wall who blows it up with a torch &amp;#8211; and he actually runs through the TV into real-life. He took out my dad and my uncle and suddenly there&amp;#8217;s like millions of this guy running around the world.&lt;/p&gt;
&lt;p&gt;Next thing I know I&amp;#8217;m out in the street, and most people are dressed up in camo and they have weapons and somehow I have a weapon and a guy from high school sees me and shouts &amp;#8211; he&amp;#8217;s got a weapon &amp;#8211; and I must have missed something by not playing the game because if you didn&amp;#8217;t see the secret message at the end of Halo 26 you weren&amp;#8217;t going to be prepared and couldn&amp;#8217;t be after the fact.&lt;/p&gt;
&lt;p&gt;So I eventually surrender my weapon and then I wander around. Eventually I call some guy I used to work with to ask what happens next and he said he was at home getting ready for the electric sky show and I hung up bewildered. And then the electric sky show started and I said holy crap&amp;#8230; and then I woke up.&lt;/p&gt;
&lt;p&gt;What?&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/BZ4yheDR0EQ" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/california-dreams-theyre-a-bit-crazy/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Fantastic thoughts to live -- and work -- for]]></title>
    <link href="http://feedproxy.google.com/~r/ChrisLKeller/~3/AjjPLdXzdB0/" />
    <updated>2012-10-09T00:00:00-07:00</updated>
    <id>http://blog.chrislkeller.com/fantastic-thoughts-to-live-and-work-for</id>
    <content type="html">&lt;ul&gt;
&lt;li&gt;Working longer is not working harder. Go home.&lt;/li&gt;
&lt;li&gt;40 hours includes the commute.&lt;/li&gt;
&lt;li&gt;Resist the urge to call a meeting.&lt;/li&gt;
&lt;li&gt;Consensus is bullshit. Do what&amp;rsquo;s best for the company.&lt;/li&gt;
&lt;li&gt;We will not ship shit.&lt;/li&gt;
&lt;li&gt;If it&amp;rsquo;s hard to use, it hurts the product, the company, and our reputation.&lt;/li&gt;
&lt;li&gt;You will do customer service for the products you create.&lt;/li&gt;
&lt;li&gt;We will work in public. Our code, our designs, and our ideas are not our business. We are our business. Our products are our business. Customers are our business.&lt;/li&gt;
&lt;li&gt;People are expensive. We will strive to keep individuals working for the customer, and not on the business.&lt;/li&gt;
&lt;li&gt;Efficiency is everything. We will remove obstructions.&lt;/li&gt;
&lt;li&gt;We will not celebrate. Every day will be awesome, or we stop what we&amp;rsquo;re doing and make it awesome. Cake is for gazelles, and we are lions.&lt;/li&gt;
&lt;li&gt;We will enjoy our work, our products, and our lives. We will make work awesome.&lt;/li&gt;
&lt;li&gt;We will be lean. We will NOT ignore problems, and we will swarm when issues arise.&lt;/li&gt;
&lt;li&gt;You are an adult. You will manage your own machine and tools.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://www.stefankendall.com/2012/10/core-values.html"&gt;Via stefankendall.com: Core Values.&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/ChrisLKeller/~4/AjjPLdXzdB0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.chrislkeller.com/fantastic-thoughts-to-live-and-work-for/</feedburner:origLink></entry>
  
</feed>
