<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Ben Godfrey</title><link>http://aftnn.org/</link><description /><language>en-GB</language><lastBuildDate>Mon, 15 Apr 2013 10:50:25 +0300</lastBuildDate><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/afternoon" /><feedburner:info uri="afternoon" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>51.4779</geo:lat><geo:long>-0.2136</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-nd/2.0/</creativeCommons:license><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><item><title>Quantified Self
</title><link>http://feedproxy.google.com/~r/afternoon/~3/2gDSvbqdH84/</link><description>&lt;p&gt;In January, &lt;a href="http://quantifiedself.com/2013/01/pew-internet-research-the-state-of-self-tracking/"&gt;Pew Research found that 21% of &lt;span class="caps"&gt;US&lt;/span&gt; adults track some aspect of their health using technology&lt;/a&gt;. This is part of a phenomenon called &amp;#8220;Quantified Self&amp;#8221; &amp;mdash; the measurement of personal behaviours and activities, often using technology such as smartphones and web apps. I&amp;#8217;m a self-quantifier and have been for a while. Over the years I&amp;#8217;ve tracked a number of&amp;nbsp;dimensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running and training bike rides using &lt;a href="http://runkeeper.com/"&gt;Runkeeper&lt;/a&gt; and &lt;a href="http://strava.com/"&gt;Strava&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;How often I eat meat, do yoga, drink coffee, caffeine or alchohol using &lt;a href="http://chains.cc/"&gt;chains.cc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Whether I clear out my email inboxes each&amp;nbsp;day&lt;/li&gt;
&lt;li&gt;Money (spending, saving, credit card use) using &lt;a href="https://www.anzmoneymanager.com/personal/"&gt;&lt;span class="caps"&gt;ANZ&lt;/span&gt; MoneyManager&lt;/a&gt; (about the best &lt;a href="http://aftnn.org/2012/oct/04/personal-finance-dashboards-uk-customers/"&gt;personal finance dashboard available in the &lt;span class="caps"&gt;UK&lt;/span&gt;&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;How many miles I&amp;#8217;ve cycled (commuting, training and events), using &lt;a href="http://your.flowingdata.com/"&gt;your.flowingdata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Travel using &lt;a href="http://www.tripadvisor.co.uk/members/Afternoon"&gt;TripAdvisor&lt;/a&gt; and &lt;a href="https://www.kayak.co.uk/trips"&gt;Kayak&amp;#8217;s My&amp;nbsp;Trips&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Driving&amp;nbsp;Improvements&lt;/h2&gt;

&lt;p&gt;I use this data to drive improvements in my&amp;nbsp;life.&lt;/p&gt;

&lt;p&gt;For example, if I&amp;#8217;m training for a race, I check that I&amp;#8217;m building up my distance at the right rate in preparation. To understand the data, I visualise it using histograms and aggregates statistics. My all time distance on Runkeeper right now is 1,188 &lt;span class="caps"&gt;KM&lt;/span&gt;. I&amp;#8217;ve only run a few KMs this month, but last month I ran almost 50 &lt;span class="caps"&gt;KM&lt;/span&gt; (I had a big&amp;nbsp;race).&lt;/p&gt;

&lt;p&gt;My self-quantification breaks down into two categories: &amp;#8220;performance&amp;#8221; and &amp;#8220;habits.&amp;#8221; The performance stuff (running and cycling) is a bit vain, but I feel that collecting and visualising performance data has helped me to achieve some big goals, like running a&amp;nbsp;marathon.&lt;/p&gt;

&lt;h2&gt;Better&amp;nbsp;Habits&lt;/h2&gt;

&lt;p&gt;Measuring some of my habits helps me to make long-term behavioural&amp;nbsp;changes.&lt;/p&gt;

&lt;p&gt;Meat-eating is a good example. I love meat, but I like to keep the total amount I consume down. I track whether I ate meat or not each day by ticking a box in &lt;a href="http://chains.cc/"&gt;chains.cc&lt;/a&gt;. Later I can look back and see easily whether I&amp;#8217;m sticking to my goal or if I need to work harder. Having aggregate goals like &amp;#8220;eat meat once per week&amp;#8221; allows me to indulge when the meat on the table is really good (like when I went to &lt;a href="http://www.auxlyonnais.com/en"&gt;Aux Lyonnais&lt;/a&gt;) but means that I get the health benefits of a mostly plant-based&amp;nbsp;diet.&lt;/p&gt;

&lt;h2&gt;Self-Experiments&lt;/h2&gt;

&lt;p&gt;Some self-quantifiers conduct &lt;a href="http://quantifiedself.com/2011/04/how-to-self-experiment/"&gt;self-experiments&lt;/a&gt; using the data they collect, e.g. &amp;#8220;does taking drug A make my condition better or worse.&amp;#8221; I&amp;#8217;m not quite there yet, but it&amp;#8217;s an interesting direction. I&amp;#8217;m not sure I have the discipline to collect sufficiently high-quality&amp;nbsp;data.&lt;/p&gt;

&lt;p&gt;For more about the Quantified Self movement I recommend checking out the &lt;a href="http://quantifiedself.com/"&gt;Quantified Self blog&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/afternoon/~4/2gDSvbqdH84" height="1" width="1"/&gt;</description><pubDate>Mon, 15 Apr 2013 10:50:25 +0300</pubDate><guid isPermaLink="false">http://aftnn.org/2013/apr/15/quantified-self/</guid><category>quantifiedself</category><feedburner:origLink>http://aftnn.org/2013/apr/15/quantified-self/</feedburner:origLink></item><item><title>Serve HTTPS From Elastic Beanstalk Application Instances
</title><link>http://feedproxy.google.com/~r/afternoon/~3/yUYhRIoeLJs/</link><description>&lt;p&gt;&lt;a href="http://aws.amazon.com/elasticbeanstalk/"&gt;Elastic Beanstalk&lt;/a&gt; is Amazon&amp;#8217;s platform-as-a-service built on top of &lt;span class="caps"&gt;EC2&lt;/span&gt;, S3 and other Amazon&amp;nbsp;services.&lt;/p&gt;

&lt;p&gt;An Elastic Beanstalk application consists of one or more &lt;span class="caps"&gt;EC2&lt;/span&gt; instances running your application and a set of supporting resources, including an &lt;a href="http://aws.amazon.com/elasticloadbalancing/"&gt;Elastic Load Balancer&lt;/a&gt;. By default, the load balancer listens on port 80 and forwards traffic to port 80 on your app servers. You can &lt;a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https.html"&gt;configure the load balancer to listen on 443 easily&lt;/a&gt;, but traffic from the &lt;span class="caps"&gt;LB&lt;/span&gt; to the app servers is not encrypted. To encrypt the traffic on this hop, you must configure your app servers to listen for &lt;span class="caps"&gt;HTTPS&lt;/span&gt;&amp;nbsp;requests.&lt;/p&gt;

&lt;h2&gt;Options For Configuring App Servers To Serve&amp;nbsp;&lt;span class="caps"&gt;HTTPS&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;This can be done one of 2 ways (examples specific to Tomcat, but the methods should be applicable to any app&amp;nbsp;server).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use Elastic Beanstalk configuration files to install packages, create Apache configuration files, certificate and key files in the relevant&amp;nbsp;locations.&lt;/li&gt;
&lt;li&gt;Create your own app server &lt;span class="caps"&gt;AMI&lt;/span&gt; with &lt;span class="caps"&gt;HTTPS&lt;/span&gt; enabled. For Tomcat, &lt;a href="https://forums.aws.amazon.com/message.jspa?messageID=235332#310452"&gt;443 forwarding to 80 (&lt;span class="caps"&gt;HTTPS&lt;/span&gt;)&amp;#8230; How can I set up &lt;span class="caps"&gt;REAL&lt;/span&gt; &lt;span class="caps"&gt;HTTPS&lt;/span&gt; on Beanstalk&lt;/a&gt; outlines the required&amp;nbsp;steps.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Method 1 seems preferable as it avoids the need to keep AMIs up-to-date, e.g. when security patches are&amp;nbsp;released.&lt;/p&gt;

&lt;h2&gt;Using Elastic Beanstalk Configuration&amp;nbsp;Files&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create an &lt;code&gt;.ebextensions&lt;/code&gt; dir at the root of your app dir or &lt;span class="caps"&gt;WAR&lt;/span&gt;&amp;nbsp;file&lt;/li&gt;
&lt;li&gt;Copy in any files you want to&amp;nbsp;create&lt;/li&gt;
&lt;li&gt;Create an Elastic Beanstalk configuration file to describing the required instance configuration&amp;nbsp;changes&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Example Configuration&amp;nbsp;File&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# vim: ft=yaml
packages:
  yum:
    mod_ssl: "" # empty string means latest
container_commands:
  10-ssl-key-cert-install:
    command: "cp -r .ebextensions/ssl /etc/httpd/"
  20-apache-ssl-config:
    command: "cp .ebextensions/ssl.conf /etc/httpd/conf.d/ssl.conf"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Custom commands are run before services are started. There&amp;#8217;s no need to restart services if you&amp;#8217;re changing their configuration (e.g. Apache in this&amp;nbsp;case).&lt;/p&gt;

&lt;p&gt;Note for Scala developers: &lt;span class="caps"&gt;SBT&lt;/span&gt; ignores hidden directories when building projects (and I can&amp;#8217;t work out how to override that). You can use &lt;code&gt;jar uf /path/to/file.war .ebextensions&lt;/code&gt; to insert the &lt;code&gt;.ebextensions&lt;/code&gt; dir into the &lt;span class="caps"&gt;WAR&lt;/span&gt; file after&amp;nbsp;packaging.&lt;/p&gt;

&lt;h3&gt;References&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.infoq.com/news/2012/11/elastic-beanstalk-config-files"&gt;Customize &lt;span class="caps"&gt;AWS&lt;/span&gt; Elastic Beanstalk with Configuration Files&lt;/a&gt; is a good starting point for Elastic Beanstalk configuration&amp;nbsp;files.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html#customize-containers-format-container_commands"&gt;Customizing the Software on &lt;span class="caps"&gt;EC2&lt;/span&gt; Instances&lt;/a&gt; describes the use of Elastic Beanstalk configuration files in&amp;nbsp;detail.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Login With &lt;span class="caps"&gt;SSH&lt;/span&gt; To Verify&amp;nbsp;Changes&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://stackoverflow.com/a/4921866/26201"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt; to one of your Elastic Beanstalk instances&lt;/a&gt; to ensure that the changes have been applied&amp;nbsp;correctly.&lt;/p&gt;

&lt;h3&gt;Initialisation&amp;nbsp;Logging&lt;/h3&gt;

&lt;p&gt;The Elastic Beanstalk startup process writes any errors raised by custom container commands to &lt;code&gt;/var/log/cfn-init.log&lt;/code&gt;. If your instance doesn&amp;#8217;t start properly, for example services don&amp;#8217;t start, look&amp;nbsp;there.&lt;/p&gt;

&lt;h3&gt;Backend&amp;nbsp;Authentication&lt;/h3&gt;

&lt;p&gt;Backend authentication is a feature of Elastic Load Balancer. It uses the public key of a certificate to verify that the backend app server is encrypting traffic with a valid certificate. This needs to be enabled for &lt;span class="caps"&gt;LB&lt;/span&gt; to app server &lt;span class="caps"&gt;HTTPS&lt;/span&gt; to work (otherwise you&amp;#8217;ll get timeouts when making requests to the &lt;span class="caps"&gt;LB&lt;/span&gt; on port&amp;nbsp;443).&lt;/p&gt;

&lt;h2&gt;Security Group And Load Balancer Config&amp;nbsp;File&lt;/h2&gt;

&lt;p&gt;A new load balancer and security group are created each time you deploy your application. Their configuration will revert back to the default, listen on port 80 only, whenever an environment is started. To avoid this, creating a second Elastic Beanstalk configuration file describing the required resource properties.&amp;nbsp;E.g.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# vim: ft=yaml
# Elastic Load Balancer and Security Group configuration for the app
#
# &amp;mdash; Allow anyone to connect to port 443 and office traffic to connect to
#   port 22
# &amp;mdash; Ensure all traffic is encrypted by configuring load balancer to listen on
#   443 and direct traffic to port 443 on app servers
# &amp;mdash; Enable cookie-based session stickiness
# &amp;mdash; Use /status for health check
# &amp;mdash; Enable backend authentication policy by providing public key for cert

Resources:
  AWSEBSecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      GroupDescription: "Security group to allow HTTPS for all, SSH for office"
      SecurityGroupIngress:
        &amp;mdash; {CidrIp: "0.0.0.0/0", IpProtocol: "tcp", FromPort: "443", ToPort: "443"}
        &amp;mdash; {CidrIp: "176.35.225.76/32", IpProtocol: "tcp", FromPort: "22", ToPort: "22"}
  AWSEBLoadBalancer:
    Type: "AWS::ElasticLoadBalancing::LoadBalancer"
    Properties:
      Listeners:
        &amp;mdash; {LoadBalancerPort: 443, InstancePort: 443, Protocol: "HTTPS", SSLCertificateId: "arn:aws:iam::1234567890:server-certificate/server"}
      AppCookieStickinessPolicy:
        &amp;mdash; {PolicyName: "lb-session", CookieName: "lb-session"}
      HealthCheck:
        HealthyThreshold: "3"
        Interval: "30"
        Target: "HTTPS:443/status"
        Timeout: "5"
        UnhealthyThreshold: "5"
      Policies:
        &amp;mdash;
          PolicyName: "MyPubKey"
          PolicyType: "PublicKeyPolicyType"
          Attributes:
            &amp;mdash;
              Name: "PublicKey"
              Value: "..."
        &amp;mdash;
          PolicyName: "BackendAuth"
          PolicyType: "BackendServerAuthenticationPolicyType"
          Attributes:
            &amp;mdash;
              Name: "PublicKeyPolicyName"
              Value: "MyPubKey"
          InstancePorts:
            &amp;mdash; "443"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You&amp;#8217;ll need to change this to point to your certificate in &lt;span class="caps"&gt;IAM&lt;/span&gt;, to restrict &lt;span class="caps"&gt;SSH&lt;/span&gt; access to the right &lt;span class="caps"&gt;IP&lt;/span&gt; range and to add your public&amp;nbsp;key.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environment-resources.html"&gt;Customizing Environment Resources&lt;/a&gt; describes how to write configuration files for the other &lt;span class="caps"&gt;AWS&lt;/span&gt; resources in an Elastic Beanstalk&amp;nbsp;environment.&lt;/p&gt;

&lt;p&gt;How to write policies to manage backend authentication is described in the examples in &lt;a href="http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-elb-policy.html"&gt;ElasticLoadBalancing Policy Type&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/afternoon/~4/yUYhRIoeLJs" height="1" width="1"/&gt;</description><pubDate>Fri, 05 Apr 2013 15:15:06 +0300</pubDate><guid isPermaLink="false">http://aftnn.org/2013/apr/05/serve-https-elastic-beanstalk-application-instances/</guid><category>aws</category><category>elasticbeanstalk</category><category>elb</category><category>https</category><feedburner:origLink>http://aftnn.org/2013/apr/05/serve-https-elastic-beanstalk-application-instances/</feedburner:origLink></item><item><title>Mock To Mobile In Minutes With Codiqa, Trigger.io And TestFlight
</title><link>http://feedproxy.google.com/~r/afternoon/~3/U20O6yIO0EI/</link><description>&lt;p&gt;I&amp;#8217;m a fan of &lt;span class="caps"&gt;HTML&lt;/span&gt; for building mobile apps. Its incredibly quick and easy to build simple apps. I already know &lt;span class="caps"&gt;HTML&lt;/span&gt;, &lt;span class="caps"&gt;CSS&lt;/span&gt; and JavaScript. Lots of other developers do too, so it&amp;#8217;s easier to find people to work with than native&amp;nbsp;platforms.&lt;/p&gt;

&lt;p&gt;When I recently started working on a mobile project, I used &lt;a href="http://codiqa.com/"&gt;Codiqa&lt;/a&gt; to build a mockup of the app interface and generate &lt;span class="caps"&gt;HTML&lt;/span&gt; and &lt;a href="http://trigger.io"&gt;Trigger.io&lt;/a&gt; and &lt;a href="https://testflightapp.com/"&gt;TestFlight&lt;/a&gt; to turn that mock into an app running on my&amp;nbsp;iPhone.&lt;/p&gt;

&lt;h2&gt;Get Creative With Your&amp;nbsp;Mock&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://codiqa.com/"&gt;Codiqa&lt;/a&gt; makes it easy to create app&amp;nbsp;mocks.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign up for &lt;a href="https://codiqa.com/signup/plans/2013basic-monthly"&gt;Codiqa basic account&lt;/a&gt; so you can build more than 3 pages and export your mock as&amp;nbsp;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Build an awesome mock by dragging and&amp;nbsp;dropping&lt;/li&gt;
&lt;li&gt;Optional: customise your app by creating a theme with &lt;a href="http://jquerymobile.com/themeroller/index.php"&gt;jQuery Mobile Themeroller&lt;/a&gt; and &lt;a href="https://codiqa.com/dash/themes"&gt;uploading it to&amp;nbsp;Codiqa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Download your mock as &lt;span class="caps"&gt;HTML&lt;/span&gt; and&amp;nbsp;unzip&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;From Mock To Mobile In&amp;nbsp;Minutes&lt;/h2&gt;

&lt;p&gt;Next, I used &lt;a href="http://trigger.io"&gt;Trigger.io&lt;/a&gt; to create an app from the mock &lt;span class="caps"&gt;HTML&lt;/span&gt; and &lt;a href="https://testflightapp.com/"&gt;TestFlight&lt;/a&gt; to release it to my&amp;nbsp;phone.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;a href="https://trigger.io/forge/toolkit/"&gt;Trigger.io&amp;#8217;s&amp;nbsp;tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Create a directory for your new&amp;nbsp;app&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;forge create&lt;/code&gt; (See &lt;a href=""&gt;Trigger.io&amp;#8217;s &lt;span class="caps"&gt;OS&lt;/span&gt;-specific instructions&lt;/a&gt; for more&amp;nbsp;detail)&lt;/li&gt;
&lt;li&gt;Replace the contents of the &lt;code&gt;src&lt;/code&gt; dir Download &lt;span class="caps"&gt;HTML&lt;/span&gt; from Codiqa to the &lt;code&gt;src&lt;/code&gt; dir of your new&amp;nbsp;app&lt;/li&gt;
&lt;li&gt;Rename &lt;code&gt;app.html&lt;/code&gt; to &lt;code&gt;index.html&lt;/code&gt; so that Trigger knows it&amp;#8217;s your start&amp;nbsp;page&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.trigger.io/en/v1.4/best_practice/release_mobile.html#ios"&gt;Change your app&amp;#8217;s config to include your package name and point to your provisioning profile&lt;/a&gt; (there&amp;#8217;s an &lt;a href="https://gist.github.com/afternoon/5254489#file-local_config-json"&gt;example &lt;code&gt;local_config.json&lt;/code&gt; here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;forge build ios&lt;/code&gt; to compile the&amp;nbsp;app&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;forge package ios&lt;/code&gt; to generate an &lt;span class="caps"&gt;IPA&lt;/span&gt; package file for&amp;nbsp;iPhones&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Distribute Your Mock&amp;nbsp;App&lt;/h2&gt;

&lt;p&gt;Once you&amp;#8217;ve followed these steps, you can upload your build to TestFlight and push it out to your&amp;nbsp;testers. &lt;/p&gt;

&lt;p&gt;To deploy apps to iPhones, you will need an Apple developer account and a provisioning profile.
TestFlight have a good resource on &lt;a href="http://help.testflightapp.com/customer/portal/articles/829857-how-do-i-prepare-a-build-for-distribution-through-testflight-"&gt;preparing a build for distribution through TestFlight&lt;/a&gt;. Also, Handshake have a good overview of &lt;a href="http://www.handshake20.com/2011/07/testing-ios-apps-with-testflight.html"&gt;Testing iOS Apps with TestFlight&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Apple&amp;#8217;s document &lt;a href="https://developer.apple.com/library/ios/#documentation/ToolsLanguages/Conceptual/DevPortalGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011159"&gt;About iOS Development Team Administration&lt;/a&gt; provides a wealth of info on the iOS development&amp;nbsp;workflow.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/afternoon/~4/U20O6yIO0EI" height="1" width="1"/&gt;</description><pubDate>Wed, 27 Mar 2013 13:06:26 +0300</pubDate><guid isPermaLink="false">http://aftnn.org/2013/mar/27/mocking-mobile-apps-codiqa-and-triggerio/</guid><category>codiqa</category><category>html</category><category>mobile</category><category>trigger.io</category><feedburner:origLink>http://aftnn.org/2013/mar/27/mocking-mobile-apps-codiqa-and-triggerio/</feedburner:origLink></item><item><title>If you had an API for your email, what would you do with it?
</title><link>http://feedproxy.google.com/~r/afternoon/~3/p9mUOkx7EG8/</link><description>&lt;p&gt;If you could analyse all your email, or all your organisation&amp;#8217;s email, in any way, what would you do with it? Leave a comment with your&amp;nbsp;answers.&lt;/p&gt;

&lt;h2&gt;Email Analytics For&amp;nbsp;You&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Build a stats dashboard with total number of emails sent, sent per day, top recipients, etc, and start a competition to see who sends the most (or&amp;nbsp;least!)&lt;/li&gt;
&lt;li&gt;Calculate what time you&amp;#8217;re most likely to get a response from a particular&amp;nbsp;person&lt;/li&gt;
&lt;li&gt;Extract all the links you&amp;#8217;ve sent and make a Twitter&amp;nbsp;feed&lt;/li&gt;
&lt;li&gt;Extract all the links you&amp;#8217;ve sent or received to a particular person and show them in a sidebar when composing (a bit like &lt;a href="http://rapportive.com/"&gt;Rapportive&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Build a cool visualisation of your email social network, like &lt;a href="http://inmaps.linkedinlabs.com/"&gt;InMaps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Email Analytics For Your&amp;nbsp;Organisation&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Trending&amp;nbsp;topics&lt;/li&gt;
&lt;li&gt;Integrate with a &lt;span class="caps"&gt;CRM&lt;/span&gt;, e.g. automatically populate contacts,&amp;nbsp;history&lt;/li&gt;
&lt;li&gt;Pull attachments and share them on Dropbox/GDocs/file server/etc (similar to &lt;a href="http://attachments.me"&gt;attachments.me&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Extract stealth documentation (questions and answers) and add it to a&amp;nbsp;wiki&lt;/li&gt;
&lt;li&gt;Archive conversations applying custom rules (filter out mailing lists, large&amp;nbsp;attachments)&lt;/li&gt;
&lt;li&gt;Detect specific content, e.g. porn, law-breaking,&amp;nbsp;bullying&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Email Analytics For The&amp;nbsp;World&lt;/h2&gt;

&lt;p&gt;By analysing the all the email in the world (or a sufficiently large volume thereof), you could apply the kind of social analytics that Twitter, Facebook, Bitly, PeerIndex, etc,&amp;nbsp;provide.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trending&amp;nbsp;topics&lt;/li&gt;
&lt;li&gt;Influence (&amp;#8220;Ben knows about&amp;nbsp;startups&amp;#8221;)&lt;/li&gt;
&lt;li&gt;Contact&amp;nbsp;segmentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The list goes on. What would you&amp;nbsp;do?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/afternoon/~4/p9mUOkx7EG8" height="1" width="1"/&gt;</description><pubDate>Mon, 19 Nov 2012 09:00:49 +0300</pubDate><guid isPermaLink="false">http://aftnn.org/2012/nov/19/if-you-had-api-your-email-what-would-you-do-it/</guid><category>analytics</category><category>email</category><feedburner:origLink>http://aftnn.org/2012/nov/19/if-you-had-api-your-email-what-would-you-do-it/</feedburner:origLink></item><item><title>Lean Startup Resources
</title><link>http://feedproxy.google.com/~r/afternoon/~3/9FASb0ld0FA/</link><description>&lt;p&gt;My own list of resources for people applying the Lean Startup&amp;nbsp;Methology.&lt;/p&gt;

&lt;h2&gt;Aphorisms&lt;/h2&gt;

&lt;p&gt;Print them on&amp;nbsp;posters.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Life&amp;#8217;s too short to build something nobody wants – Eric&amp;nbsp;Ries&lt;/li&gt;
&lt;li&gt;Remove any feature, process or effort that does not contribute directly to the learning you seek – Eric&amp;nbsp;Ries&lt;/li&gt;
&lt;li&gt;Innovation accounting: Baseline with an &lt;span class="caps"&gt;MVP&lt;/span&gt;; Tune; Pivot or Persevere – Eric&amp;nbsp;Ries&lt;/li&gt;
&lt;li&gt;A good design is one that changes customer behaviour for the better – Eric&amp;nbsp;Ries&lt;/li&gt;
&lt;li&gt;Real learning comes from facts and commitment, not opinions and promises – Eric&amp;nbsp;Ries&lt;/li&gt;
&lt;li&gt;3 A&amp;#8217;s of metrics: actionable, accessible, auditable – Eric&amp;nbsp;Ries&lt;/li&gt;
&lt;li&gt;If you launch it and see what happens, you&amp;#8217;ll succeed – at seeing what happens – Eric&amp;nbsp;Ries&lt;/li&gt;
&lt;li&gt;Launch when you can deliver a quantum of value – Eric&amp;nbsp;Ries&lt;/li&gt;
&lt;li&gt;Given the right context, customers can clearly articulate their problems, but it&amp;#8217;s your job to come up with the solution – Ash&amp;nbsp;Maurya&lt;/li&gt;
&lt;li&gt;It&amp;#8217;s not the customer&amp;#8217;s job to know what they want – Steve&amp;nbsp;Jobs&lt;/li&gt;
&lt;li&gt;Get out of the building – Steve&amp;nbsp;Blank&lt;/li&gt;
&lt;li&gt;Startups that succeed are those that manage to iterate enough times before running out of resources – Eric&amp;nbsp;Ries&lt;/li&gt;
&lt;li&gt;Practice trumps theory – Ash&amp;nbsp;Maurya&lt;/li&gt;
&lt;li&gt;Customers don&amp;#8217;t care about your solution, they care about their problems – Dave&amp;nbsp;McClure&lt;/li&gt;
&lt;li&gt;While ideas are cheap, acting on them is quite expensive – Ash&amp;nbsp;Maurya&lt;/li&gt;
&lt;li&gt;Bind a solution to your problem as late as possible – Ash&amp;nbsp;Maurya&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Types Of&amp;nbsp;&lt;span class="caps"&gt;MVP&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;In ascending order of&amp;nbsp;complexity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Observation&lt;/li&gt;
&lt;li&gt;Re-enactment&lt;/li&gt;
&lt;li&gt;Interview&lt;/li&gt;
&lt;li&gt;Pitch a fake product (email, call,&amp;nbsp;face-to-face)&lt;/li&gt;
&lt;li&gt;Video like&amp;nbsp;Dropbox&lt;/li&gt;
&lt;li&gt;Mail campaign/&lt;span class="caps"&gt;PPC&lt;/span&gt;/landing page with &lt;span class="caps"&gt;AB&lt;/span&gt;/multivariate&amp;nbsp;testing&lt;/li&gt;
&lt;li&gt;Concierge &amp;mdash; talk to the customer, simulate the&amp;nbsp;service&lt;/li&gt;
&lt;li&gt;Wizard of Oz &amp;mdash; perform back-office tasks&amp;nbsp;manually&lt;/li&gt;
&lt;li&gt;Partly-implemented application, e.g. application form that declines&amp;nbsp;everyone&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Books&lt;/h2&gt;

&lt;h3&gt;Essentials&lt;/h3&gt;

&lt;p&gt;Don&amp;#8217;t skip&amp;nbsp;these!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://theleanstartup.com/"&gt;The Lean Startup&lt;/a&gt; – Eric&amp;nbsp;Ries&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.runningleanhq.com/"&gt;Running Lean&lt;/a&gt; – Ash&amp;nbsp;Maurya&lt;/li&gt;
&lt;li&gt;&lt;a href="http://custdev.com/"&gt;The Entrepreneur&amp;#8217;s Guide To Customer Development&lt;/a&gt; – Brant Cooper and Patrick&amp;nbsp;Vlaskovits&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Very, Very&amp;nbsp;Useful&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.businessmodelgeneration.com/book"&gt;Business Model Generation&lt;/a&gt; – Alex Osterwalder and Yves&amp;nbsp;Pigneur&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.co.uk/Four-Steps-Epiphany-Steven-Blank/dp/0976470705"&gt;4 Steps To The Epiphany&lt;/a&gt; – Steve&amp;nbsp;Blank&lt;/li&gt;
&lt;li&gt;&lt;a href="http://neildavidson.com/download/dont-just-roll-the-dice/"&gt;Don&amp;#8217;t Just Roll The Dice&lt;/a&gt; – Neil&amp;nbsp;Davidson&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.co.uk/Positioning-Battle-Your-Al-Ries/dp/0071373586"&gt;Positioning: The Battle For Your Mind&lt;/a&gt; – Al Ries, Jack&amp;nbsp;Trout&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Tools&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Business Modelling&lt;/em&gt;: &lt;a href="http://leancanvas.com/"&gt;Lean Canvas&lt;/a&gt;, &lt;a href="http://leanstartupmachine.com/validationboard/"&gt;Validation&amp;nbsp;Board&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Source Control&lt;/em&gt;: &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Hosting&lt;/em&gt;: Heroku, S3,&amp;nbsp;GitHub&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;span class="caps"&gt;CI&lt;/span&gt;&lt;/em&gt;: Circle &lt;span class="caps"&gt;CI&lt;/span&gt;, Cloud Bees Hosted&amp;nbsp;Jenkins&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Analytics&lt;/em&gt;: KISSmetrics, Mixpanel, Google Analytics,&amp;nbsp;StatsMix&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Split Testing&lt;/em&gt;: KISSmetrics, Google Website Optimizer, Visual Website&amp;nbsp;Optimizer&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;span class="caps"&gt;CRM&lt;/span&gt;&lt;/em&gt;: Intercom,&amp;nbsp;Salesforce&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Email Marketing&lt;/em&gt;:&amp;nbsp;MailChimp&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Surveys&lt;/em&gt;: SurveyGizmo, AskYourTargetMarket,&amp;nbsp;SurveyMonkey&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Offers&lt;/em&gt;: &lt;a href="http://hackersandfounders.rewardli.com/"&gt;Hackers And Founders&amp;nbsp;Rewardli&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Resources&lt;/h2&gt;

&lt;h3&gt;Lean Startup&amp;nbsp;Methodology&lt;/h3&gt;

&lt;p&gt;&lt;iframe src="http://www.slideshare.net/slideshow/embed_code/13585758" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen&gt; &lt;/iframe&gt; &lt;div style="margin-bottom:5px"&gt; &lt;strong&gt; &lt;a href="http://www.slideshare.net/LeanStartupMachine/lean-101-13585758" title="Lean 101" target="_blank"&gt;Lean 101&lt;/a&gt; &lt;/strong&gt; from &lt;strong&gt;&lt;a href="http://www.slideshare.net/LeanStartupMachine" target="_blank"&gt;Lean Startup Machine&lt;/a&gt;&lt;/strong&gt; &lt;/div&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe src="http://www.slideshare.net/slideshow/embed_code/3018080?rel=0" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen&gt; &lt;/iframe&gt; &lt;div style="margin-bottom:5px"&gt; &lt;strong&gt; &lt;a href="http://www.slideshare.net/startuplessonslearned/2010-01-27-the-lean-startup-twiistup" title="2010 01 27 The Lean Startup Twiistup" target="_blank"&gt;2010 01 27 The Lean Startup Twiistup&lt;/a&gt; &lt;/strong&gt; from &lt;strong&gt;&lt;a href="http://www.slideshare.net/startuplessonslearned" target="_blank"&gt;Eric Ries&lt;/a&gt;&lt;/strong&gt; &lt;/div&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe src="http://www.slideshare.net/slideshow/embed_code/7962824" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen&gt; &lt;/iframe&gt; &lt;div style="margin-bottom:5px"&gt; &lt;strong&gt; &lt;a href="http://www.slideshare.net/lfittl/lean-startup-essentials" title="Lean Startup Essentials &amp;mdash; STARTup Live Hagenberg" target="_blank"&gt;Lean Startup Essentials &amp;mdash; STARTup Live Hagenberg&lt;/a&gt; &lt;/strong&gt; from &lt;strong&gt;&lt;a href="http://www.slideshare.net/lfittl" target="_blank"&gt;Lukas Fittl&lt;/a&gt;&lt;/strong&gt; &lt;/div&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe src="http://www.slideshare.net/slideshow/embed_code/11144479" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen&gt; &lt;/iframe&gt; &lt;div style="margin-bottom:5px"&gt; &lt;strong&gt; &lt;a href="http://www.slideshare.net/giffc/mvpexperiments-talk-at-sva-ixd-program" title="MVP/Experiments talk at SVA IxD program" target="_blank"&gt;&lt;span class="caps"&gt;MVP&lt;/span&gt;/Experiments talk at &lt;span class="caps"&gt;SVA&lt;/span&gt; IxD program&lt;/a&gt; &lt;/strong&gt; from &lt;strong&gt;&lt;a href="http://www.slideshare.net/giffc" target="_blank"&gt;Giff Constable&lt;/a&gt;&lt;/strong&gt; &lt;/div&gt;&lt;/p&gt;

&lt;p&gt;The Lean Startup Circle&amp;nbsp;Wiki&lt;/p&gt;

&lt;h3&gt;Metrics&lt;/h3&gt;

&lt;p&gt;&lt;iframe src="http://www.slideshare.net/slideshow/embed_code/2992302?rel=0" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen&gt; &lt;/iframe&gt; &lt;div style="margin-bottom:5px"&gt; &lt;strong&gt; &lt;a href="http://www.slideshare.net/dmc500hats/startup-metrics-for-pirates-sf-jan-2010" title="Startup Metrics for Pirates (SF, Jan 2010)" target="_blank"&gt;Startup Metrics for Pirates (&lt;span class="caps"&gt;SF&lt;/span&gt;, Jan 2010)&lt;/a&gt; &lt;/strong&gt; from &lt;strong&gt;&lt;a href="http://www.slideshare.net/dmc500hats" target="_blank"&gt;Dave McClure&lt;/a&gt;&lt;/strong&gt; &lt;/div&gt;&lt;/p&gt;

&lt;h3&gt;Understanding&amp;nbsp;Opportunities/Ideation&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blog.diotalevi.com.s3.amazonaws.com/leancanvas.pdf"&gt;Lean Canvas Poster&amp;nbsp;&lt;span class="caps"&gt;PDF&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.imediaconnection.com/content/presentations/06adtechsf/SF06_TaddyHall_WorkshopMarketingMalpractice.pdf"&gt;Marketing Malpractice: The Cause and the Cure&lt;/a&gt;
Summary of a lot of Clayton Christensen&amp;#8217;s ideas on product management, e.g. &lt;code&gt;I hire product _________ to do the job of __________&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Customer&amp;nbsp;Development&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[Customer Development &lt;span class="caps"&gt;FAQ&lt;/span&gt;] (http://www.cindyalvarez.com/learning/faq-customer-development-for-product-managers) by Cindy Alvarez at&amp;nbsp;Yammer&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.leanstartupmachine.com/2012/10/how-to-get-out-of-the-building-with-the-validation-board"&gt;How To Get Out Of The Building&lt;/a&gt; by Trevor Owens at Lean Startup&amp;nbsp;Machine&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dex.io/robfitz/how-to-screw-up-custdev/"&gt;How To Screw Up Customer Development&lt;/a&gt; by Rob Fitzpatrick (lean startup&amp;nbsp;expert)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://giffconstable.com/2011/07/12-tips-for-customer-development-interviews-revised/"&gt;12 Tips for Customer Development&amp;nbsp;Interviews&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.saintsal.com/2012/09/softball-anchor-and-deflection-questions/"&gt;Essential Customer Development skills – Softball, Anchor and Deflection&amp;nbsp;questions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/afternoon/~4/9FASb0ld0FA" height="1" width="1"/&gt;</description><pubDate>Wed, 17 Oct 2012 10:17:50 +0300</pubDate><guid isPermaLink="false">http://aftnn.org/2012/oct/17/lean-startup-resources/</guid><feedburner:origLink>http://aftnn.org/2012/oct/17/lean-startup-resources/</feedburner:origLink></item><item><title>Small Data: Processing CSV In Unix
</title><link>http://feedproxy.google.com/~r/afternoon/~3/DiSxuHbJa_8/</link><description>&lt;p&gt;Unix provides a wealth of great tools for performing simple analysis of small datasets. &lt;code&gt;awk&lt;/code&gt; in particular is useful for crunching &lt;span class="caps"&gt;CSV&lt;/span&gt;&amp;nbsp;files.&lt;/p&gt;

&lt;p&gt;Why use Unix tools and not Excel? The commands you create can be saved as a script and applied to updated files, multiple files at once, combined with curl to process a file from the&amp;nbsp;web.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a few examples using a fictional data file, &lt;code&gt;emails.csv&lt;/code&gt;, which contains data about a number of email campaigns sent to&amp;nbsp;customers.&lt;/p&gt;

&lt;h2&gt;Get&amp;nbsp;Started&lt;/h2&gt;

&lt;p&gt;First, let&amp;#8217;s inspect the file format by printing the first few&amp;nbsp;rows.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ head -5 emails.csv
ReportRunOn,MemberID,StartDate,EndDate
10/10/2012 13:13:10,1038277,10/09/2012 00:00:00,10/10/2012 23:59:59

UserName,UserID,JobID,EmailName,EmailSubject,PickupTime,BCC,CcEmail,NormalSends,NormalSendsBCC,NormalSendsCC,TriggeredSends,TriggeredSendsBCC,TriggeredSendsCC,NormalSends_1,NormalSendsBCC_1,NormalSendsCC_1,TriggeredSends_1,TriggeredSendsBCC_1,TriggeredSendsCC_1
Ben Godfrey,ben.godfrey,1839429,Example Email,Give us your feedback!,05/10/2012 15:22:55,,,1,0,0,0,0,0,470,0,0,0,0,0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This file has a metadata section at the top. Let&amp;#8217;s chop that&amp;nbsp;off.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ tail +4 emails.csv &amp;gt; emails-no-meta.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Introducing &lt;code&gt;awk&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;The file has a lot of columns. We can use &lt;code&gt;awk&lt;/code&gt; to extract only the columns
we&amp;#8217;re interested&amp;nbsp;in.&lt;/p&gt;

&lt;p&gt;As an intermediate result, let&amp;#8217;s just print out the first&amp;nbsp;column.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ awk -F, '{ print $1 }' emails-no-meta.csv | head
UserName
Ben Godfrey
Ben Godfrey
Ben Godfrey
Ben Godfrey
Ben Godfrey
Other User
Other User
Other User
Other User
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;awk&lt;/code&gt;&amp;#8216;s &lt;code&gt;-F&lt;/code&gt; argument sets the field separator. We&amp;#8217;re using the comma character.
Use &lt;code&gt;-F\\t&lt;/code&gt; for tabs. The default separator is the space&amp;nbsp;character.&lt;/p&gt;

&lt;p&gt;We provide a program to &lt;code&gt;awk&lt;/code&gt; on the command line. &lt;code&gt;awk&lt;/code&gt; programs operate on
each line, with &lt;code&gt;BEGIN&lt;/code&gt; and &lt;code&gt;END&lt;/code&gt; sections to do pre- and post-processing on the
whole&amp;nbsp;file.&lt;/p&gt;

&lt;p&gt;This simple program contains a block which is applied to all lines and prints
&lt;code&gt;$1&lt;/code&gt;, which is &lt;code&gt;awk&lt;/code&gt;&amp;#8216;s syntax for column&amp;nbsp;1.&lt;/p&gt;

&lt;p&gt;We can go a step futher and add a pattern match to our program so we print the
first column of lines matching &amp;#8220;Ben&amp;nbsp;Godfrey.&amp;#8221;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ awk -F, '/Ben Godfrey/ { print $1 }' emails-no-meta.csv
Ben Godfrey
Ben Godfrey
Ben Godfrey
Ben Godfrey
Ben Godfrey
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is functionally equivalent to using &lt;code&gt;grep&lt;/code&gt; and piping the result to &lt;code&gt;awk&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ grep "Ben Godfrey" emails-no-meta.csv | awk -F, '{ print $1 }'
Ben Godfrey
Ben Godfrey
Ben Godfrey
Ben Godfrey
Ben Godfrey
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;awk&lt;/code&gt;-only solution involves less overhead &amp;mdash; only one pass through the file
and only program is used &amp;mdash; but &lt;code&gt;grep&lt;/code&gt; is such a powerful tool and familiar to so
many that it is often used for the filtering part of a pipeline. Combining
simple tools to create powerful results is a key part of the Unix&amp;nbsp;philosophy.&lt;/p&gt;

&lt;h2&gt;More&amp;nbsp;Columns&lt;/h2&gt;

&lt;p&gt;We can also use &lt;code&gt;awk&lt;/code&gt; to construct a new &lt;span class="caps"&gt;CSV&lt;/span&gt; file with a subset of&amp;nbsp;columns.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ awk -F, '/Ben Godfrey/ { print $1","$4","$6","$9 }' emails-no-meta.csv
Ben Godfrey,Example Email,05/10/2012 15:22:55,1
Ben Godfrey,Example Email,05/10/2012 17:06:59,1
Ben Godfrey,Example Email,08/10/2012 10:36:45,2
Ben Godfrey,Example Email,08/10/2012 11:32:56,469
Ben Godfrey,Example Email,10/10/2012 12:02:53,4232
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a powerful technique, because we can easily rerun that command on an
updated file. This beats performing the same manual steps in Excel for every new
file. We can also run the &lt;code&gt;awk&lt;/code&gt; program again many files (potentially sourced
from different locations with &lt;code&gt;find&lt;/code&gt; or &lt;code&gt;curl&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;As a final trick, let&amp;#8217;s total up how many emails I&amp;#8217;ve&amp;nbsp;sent.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ awk -F, '/Ben Godfrey/ { total = total + $9 } END { print total }' emails-no-meta.csv
4705
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We add the values from column 9 to the &lt;code&gt;total&lt;/code&gt; variable as we proceed through
the file (as long as the line matches the expression &lt;code&gt;/Ben Godfrey/&lt;/code&gt;). Finally,
we use an &lt;code&gt;END&lt;/code&gt; block to print the value of &lt;code&gt;total&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Vim&lt;/h2&gt;

&lt;p&gt;Most Unix tools, including &lt;code&gt;awk&lt;/code&gt;, can operate on either a file or &lt;code&gt;stdin&lt;/code&gt; and
&lt;code&gt;stdout&lt;/code&gt;. Within Vim, you can filter the contents using an external&amp;nbsp;program.&lt;/p&gt;

&lt;p&gt;If we open &lt;code&gt;emails.csv&lt;/code&gt; in Vim, we can issue the following command to reduce the
list of columns in the current buffer without modifying the original&amp;nbsp;file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:%! awk -F, '{ print $1","$4","$6","$9 }'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;%!&lt;/code&gt; is a Vim command to filter the whole file through an external command. You
can also filter a specified range. We could filter every line except the&amp;nbsp;header.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:2,$! awk -F, '{ print $1","$4","$6","$9 }'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also, you can select some lines in visual mode then filter&amp;nbsp;those.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:'&amp;lt;,'&amp;gt;! awk -F, '{ print $1","$4","$6","$9 }'
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/afternoon/~4/DiSxuHbJa_8" height="1" width="1"/&gt;</description><pubDate>Wed, 10 Oct 2012 17:14:59 +0300</pubDate><guid isPermaLink="false">http://aftnn.org/2012/oct/10/small-data-processing-csv-unix/</guid><category>awk</category><category>unix</category><feedburner:origLink>http://aftnn.org/2012/oct/10/small-data-processing-csv-unix/</feedburner:origLink></item><item><title>Personal Finance Dashboards For UK Customers
</title><link>http://feedproxy.google.com/~r/afternoon/~3/DcOz8vBZyjg/</link><description>&lt;p&gt;The current crop of Personal Finance Management (&lt;span class="caps"&gt;PFM&lt;/span&gt;) tools collect data from your bank accounts and cards and try to make sense of it all. Generally they do a bad job of this. Getting the data in is time-consuming and error-prone. The analyses are unhelpful. You get pretty graphs that tell you&amp;nbsp;nothing.&lt;/p&gt;

&lt;p&gt;The serious options for &lt;span class="caps"&gt;UK&lt;/span&gt; customers right now are &lt;a href="http://lovemoney.com"&gt;LoveMoney&lt;/a&gt; and &lt;a href="http://www.moneydashboard.com/"&gt;Money Dashboard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Both tools are very similar. They pull data from your bank account using Yodlee&amp;#8217;s &lt;span class="caps"&gt;API&lt;/span&gt;. They display transactions and analysis of your&amp;nbsp;spending.&lt;/p&gt;

&lt;h2&gt;Transactions&lt;/h2&gt;

&lt;p&gt;Transactions are categorised. This is done automatically where possible. That identification process varies in it&amp;#8217;s accuracy. Correct categorisation is vital for the analysis to be accurate. LoveMoney showed my monthly spending on health insurance as unexpectedly high, they had categorised my mortgage payment as health insurance&amp;nbsp;payments.&lt;/p&gt;

&lt;p&gt;Money Dashboard has a huge list of categories. LoveMoney has a small, more manageable list. The categories they present are too specific, e.g. gym instead of fitness. Money Dashboard&amp;#8217;s list satisfies my desire to be accurate, but took a bit longer to find my way&amp;nbsp;around.&lt;/p&gt;

&lt;p&gt;None of the dashboards I&amp;#8217;ve tried can understand money moving between accounts. They all show both sides of the transaction&amp;nbsp;separately.&lt;/p&gt;

&lt;h2&gt;Confusing interfaces, poor&amp;nbsp;performance&lt;/h2&gt;

&lt;p&gt;LoveMoney&amp;#8217;s interface is more generally friendly. It&amp;#8217;s easier to find your way around and understand the data. A tiny example: transactions are marked with the icon of the account they came from. It&amp;#8217;s easier to understand than Money Dashboard&amp;#8217;s more abstract colour&amp;nbsp;coding.&lt;/p&gt;

&lt;p&gt;Both tools are really slow. This is possibly because they&amp;#8217;re pulling data from Yodlee&amp;#8217;s &lt;span class="caps"&gt;API&lt;/span&gt; for every request. The slowness increases the friction of adding accounts and categorising&amp;nbsp;events.&lt;/p&gt;

&lt;p&gt;Yodlee&amp;#8217;s system for capturing credentials doesn&amp;#8217;t provide enough validation feedback. For example, I had to make a few guesses on what format sort code should be in for one account (it&amp;#8217;s 2012, validation should be&amp;nbsp;solved).&lt;/p&gt;

&lt;h2&gt;Analysis&lt;/h2&gt;

&lt;p&gt;LoveMoney breaks down spending into categories and shows both this month&amp;#8217;s spending and the monthly average for each category. This is quite a helpful&amp;nbsp;tool.&lt;/p&gt;

&lt;p&gt;Money Dashboard displays categories as a pie chart, money in and out and balance trends. I like the latter because it gives me an indication of how my savings are&amp;nbsp;going.&lt;/p&gt;

&lt;h2&gt;Budgeting&lt;/h2&gt;

&lt;p&gt;Money Dashboard allows you to set goals, e.g. saving for a rainy day. The data driving these need to be updated manually. They also have a budgeting tool which tries to predict monthly spending cash. My numbers were&amp;nbsp;incomprehensible.&lt;/p&gt;

&lt;p&gt;LoveMoney suffers from the same problem. Their analysis of the month so far was that I&amp;#8217;m in a huge deficit, when all I had done is make a large transfer to my savings account. I had added the savings account so this was&amp;nbsp;disappointing.&lt;/p&gt;

&lt;h2&gt;My User&amp;nbsp;Stories&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;m frustrated with &lt;span class="caps"&gt;PFM&lt;/span&gt; tools. I like the idea, but the implementations don&amp;#8217;t answer my financial&amp;nbsp;questions.&lt;/p&gt;

&lt;h3&gt;How am I doing on my retirement&amp;nbsp;saving?&lt;/h3&gt;

&lt;p&gt;Instead of tagging every transaction, I could nominate accounts or a subset of transactions as saving for retirement. These would be easy to spot&amp;nbsp;heuristically.&lt;/p&gt;

&lt;h3&gt;Can I afford to buy this expensive item this&amp;nbsp;month?&lt;/h3&gt;

&lt;p&gt;Answer: No. Better answer: Do I have enough of my genuinely disposable income left? Understanding what transactions are regular outgoings and which are genuinely disposable is key to this. Whether I spent the money on books or stuff for my bike is less important to&amp;nbsp;me.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/afternoon/~4/DcOz8vBZyjg" height="1" width="1"/&gt;</description><pubDate>Thu, 04 Oct 2012 13:26:48 +0300</pubDate><guid isPermaLink="false">http://aftnn.org/2012/oct/04/personal-finance-dashboards-uk-customers/</guid><category>pfm</category><feedburner:origLink>http://aftnn.org/2012/oct/04/personal-finance-dashboards-uk-customers/</feedburner:origLink></item><item><title>Play 2.0 And Scalate Step-By-Step
</title><link>http://feedproxy.google.com/~r/afternoon/~3/AoBi6SJ2eJk/</link><description>&lt;p&gt;Jan Helwich has done a great job of describing &lt;a href="http://janhelwich.wordpress.com/tag/scalate/"&gt;how to use Scalate with Play 2.0&lt;/a&gt;. He&amp;#8217;s even provided an &lt;a href="https://github.com/janhelwich/Play-2-with-Scala-and-Scalate"&gt;example Play 2.0 project which uses Scalate&lt;/a&gt;. This post contains step-by-step instructions for a new project based on his&amp;nbsp;work.&lt;/p&gt;

&lt;p&gt;For convenience, I&amp;#8217;ve also wrapped these changes up as a &lt;a href="https://gist.github.com/3812769"&gt;patch that can be applied to a new Play 2.0 project&lt;/a&gt;. Apply it with &lt;code&gt;git am --signoff play20-with-scalate.patch&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new Play&amp;nbsp;project.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;play new myproject
# choose "1 &amp;mdash; Create a simple Scala application"
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add Scalate to your project dependencies in &lt;code&gt;project/Build.scala&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;val appDependencies = Seq(                                                   
  // Add your project dependencies here,                                     
  "org.fusesource.scalate" % "scalate-core" % "1.5.3"                        
)
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Place a copy of Jan Helwich&amp;#8217;s &lt;code&gt;ScalateIntegration.scala&lt;/code&gt; in &lt;code&gt;app/lib&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;curl -o app/lib/ScalateIntegration.scala https://raw.github.com/janhelwich/Play-2-with-Scala-and-Scalate/master/app/controllers/ScalateIntegration.scala
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set the default Scalate template type in &lt;code&gt;conf/application.conf&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Default Scalate template format (mustache, scaml, jade, ssp)
scalate.format=jade
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a layout and a&amp;nbsp;template.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# app/views/layouts/default.jade
-@ var body: String
-@ var title: String = "Page"

!!!5
html
  head
    title= title
  body
    != body

# app/views/index.jade
-@ var title: String = "Page"

h1= title
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use your templates in a&amp;nbsp;controller.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;package controllers

import play.api._
import play.api.mvc._

object Application extends Controller {
  def index = Action {
    Ok(Scalate("index.jade").render('title -&amp;gt; "Hello world!"))
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Done! Try out your app with &lt;code&gt;play run&lt;/code&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/afternoon/~4/AoBi6SJ2eJk" height="1" width="1"/&gt;</description><pubDate>Mon, 01 Oct 2012 16:20:26 +0300</pubDate><guid isPermaLink="false">http://aftnn.org/2012/oct/01/play-20-and-scalate/</guid><category>play2</category><category>scala</category><category>scalate</category><feedburner:origLink>http://aftnn.org/2012/oct/01/play-20-and-scalate/</feedburner:origLink></item><item><title>Authentication workflow for gitlab, gitolite and AD
</title><link>http://feedproxy.google.com/~r/afternoon/~3/REMmthH21kk/</link><description>&lt;p&gt;&lt;a href="http://gitlabhq.com"&gt;gitlab&lt;/a&gt; and &lt;a href="http://sitaramc.github.com/gitolite/"&gt;gitolite&lt;/a&gt; can be integrated with Active Directory (or another &lt;span class="caps"&gt;LDAP&lt;/span&gt; server), but how it works is a bit&amp;nbsp;roundabout.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User logs in to gitlab web&amp;nbsp;interface&lt;/li&gt;
&lt;li&gt;gitlab checks user&amp;#8217;s credentials against Active Directory (&lt;a href="https://github.com/gitlabhq/gitlabhq/wiki/Setting-up-ldap-auth"&gt;via ominauth plugin&lt;/a&gt;) and allows log&amp;nbsp;in&lt;/li&gt;
&lt;li&gt;User uploads &lt;span class="caps"&gt;SSH&lt;/span&gt; key via gitlab web&amp;nbsp;interface&lt;/li&gt;
&lt;li&gt;gitlab writes key to gitolite keys&amp;nbsp;dir?&lt;/li&gt;
&lt;li&gt;User attempts to access repo via &lt;span class="caps"&gt;SSH&lt;/span&gt; (e.g. &lt;code&gt;git clone git@host:repo.git&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt; key is&amp;nbsp;sent&lt;/li&gt;
&lt;li&gt;gitolite checks keys dir and finds&amp;nbsp;key&lt;/li&gt;
&lt;li&gt;gitolite checks repository permissions and decides to allow the operation
&lt;ul&gt;
&lt;li&gt;This could be because user is a member of an &lt;span class="caps"&gt;AD&lt;/span&gt; group which has been assigned perms in &lt;code&gt;gitolite.conf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/1710266"&gt;Script to pull group info from&amp;nbsp;&lt;span class="caps"&gt;AD&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;repo is&amp;nbsp;cloned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simples!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/afternoon/~4/REMmthH21kk" height="1" width="1"/&gt;</description><pubDate>Fri, 20 Jul 2012 23:39:20 +0300</pubDate><guid isPermaLink="false">http://aftnn.org/2012/jul/20/authentication-workflow-gitlab-gitolite-and-ad/</guid><feedburner:origLink>http://aftnn.org/2012/jul/20/authentication-workflow-gitlab-gitolite-and-ad/</feedburner:origLink></item><item><title>The Specious Notion That Everybody Has To Earn A Living
</title><link>http://feedproxy.google.com/~r/afternoon/~3/XzDT3xt8XP8/</link><description>&lt;blockquote&gt;
  &lt;p&gt;We must do away with the absolutely specious notion that everybody has to earn
  a living. It is a fact today that one in ten thousand of us can make a
  technological breakthrough capable of supporting all the rest. The youth of
  today are absolutely right in recognizing this nonsense of earning a living.
  We keep inventing jobs because of this false idea that everybody has to be
  employed at some kind of drudgery because, according to Malthusian-Darwinian
  theory, he must justify his right to exist. So we have inspectors of
  inspectors and people making instruments for inspectors to inspect inspectors.
  The true business of people should be to go back to school and think about
  whatever it was they were thinking about before somebody came along and told
  them they had to earn a&amp;nbsp;living.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&amp;#8212; Buckminster&amp;nbsp;Fuller&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/afternoon/~4/XzDT3xt8XP8" height="1" width="1"/&gt;</description><pubDate>Fri, 13 Jul 2012 10:53:42 +0300</pubDate><guid isPermaLink="false">http://aftnn.org/2012/jul/13/specious-notion-everybody-has-earn-living/</guid><category>work</category><feedburner:origLink>http://aftnn.org/2012/jul/13/specious-notion-everybody-has-earn-living/</feedburner:origLink></item></channel></rss>
