<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>erj.me</title>
    <link>//erj.me/</link>
    <description>Recent content on erj.me</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 01 Feb 2016 21:39:59 +0100</lastBuildDate>
    <atom:link href="//erj.me/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Moving</title>
      <link>//erj.me/post/moving/</link>
      <pubDate>Mon, 01 Feb 2016 21:39:59 +0100</pubDate>
      
      <guid>//erj.me/post/moving/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s been a while since I wrote anything here. As usual, my inspiration
for stuff like this is extremely periodical.&lt;/p&gt;

&lt;p&gt;Since last time I posted, me and my wife have been in the process of
moving from Sweden to the UK. We&amp;rsquo;re leaving for Bristol tomorrow
morning, to be more specific. Our current plan is to live and work there
for approximately half a year.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;re going to be posting updates on &lt;a href=&#34;https://magdaocherik.meldanya.se&#34;&gt;a common
blog&lt;/a&gt; I set up for that. My current
idea is that I will cross post any interesting stuff here. We&amp;rsquo;ll see if
I stick to that. The other blog will be in Swedish though so the cross
posted posts are going to be in Swedish as well.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Thoughts on SpaceX</title>
      <link>//erj.me/post/thoughts-on-spacex/</link>
      <pubDate>Tue, 30 Jun 2015 08:30:53 +0200</pubDate>
      
      <guid>//erj.me/post/thoughts-on-spacex/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been wanting to write down my thoughts about SpaceX for a while
now. More precisely, ever since I read Phil Plait&amp;rsquo;s article about
&lt;a href=&#34;http://www.slate.com/blogs/bad_astronomy/2015/04/16/elon_musk_and_mars_spacex_ceo_and_our_multi_planet_species.html&#34;&gt;visiting the SpaceX
headquarters&lt;/a&gt;.
The accident last Sunday, where a &lt;a href=&#34;https://youtu.be/SrnN8GhqRj8&#34;&gt;Falcon 9 burned
up&lt;/a&gt; shortly after takeoff, triggered me
into sitting down and actually write them down.&lt;/p&gt;

&lt;p&gt;Plait&amp;rsquo;s article is really worth a read if you haven&amp;rsquo;t done so. In it,
Plait summarized his discussion with Elon Musk about the reason for
starting SpaceX. For the uninitiated, the goal of SpaceX is formulated
as the following on their &lt;a href=&#34;http://www.spacex.com/&#34;&gt;website&lt;/a&gt; (my bold):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The company was founded in 2002 to revolutionize space technology,
with &lt;strong&gt;the ultimate goal of enabling people to live on other
planets&lt;/strong&gt;.
&lt;cite&gt;&lt;a href=&#34;http://www.spacex.com/about&#34;&gt;spacex.com/about&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Plait joked about Musk having founded SpaceX because he wanted to retire
on Mars, which Musk quickly corrected. That was just something he said
when a journalist was pressing him for a quote. When Plait asked what
the actual reason was, Musk answered simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Humans need to be a multiplanet species. &lt;cite&gt;&lt;a href=&#34;http://www.slate.com/blogs/bad_astronomy/2015/04/16/elon_musk_and_mars_spacex_ceo_and_our_multi_planet_species.html&#34;&gt;Elon
Musk&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not &amp;ldquo;should be&amp;rdquo; or &amp;ldquo;it would be nice if we were&amp;rdquo;. No, we &lt;strong&gt;&lt;em&gt;need to
be&lt;/em&gt;&lt;/strong&gt; a multiplanet species for our longterm survival.&lt;/p&gt;

&lt;p&gt;This resonated quite strongly with me. Even if we set aside the blatant
disregard we&amp;rsquo;re currently showing for the only Earth we have, there are
still a multitude of natural disasters that can wipe us out from the
universe&amp;rsquo;s timeline. Basically, we need an &lt;strong&gt;off-site backup for
humanity&lt;/strong&gt; in order to secure our longterm survival.&lt;/p&gt;

&lt;p&gt;With this goal in mind, the work SpaceX is doing is extremely important
on a larger timescale. Which is why I was saddened by Sunday&amp;rsquo;s accident
(imagine then how Elon Musk is feeling, it happened on his &lt;em&gt;birthday&lt;/em&gt;,
really crappy birthday present). Currently, it looks like there was a
problem just before the first stage separation was to take place. SpaceX
hasn&amp;rsquo;t yet released any info other than Elon Musk&amp;rsquo;s tweet:&lt;/p&gt;

&lt;p&gt;&lt;blockquote class=&#34;twitter-tweet&#34; lang=&#34;en&#34; align=&#34;center&#34;&gt;
&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;There was an overpressure event in the upper
stage liquid oxygen tank. Data suggests counterintuitive
cause.&lt;/p&gt;&amp;mdash; Elon Musk (@elonmusk)
&lt;a href=&#34;https://twitter.com/elonmusk/status/615185076813459456&#34;&gt;June
28, 2015&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&#34;//platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;&lt;/p&gt;

&lt;p&gt;I hope this doesn&amp;rsquo;t hamper SpaceX&amp;rsquo;s progress too much. The work they&amp;rsquo;re
doing is really important and the whole of humanity would be poorer for
it, should they fail.&lt;/p&gt;

&lt;iframe width=&#34;560&#34; height=&#34;315&#34; style=&#34;margin: 0 auto; display:block;&#34;
src=&#34;https://www.youtube.com/embed/4PN5JJDh78I&#34; frameborder=&#34;0&#34;
allowfullscreen&gt;&lt;/iframe&gt;
</description>
    </item>
    
    <item>
      <title>I&#39;m An Average Programmer</title>
      <link>//erj.me/post/im-an-average-programmer/</link>
      <pubDate>Fri, 26 Jun 2015 21:21:46 +0200</pubDate>
      
      <guid>//erj.me/post/im-an-average-programmer/</guid>
      <description>

&lt;p&gt;&lt;a href=&#34;https://jacobian.org/&#34;&gt;Jacob Kaplan-Moss&amp;rsquo;&lt;/a&gt; keynote at PyCon 2015 has
got to be one of the best keynotes I&amp;rsquo;ve watched in a very long time:&lt;/p&gt;

&lt;iframe width=&#34;100%&#34; height=&#34;335&#34; src=&#34;https://www.youtube.com/embed/hIJdFxYlEKE&#34; frameborder=&#34;0&#34; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;As you&amp;rsquo;ll learn when you watch the keynote (yes when, not if, go do it
now!), he is a core contributor to
&lt;a href=&#34;https://www.djangoproject.com/&#34;&gt;Django&lt;/a&gt; and an ultra runner. You really
should watch the keynote before reading my thoughts &amp;mdash; they will seem
&lt;em&gt;even more&lt;/em&gt; like incoherent ramblings if you don&amp;rsquo;t. (I blame the whiskey
I&amp;rsquo;ve had tonight, or possibly the &lt;a href=&#34;https://play.spotify.com/user/spotify/playlist/2uAichKSjJSyrmal8Kb3W9&#34;&gt;90s music
playlist&lt;/a&gt;
Spotify suggested for me.)&lt;/p&gt;

&lt;p&gt;The main point of his presentation is that there is a perception problem
in the programming industry. We deify this highly improbable rock star
programmer, we expect everyone to be all-knowing yet specialised, we are
too fixed on the idea of programming as a talent and that most
programmers are either awesome or crap. Naturally, this leads to, or at
least contributes to, a number of problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Difficulty attracting new people to the programming industry.&lt;/li&gt;
&lt;li&gt;The entire industry is full of misogyny and discrimination of
minorities.&lt;/li&gt;
&lt;li&gt;It promotes unhealthy working habits and bad work life balance.&lt;/li&gt;
&lt;li&gt;It promotes the image of a programmer as a young, white dude.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pretty much all of what he said resonated with me, although I hadn&amp;rsquo;t
really thought about it in those terms before I watched the keynote.
I&amp;rsquo;ve had personal experience with the unhealthy working habits. The
expectation that I should be available for work calls at 9PM on a Sunday
evening bothers me immensely. Valuing free time highly should be okay.&lt;/p&gt;

&lt;p&gt;Part of the problem is probably that programming is a very young
industry, most of the people I know that work in older industries are
not expected to work evenings or weekends. Being an okay employee is
accepted, as long as you perform your duties.&lt;/p&gt;

&lt;p&gt;The misogyny and discrimination problem deserves an article all on its
own (and indeed I&amp;rsquo;m trying, and currently failing, to write one). I
recently purchased the essay collection &lt;a href=&#34;http://model-view-culture.myshopify.com/products/your-startup-is-broken&#34;&gt;Your Startup is
Broken&lt;/a&gt;
from Model-View-Culture, which I decided tonight I&amp;rsquo;m going to read this
weekend. It&amp;rsquo;s obviously a problem, the fact that my office has 3-4 women
(not including secretaries) among 30-40 employees is a horrible
disparity.&lt;/p&gt;

&lt;h2 id=&#34;quotes:6799712cded27892df2ef97676cb01ed&#34;&gt;Quotes&lt;/h2&gt;

&lt;p&gt;These are some quotes I particularly liked.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There&amp;rsquo;s a voice in the back of my head that&amp;rsquo;s telling me: &amp;ldquo;You don&amp;rsquo;t
deserve to be here. Look at the amazing people you shared this stage
with. Who are you? What did you do to get up on stage with them? You
don&amp;rsquo;t belong in this company. You don&amp;rsquo;t deserve this success.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This definitely felt familiar to me. It made me think about &lt;a href=&#34;https://en.wikipedia.org/wiki/Impostor_syndrome&#34;&gt;impostor
syndrome&lt;/a&gt;, which I most
definitely suffer from.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Because programming is something you are in this myth, not something
you do. The truth is that programming isn&amp;rsquo;t a passion, it isn&amp;rsquo;t a
talent. It&amp;rsquo;s just some things you can learn.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No doubt this is true, he points out that this is one of the few fields
where this is the case. No one assumes that people are born with the
ability to run a marathon &amp;ndash; that&amp;rsquo;s what training is for. Why would we
think it&amp;rsquo;s different for programming? It&amp;rsquo;s a set of skills to learn and
improve.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If we embrace this idea that it&amp;rsquo;s cool to be okay at these skills,
that being average is fine, it&amp;rsquo;ll be less intimidating for newcomers.
If we set the bar for success at &amp;ldquo;okay&amp;rdquo; rather than at &amp;ldquo;exceptional&amp;rdquo;,
that bar seems a lot easer to clear for people new to our community.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&#34;wrap-up:6799712cded27892df2ef97676cb01ed&#34;&gt;Wrap up&lt;/h2&gt;

&lt;p&gt;All of this is presented much more eloquently by Jacob Kaplan-Moss
during the keynote, so really, watch it if you haven&amp;rsquo;t yet.&lt;/p&gt;

&lt;p&gt;Without further ado, here&amp;rsquo;s the reason I started writing this post. I&amp;rsquo;m
joining Jacob Kaplan-Moss&amp;rsquo; call to action: &lt;strong&gt;I&amp;rsquo;m an average programmer.
I&amp;rsquo;m okay at programming and that&amp;rsquo;s okay.&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>UK vs. Swedish Voter Representation</title>
      <link>//erj.me/post/uk-vs-swedish-voter-representation/</link>
      <pubDate>Mon, 18 May 2015 15:10:44 +0200</pubDate>
      
      <guid>//erj.me/post/uk-vs-swedish-voter-representation/</guid>
      <description>

&lt;p&gt;I listen fairly religiously to the &lt;a href=&#34;http://www.hellointernet.fm/&#34;&gt;Hello Internet
podcast&lt;/a&gt; with &lt;a href=&#34;http://www.bradyharan.com/&#34;&gt;Brady
Haran&lt;/a&gt; and
&lt;a href=&#34;http://www.cgpgrey.com/&#34;&gt;CGPGrey&lt;/a&gt;. In the &lt;a href=&#34;http://www.hellointernet.fm/podcast/37&#34;&gt;most recent
episode&lt;/a&gt;, they discussed the
recent UK election and how badly the UK  voting system works to fairly
represent the actual distribution of votes. This piqued my interest so I
thought I would investigate how well Sweden performs in this regard.&lt;/p&gt;

&lt;p&gt;Right off the bat (after refreshing my memory on how our voting system
works&amp;hellip;), I realized this wouldn&amp;rsquo;t really be a fair comparison. In
order to understand why, get ready for a&amp;hellip;&lt;/p&gt;

&lt;h2 id=&#34;crash-course-in-the-swedish-voting-system:4f8a1b81a94cc6f89eb32e3a52d8a18c&#34;&gt;Crash Course in the Swedish Voting System&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;If you&amp;rsquo;re not interested in this part (why wouldn&amp;rsquo;t you be?!), you can
skip down to the actual &lt;a href=&#34;#comparison&#34;&gt;comparison&lt;/a&gt;. Although it might not
make as much sense if you skip this.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sweden&amp;rsquo;s allocation of seats in the Riksdag&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:4f8a1b81a94cc6f89eb32e3a52d8a18c:riksdag&#34;&gt;&lt;a rel=&#34;footnote&#34; href=&#34;#fn:4f8a1b81a94cc6f89eb32e3a52d8a18c:riksdag&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; is explicitly
designed (with some minor caveats) to be proportional to the number of
votes each party has received. The UK on the other hand, uses &lt;a href=&#34;https://youtu.be/s7tWHJfhiyo&#34;&gt;First
Past the Post voting&lt;/a&gt; which is what causes
their representation disparity.&lt;/p&gt;

&lt;p&gt;The basic system we have is fairly easy: The country is divided into a
number of &lt;em&gt;constituencies&lt;/em&gt; (historically there have been different
number of constituencies but we currently have 29). There are 349 seats
in the Riksdag, 310 of which are &lt;em&gt;fixed constituency seats&lt;/em&gt;. These 310
seats are divided between the constituencies in relation to the number
of people eligible to vote in each constituency. The remaining 39 seats
are &lt;em&gt;adjustment seats&lt;/em&gt; which I&amp;rsquo;ll explain a little later.  To be in the
running for any seats at all, a party needs at least 4% of the national
votes or 12% in any single constituency.&lt;/p&gt;

&lt;p&gt;In order to understand how seats are appointed to the different
political parties, we need to make a &amp;hellip;&lt;/p&gt;

&lt;h3 id=&#34;detour-to-the-sainte-lagu-euml-method:4f8a1b81a94cc6f89eb32e3a52d8a18c&#34;&gt;Detour to the Sainte-Lagu&amp;euml; method&lt;/h3&gt;

&lt;p&gt;The method used to calculate how many seats each party should receive is
called the &lt;a href=&#34;http://en.wikipedia.org/wiki/Sainte-Laguë_method&#34;&gt;Sainte-Lagu&amp;euml;
method&lt;/a&gt;. Actually,
Sweden uses a &lt;a href=&#34;http://en.wikipedia.org/wiki/Sainte-Lagu%C3%AB_method#Modified_Sainte-Lagu.C3.AB_method&#34;&gt;modified
Sainte-Lagu&amp;euml;&lt;/a&gt;
method but the basics are the same. I&amp;rsquo;ll just explain it briefly here so
if you&amp;rsquo;re interested in the specifics, read the Wikipedia article.&lt;/p&gt;

&lt;p&gt;Sainte-Lagu&amp;euml; is an iterative method. For each iteration, you
calculate a quotient for each party according to the following formula:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;quot = V / (2*s + 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Where &lt;code&gt;V&lt;/code&gt; is the number of votes the party has received and &lt;code&gt;s&lt;/code&gt; is the
number of seats the party has been appointed so far. The party with the
largest quotient is awarded the seat in this iteration. Looking at the
equation, it&amp;rsquo;s obvious that the quotient is equal to the number of votes
in the first iteration. This is where the modification Sweden has made
comes in: For parties that has received zero seats, their vote count is
divided by &lt;code&gt;1.2&lt;/code&gt; instead of &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s important (for the charts later in the article) to note that there
was a recent change to the election law in Sweden. Previously, the vote
count in the first iteration was divided by &lt;code&gt;1.4&lt;/code&gt; instead of &lt;code&gt;1.2&lt;/code&gt;.
However, this change was voted into law after the 2014 general election
so the results I&amp;rsquo;ve looked at below uses the old value.&lt;/p&gt;

&lt;h3 id=&#34;appointing-seats-in-sweden:4f8a1b81a94cc6f89eb32e3a52d8a18c&#34;&gt;Appointing seats in Sweden&lt;/h3&gt;

&lt;p&gt;When votes are counted in each constituency, the Sainte-Lagu&amp;euml;
method is used to appoint the seats in the constituency.&lt;/p&gt;

&lt;p&gt;When all the votes are counted and all constituencies have appointed
their seats, the number of seats each party has received over all
constituencies is tallied up. Next, the Sainte-Lagu&amp;euml; method is used
to simulate assigning all 349 seats but this time with the entire nation
as a single constituency. The number of seats each party has received in
the two different assignment processes is compared to see how good the
representation is at a national level.&lt;/p&gt;

&lt;p&gt;This is where the 39 adjustment seats come in to action. The parties
that have received too few seats when the 310 fixed seats were appointed
are given an adjustment seat in the constituency where it&amp;rsquo;s quotient is
still largest after the 310 seat appointment. Conversely, if it has
received too many seats, one is returned in the constituency where the
party has the smallest quotient. One interesting note is that the
appointment of the adjustment seats is done using the non-modified
version of Sainte-Lagu&amp;euml;.&lt;/p&gt;

&lt;p&gt;Also, to preempt any comments about it: Yes, we can vote for specific
persons in each constituency as well. I&amp;rsquo;m not going to dive into that
process though, I&amp;rsquo;ll have to save you some rabbit holes to go down over
at &lt;a href=&#34;http://en.wikipedia.org/wiki/Elections_in_Sweden&#34;&gt;Wikipedia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Wow! If you&amp;rsquo;re still here, you must be at least as much of a geek as I
am. Now, onto the promised comparison between the UK and Sweden:&lt;/p&gt;

&lt;h2 id=&#34;comparison:4f8a1b81a94cc6f89eb32e3a52d8a18c&#34;&gt;Comparison&lt;/h2&gt;

&lt;p&gt;Without further ado, here are the charts for Sweden:&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;//erj.me/media/2015/05/voting_representation.png&#34;&gt;&lt;img src=&#34;//erj.me/media/2015/05/voting_representation.png&#34; alt=&#34;Comparison between vote and seat distribution for
Sweden&#34; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can look at the full Google Spreadsheet
&lt;a href=&#34;https://docs.google.com/spreadsheets/d/1yePPqdISujzVb0WCZSHs2tXG1WK4cp4W5648oSJUdEY/edit?usp=sharing&#34;&gt;here&lt;/a&gt;.
For reference, below are &lt;a href=&#34;https://twitter.com/cgpgrey/status/596665514212069376&#34;&gt;CGPGrey&amp;rsquo;s original
charts&lt;/a&gt; for the
UK. You can also look at &lt;a href=&#34;https://www.icloud.com/numbers/AwBWCAESEENcsZJhlHNi5aJgx3Gdi6EaKnEB5rK4lDWfp3HH9qLYCzXRvg_JihRe2DA53sXagPKNmsR5BhkeV9YZIQMCUCAQEEIPMp3MFjWXzyI0fZfip26xLyNId3LvKoCV0bJFiSNyJr#2015_UK_Results&#34;&gt;his Numbers
spreadsheet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://pbs.twimg.com/media/CEfIH4fWAAArW84.png:large&#34;&gt;&lt;img src=&#34;https://pbs.twimg.com/media/CEfIH4fWAAArW84.png&#34; alt=&#34;Comparison between vote ans seat distritution for the
UK&#34; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I must say, I was pleasantly surprised that our representation is as
good as it is. You can see the fact that smaller parties are punished
somewhat while larger ones are rewarded (which is the system working as
intended) but overall, the representation is really good. Since parties
need to be above the 4% mark to even be considered for the seats, I
really should have removed the ones below that line in the left chart
but I don&amp;rsquo;t really feel like it.&lt;/p&gt;

&lt;p&gt;People naturally have opinions about the Swedish system as well. There
is some legitimate criticism that smaller parties are punished while
larger ones are rewarded. This comes from a combination of the 4%
barrier and the modification we have to the Sainte-Langu&amp;euml; method. I
can see the merit of this criticism but I think the system has to
promote larger parties. A legislature with too many small parties could
be problematic. In my opinion, this system strikes a good compromise
between fair representation and practicality. At any rate, it&amp;rsquo;s
definitely better than the UK system!&lt;/p&gt;

&lt;h2 id=&#34;reference:4f8a1b81a94cc6f89eb32e3a52d8a18c&#34;&gt;Reference&lt;/h2&gt;

&lt;p&gt;If you want to have a boring evening of reading, I would recommend the
&lt;a href=&#34;https://www.riksdagen.se/sv/Dokument-Lagar/Lagar/Svenskforfattningssamling/sfs_sfs-2005-837/#K14&#34;&gt;Swedish election
law&lt;/a&gt;,
that&amp;rsquo;s where I got my information from. Unfortunately, there are no
English translations of the current law so you have to be able to speak
Swedish to understand it.&lt;/p&gt;

&lt;p&gt;If you want to discuss any of this with me, you can find &lt;a href=&#34;https://twitter.com/Meldanya&#34;&gt;me on
Twitter&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr /&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:4f8a1b81a94cc6f89eb32e3a52d8a18c:riksdag&#34;&gt;The national legislative body of Sweden.
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:4f8a1b81a94cc6f89eb32e3a52d8a18c:riksdag&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>My Problems With Photos For OS X</title>
      <link>//erj.me/post/problems-with-photos-for-os-x/</link>
      <pubDate>Tue, 28 Apr 2015 07:21:18 +0200</pubDate>
      
      <guid>//erj.me/post/problems-with-photos-for-os-x/</guid>
      <description>

&lt;p&gt;I&amp;rsquo;ve had a really bad first impression of the new &lt;a href=&#34;https://www.apple.com/osx/photos/&#34;&gt;Photos
app&lt;/a&gt; for OS X. My scenario is a bit
of a corner case but it shouldn&amp;rsquo;t be a hard problem to solve if Photos
were even a tiny bit less stupid about a couple of things.&lt;/p&gt;

&lt;h2 id=&#34;scenario:1d59a935d809c96fa38af444b00ac97b&#34;&gt;Scenario&lt;/h2&gt;

&lt;p&gt;I don&amp;rsquo;t want to use Photos to actually organize my pictures on the file
system. I also don&amp;rsquo;t want to use Photo&amp;rsquo;s iCloud sync. The reason is that
I have a heterogeneous set of devices and computers at home and as a
result, I already have a system for managing my pictures that works on
all these devices. If I would go all in on Photos, I would have a hard
time using the same library on my Linux, Android and FreeBSD systems. (I
also have a bit of a philosophical issue with trusting my entire library
to a single program.)&lt;/p&gt;

&lt;p&gt;So if I already have a system, why would I want to use Photos at all?
Basically, there are two things I want from Photos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Marking photos I love as favourites.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Tagging photos with faces so I can find for example pictures of me
and my fiancée for the calendar my family does every year.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These features are nice enhancements to my library but not so crucial
that I want to give my entire library over to Photos.&lt;/p&gt;

&lt;p&gt;My current system involves manually creating folders for my pictures,
grouping them by capture date and naming the folder with something
descriptive. It&amp;rsquo;s fairly easy to maintain and since I don&amp;rsquo;t use any
special program, I can simply &lt;code&gt;rsync&lt;/code&gt; my pictures between my different
computers (and server) and all of them are able to display them
natively. The only part I&amp;rsquo;m missing is the two points above.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve thought about actually copying the &lt;code&gt;Masters&lt;/code&gt; directory in the
Photos library to the other systems but the problem is that the pictures
in that directory are arranged according to &lt;em&gt;import&lt;/em&gt; time. This means
that I would loose the ability to easily list all the pictures taken on
a particular day or event on the non-Apple systems &amp;mdash; a deal breaker
for me since that&amp;rsquo;s how I usually look at my pictures.&lt;/p&gt;

&lt;p&gt;Photos does support referenced libraries which I thought I could use to
achieve what I wanted (and I could if it wasn&amp;rsquo;t such a brain-dead
implementation). In a referenced library, no pictures are actually
copied to the library during an import. Instead, Photos keeps a
reference to where in the file system the pictures actually exist.&lt;/p&gt;

&lt;h2 id=&#34;problem:1d59a935d809c96fa38af444b00ac97b&#34;&gt;Problem&lt;/h2&gt;

&lt;p&gt;I launched Photos, opened its preferences and unchecked the &amp;ldquo;Copy items
to the Photos library&amp;rdquo; check box. I then began importing all my pictures
&amp;mdash; a modest 66GB. At first everything seemed to go well so I left the
computer and went to help some friends who were moving. When I got back
a couple of hours later, Photos was done importing and had finished
running facial recognition on all pictures. I opened Finder, curious
to see how big the library had become (it&amp;rsquo;s just references, shouldn&amp;rsquo;t
be more than a couple of gigabytes, right?).&lt;/p&gt;

&lt;p&gt;Before I even got to the &lt;code&gt;~/Pictures&lt;/code&gt; folder, I noticed something wrong:
I was down to under one gigabyte of disk space left. With suspicion, I
clicked on the &lt;code&gt;Photos Library.photoslibrary&lt;/code&gt; file (a fairly annoying
name for a file that isn&amp;rsquo;t even a file) and waited a second for Finder
to tell me how big it was.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;60GB?! What on earth happened here?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After some research, I found that some other people had had the same
issue. The conclusion they came to was that it seemed to be related to
facial recognition in some way.  The directory in the Photos library that
had expanded uncontrollably was &lt;code&gt;resources/modelresources&lt;/code&gt;. The folder
contains a lot of full-size &lt;em&gt;copies&lt;/em&gt;&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1d59a935d809c96fa38af444b00ac97b:copies&#34;&gt;&lt;a rel=&#34;footnote&#34; href=&#34;#fn:1d59a935d809c96fa38af444b00ac97b:copies&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; of my pictures but cropped
in some way, often cropped on peoples faces&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1d59a935d809c96fa38af444b00ac97b:faces&#34;&gt;&lt;a rel=&#34;footnote&#34; href=&#34;#fn:1d59a935d809c96fa38af444b00ac97b:faces&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;I don&amp;rsquo;t know how things are implemented behind the scenes but
apparently, none of the Apple engineers are constrained by disk space
(or alternatively, have significantly smaller libraries than I do). It&amp;rsquo;s
especially frustrating since it would be fairly resonable to assume that
a person that chooses to use referenced libraries already have a copy of
their pictures and doesn&amp;rsquo;t necessarily have that much disk space left.
Uncontrollably gobbling up disk space seems like a bad design decision
in this case.&lt;/p&gt;

&lt;p&gt;Until this rectified, Photos is basically useless for me. I don&amp;rsquo;t want
to give up that much disk space just to have the convenience points
listed above.&lt;/p&gt;

&lt;h2 id=&#34;thoughts-about-a-space-efficient-alternative-solution:1d59a935d809c96fa38af444b00ac97b&#34;&gt;Thoughts About a Space Efficient Alternative Solution&lt;/h2&gt;

&lt;p&gt;As a programmer, I began thinking about the least amount of information
I would need to store in order to keep track of which people are in
which pictures. &lt;strong&gt;Note: This is a rough idea and undoubtedly, someone
will find a problem with it. It also only handles face detection and
doesn&amp;rsquo;t concern itself with thumbnails and other things needed in the
library.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let&amp;rsquo;s assume our facial recognition algorithm returns a list of the
positions (&lt;code&gt;x1,y1,x2,y2&lt;/code&gt;) of faces in each picture it processes. We then
ask the user to identify which person belongs to which face so we can
attach a name (and some form of unique identifier) to each face. This
would give us the following information to keep track of for each
detected face:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A UUID representing the person this face belongs to.&lt;/li&gt;
&lt;li&gt;A tuple (&lt;code&gt;x1,y1,x2,y2&lt;/code&gt;) representing the rectangle of the location of
the face in the picture.&lt;/li&gt;
&lt;li&gt;A reference to the picture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This would allow us to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List all the pictures a specific person is in.&lt;/li&gt;
&lt;li&gt;Show the location of each face in each picture.&lt;/li&gt;
&lt;li&gt;List all faces in a particular picture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This covers all the functionality Photos provides for faces. We&amp;rsquo;ll
assume a UUID is 128 bits and each position coordinate is 64 bits (a bit
overkill, yes).  The reference could be an absolute path to the picture
which would make it hard to estimate its size. Lets say its 32 bits for
each character and max 500 characters long (the paths to my pictures
would easily fit in half of that). This would mean a maximum of &lt;code&gt;128 + 4
* 32
+ 32 * 500 = 16 256 bits&lt;/code&gt; for each face.&lt;/p&gt;

&lt;p&gt;Allowing for an average of 3 faces in each picture (probably high for my
library), this would mean that the library would take up &lt;code&gt;3 * 5400 *
16253 = 263 298 600 bits ≈ 32 MB&lt;/code&gt; with this method.&lt;/p&gt;

&lt;h3 id=&#34;caveats:1d59a935d809c96fa38af444b00ac97b&#34;&gt;Caveats&lt;/h3&gt;

&lt;p&gt;Note that this (deliberately) doesn&amp;rsquo;t say anything about the data
structures used to store the information. In reality, we would need to
keep it in some sort of database with indexes that allows us to look up
rows by UUID or picture reference quickly. This would undoubtedly mean a
larger library than I have calculated above but it would probably still
be possible to stay under 1GB.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr /&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:1d59a935d809c96fa38af444b00ac97b:copies&#34;&gt;&lt;p&gt;Yes, copies, not hard links as some forum posts claim. The
	   inode count for the files in that directory is 1, meaning
	   those files are the only reference pointing to that inode.&lt;/p&gt;
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1d59a935d809c96fa38af444b00ac97b:copies&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;

&lt;li id=&#34;fn:1d59a935d809c96fa38af444b00ac97b:faces&#34;&gt;&lt;p&gt;This is what lead people to think that &lt;code&gt;modelresources&lt;/code&gt; has
	  something to do with facial recognition. Although not all
	  pictures in my &lt;code&gt;modelresources&lt;/code&gt; were of faces.&lt;/p&gt;
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1d59a935d809c96fa38af444b00ac97b:faces&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Why I Don&#39;t Hate Git: Hidden Consistency</title>
      <link>//erj.me/post/why-i-dont-hate-git-hidden-consistency/</link>
      <pubDate>Wed, 08 Apr 2015 12:39:11 +0200</pubDate>
      
      <guid>//erj.me/post/why-i-dont-hate-git-hidden-consistency/</guid>
      <description>&lt;p&gt;This post resonated quite well with me and explains why I have a harder
time learning Mercurial than I had learning Git.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>This Industry Is Still Completely Ridiculous</title>
      <link>//erj.me/post/this-industry-is-completely-ridiculous/</link>
      <pubDate>Tue, 07 Apr 2015 10:59:12 +0200</pubDate>
      
      <guid>//erj.me/post/this-industry-is-completely-ridiculous/</guid>
      <description>&lt;p&gt;This is a great article on TechCrunch about how the technology industry
is a bit weird. A lot of stuff made me laugh throughout the article.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;And we we were all faced with the hilariously terrifying possibility
that technology is now moving so fast that the US government can no
longer distinguish a rogue state with nuclear weapons from a gang of
trolls in it for the lulz.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another one:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Maybe this kind of florid bureaucratic surreality from their online
guardians is why both the US president and the UK’s prime minister
have called for math to be banned, lest their surveillance states be
blinded. No, really. Encryption is just math, folks. And making math
illegal will obviously stop terrorists. Right?
&lt;blockquote class=&#34;twitter-tweet&#34; lang=&#34;en&#34;&gt;&lt;p&gt;ISIS guy 1: I know, let&amp;#39;s use cryptography to hide our messages!&amp;#10;ISIS guy 2: We can&amp;#39;t, it&amp;#39;s against the law in the UK.&amp;#10;ISIS guy 1: Oh, OK.&lt;/p&gt;&amp;mdash; Mustafa Al-Bassam (@musalbas) &lt;a href=&#34;https://twitter.com/musalbas/status/554724039248592899&#34;&gt;January 12, 2015&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src=&#34;//platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    
    <item>
      <title>Thoughts About Moto 360</title>
      <link>//erj.me/post/moto-360/</link>
      <pubDate>Thu, 02 Apr 2015 18:13:04 +0100</pubDate>
      
      <guid>//erj.me/post/moto-360/</guid>
      <description>

&lt;p&gt;When I graduated from university last summer, my fiancée and her family
were very nice and bought me a smart watch as a graduation present.
Knowing that I&amp;rsquo;m a bit picky about my technology items, instead of
buying one directly, they gave me the money to buy the watch I wanted. I
had my eyes on the &lt;a href=&#34;https://moto360.motorola.com/&#34;&gt;Motorola Moto 360&lt;/a&gt;
which meant that I had to wait for a a couple of months since it wasn&amp;rsquo;t
available here in Sweden at the time. As soon as I could, I ordered it
and I&amp;rsquo;ve been wearing it daily since mid-January.&lt;/p&gt;

&lt;p&gt;This post is a collection of my thoughts about the watch interspersed
with images of it when I unboxed it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;//erj.me/media/2015/01/DSC_0187.JPG&#34;&gt;&lt;img src=&#34;//erj.me/media/2015/01/DSC_0187_thumb.JPG&#34; alt=&#34;Moto 360 in its
packaging&#34; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&#34;replacing-a-regular-watch:2de5c9a1a12df2f8313b33d447895bc2&#34;&gt;Replacing a Regular Watch&lt;/h2&gt;

&lt;p&gt;I was wearing a regular watch before buying the Moto 360. The regular
watch is actually better at two things: battery life and displaying time
(really?). I&amp;rsquo;ll get to the battery life later in the post but the reason
the Moto 360 is worse at displaying time is that the screen is turned
off after a while. This is slightly annoying since it takes the Moto 360
a fraction of a second to wake up when I look at it which isn&amp;rsquo;t a
problem the regular watch has.&lt;/p&gt;

&lt;p&gt;Even more annoying is that sometimes, the watch face doesn&amp;rsquo;t wake up at
all when I look at it. This happens so infrequent as to be tolerable
though, I simply flick my wrist again to wake it up. I also enabled
Ambient Screen recently which seems to alleviate the problem completely.
I&amp;rsquo;m hoping it won&amp;rsquo;t eat too much battery so I can leave it on as my new
default.  Speaking of battery&amp;hellip;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;//erj.me/media/2015/01/DSC_0189.JPG&#34;&gt;&lt;img src=&#34;//erj.me/media/2015/01/DSC_0189_thumb.JPG&#34; alt=&#34;Moto 360 in its opened
packaging&#34; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&#34;battery-life:2de5c9a1a12df2f8313b33d447895bc2&#34;&gt;Battery Life&lt;/h2&gt;

&lt;p&gt;Some early reports on the Moto 360 were complaining that the battery
life was terrible. That couldn&amp;rsquo;t be further from my experience&amp;mdash;I often
take it off when I get home after a whole day with 60&amp;ndash;70% left. That&amp;rsquo;s
with Ambient Screen turned off though. For reasons you&amp;rsquo;ll see below, I
usually sleep with the watch on me as well and usually only charge it in
the morning while I do my morning routine. It charges incredibly fast
(possible because the battery is small) and is usually fully charged
when I leave home.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;//erj.me/media/2015/01/DSC_0190.JPG&#34;&gt;&lt;img src=&#34;//erj.me/media/2015/01/DSC_0190_thumb.JPG&#34; alt=&#34;Moto 360 in its opened
packaging&#34; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&#34;most-useful-features:2de5c9a1a12df2f8313b33d447895bc2&#34;&gt;Most Useful Features&lt;/h2&gt;

&lt;p&gt;The rest of the article is a list of the most useful features of the
watch from my perspective, ordered by their usefulness.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;//erj.me/media/2015/01/DSC_0193.JPG&#34;&gt;&lt;img src=&#34;//erj.me/media/2015/01/DSC_0193_thumb.JPG&#34; alt=&#34;All the packaging&#39;s
content&#34; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&#34;silent-alarm:2de5c9a1a12df2f8313b33d447895bc2&#34;&gt;Silent Alarm&lt;/h3&gt;

&lt;p&gt;This is by far the most useful feature for my fiancé (and me). I use
&lt;a href=&#34;https://play.google.com/store/apps/details?id=com.urbandroid.sleep&#34;&gt;Sleep as
Android&lt;/a&gt;
as my alarm clock app. It features some nice sleep tracking capabilities
which uses the watch&amp;rsquo;s accelerometer but the real killer feature is the
silent alarm. A couple of seconds before my alarm is about to go off,
the watch starts to vibrate slightly on my wrist. This wakes me up so I
can turn off the alarm just before it makes any sound.&lt;/p&gt;

&lt;p&gt;My fiancé is very thankful for this since I&amp;rsquo;m a heavy sleeper and she&amp;rsquo;s
not. I used to have fairly loud alarm signals which almost woke her up
with heart palpitations in the mornings (not a nice way to wake up).
Now, she doesn&amp;rsquo;t even wake up before I (stupidly) step on the creaky
floor board as I&amp;rsquo;m tiptoeing out of the bedroom.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;//erj.me/media/2015/01/DSC_0194.JPG&#34;&gt;&lt;img src=&#34;//erj.me/media/2015/01/DSC_0194_thumb.JPG&#34; alt=&#34;Moto
360&#34; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&#34;runkeeper:2de5c9a1a12df2f8313b33d447895bc2&#34;&gt;Runkeeper&lt;/h3&gt;

&lt;p&gt;I track my runs with
&lt;a href=&#34;https://play.google.com/store/apps/details?id=com.fitnesskeeper.runkeeper.pro&#34;&gt;Runkeeper&lt;/a&gt;
which is an awesome app. However, it&amp;rsquo;s a bit cumbersome to get the phone
out of my pocket every time I want to see how far I&amp;rsquo;ve run. With the
watch, I can see the distance, duration and pace of the run on my wrist.
This has been even more useful since I had an accident with my old Nexus
4 and bought a Nexus 6&amp;mdash;it&amp;rsquo;s much harder to get the Nexus 6 into and
out of the pocket of my running tights.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;//erj.me/media/2015/01/DSC_0196.JPG&#34;&gt;&lt;img src=&#34;//erj.me/media/2015/01/DSC_0196_thumb.JPG&#34; alt=&#34;Moto 360 on its
side&#34; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&#34;pocket-casts:2de5c9a1a12df2f8313b33d447895bc2&#34;&gt;Pocket Casts&lt;/h3&gt;

&lt;p&gt;I like that Pocket Casts displays a persistent notification on the watch
when I&amp;rsquo;m listening to podcasts. The notification has controls for
pausing, skipping and changing volume. Having these controls easily
accessible on the wrist is very useful when I&amp;rsquo;m walking to the train
with the phone in my pocket or when I&amp;rsquo;m out running.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;//erj.me/media/2015/01/DSC_0201.JPG&#34;&gt;&lt;img src=&#34;//erj.me/media/2015/01/DSC_0201_thumb.JPG&#34; alt=&#34;Moto 360 on
charger&#34; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;//erj.me/media/2015/01/DSC_0204.JPG&#34;&gt;&lt;img src=&#34;//erj.me/media/2015/01/DSC_0204_thumb.JPG&#34; alt=&#34;Moto 360
started&#34; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;//erj.me/media/2015/01/DSC_0206.JPG&#34;&gt;&lt;img src=&#34;//erj.me/media/2015/01/DSC_0206_thumb.JPG&#34; alt=&#34;Moto 360
started&#34; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&#34;wrap-up:2de5c9a1a12df2f8313b33d447895bc2&#34;&gt;Wrap Up&lt;/h2&gt;

&lt;p&gt;I love my new watch! It took the place of my existing watch
effortlessly. If anyone is worrying about the size of the watch, don&amp;rsquo;t.
It&amp;rsquo;s perfectly sized and looks like a nice, big, regular watch.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>This American Life: Cops See It Differently</title>
      <link>//erj.me/post/this-american-life-cops-see-it-differently/</link>
      <pubDate>Sat, 21 Feb 2015 18:04:37 +0100</pubDate>
      
      <guid>//erj.me/post/this-american-life-cops-see-it-differently/</guid>
      <description>&lt;p&gt;The radio-show-turned-podcast This American Life recently did two
episodes on how the views of police officers and civilians can differ.
This American Life usually produce very good podcasts but these episodes
really struck me as extraordinary. Everyone should probably listen to
them.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve embedded the SoundCloud player with the two episodes below so you
don&amp;rsquo;t even need to search for them.&lt;/p&gt;

&lt;iframe width=&#34;100%&#34; height=&#34;150&#34; scrolling=&#34;no&#34; frameborder=&#34;no&#34; src=&#34;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/190266009&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;visual=true&#34;&gt;&lt;/iframe&gt;

&lt;iframe width=&#34;100%&#34; height=&#34;150&#34; scrolling=&#34;no&#34; frameborder=&#34;no&#34; src=&#34;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/191440865&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;visual=true&#34;&gt;&lt;/iframe&gt;
</description>
    </item>
    
    <item>
      <title>Parsing Polynomials in C</title>
      <link>//erj.me/post/polynomial_in_c/</link>
      <pubDate>Thu, 08 Jan 2015 07:15:58 +0000</pubDate>
      
      <guid>//erj.me/post/polynomial_in_c/</guid>
      <description>

&lt;p&gt;This autumn, I worked as one of the teaching assistants in
&lt;a href=&#34;http://cs.lth.se/edaa25-c-programming/&#34;&gt;EDAA25&lt;/a&gt;, the C programming
course at Lund University&amp;rsquo;s Computer Science department.  This mainly
involves grading the programming assignments the students are required
to hand in during the course. After grading a &lt;em&gt;lot&lt;/em&gt; of solutions, I&amp;rsquo;m
amazed by how many students have difficulties structuring their code in
a reasonable and readable way. Many solutions barely work, or rely on
undefined behaviour to work, but even the correct ones are extremely
difficult to read and understand. A lot of students write functions that
span multiple &lt;em&gt;printed&lt;/em&gt; pages. The students are mostly fourth or fifth
year students pursuing a master of computer science and engineering
degree. I believe they ought to be able to do better.&lt;/p&gt;

&lt;p&gt;One could probably draw some conclusions from this regarding how much
programming the students have actually learned during their first 3&amp;ndash;4
years of studying. However, that&amp;rsquo;s for another post. In this post, I&amp;rsquo;m
presenting a solution for part of the third programming assignment which
I think is ideal and easy to understand.&lt;/p&gt;

&lt;p&gt;Before continuing, allow me to state the obvious: &lt;strong&gt;If &lt;em&gt;you&lt;/em&gt; are taking
the course, stop reading now and solve the assignment on your own! You
will learn nothing from copying this solution and it will only hurt you
during the exam (which is usually pretty excruciating). Also, the
parsing function that I&amp;rsquo;m presenting here is not the must difficult part
of the assignment.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&#34;problem-description:246fed17df2da0f5021c2932efc2e0a9&#34;&gt;Problem Description&lt;/h2&gt;

&lt;p&gt;The assignment consists of implementing a couple of function that can
parse, multiply and print polynomials. The format of a polynomial is
fairly simple:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;x^2 - 2x + 1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I will only present an implementation of the parsing function.&lt;/p&gt;

&lt;h3 id=&#34;structure-of-a-polynomial:246fed17df2da0f5021c2932efc2e0a9&#34;&gt;Structure of a Polynomial&lt;/h3&gt;

&lt;p&gt;Below is a simplified (but hopefully complete)
&lt;a href=&#34;http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form&#34;&gt;EBNF&lt;/a&gt;
notation of a polynomial (optional whitespace is left out).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;polynomial  = term , { sign, term } ;
term        = coefficient
            | [ coefficient ] , variable
            | [ coefficient ] , variable , exponent ;
sign        = &amp;quot;+&amp;quot; | &amp;quot;-&amp;quot; ;
coefficient = number ;
variable    = &amp;quot;x&amp;quot; ;
exponent    = &amp;quot;^&amp;quot; , number ;
number      = digit , { digit } ;
digit       = &amp;quot;0&amp;quot; | &amp;quot;1&amp;quot; | &amp;quot;2&amp;quot; | &amp;quot;3&amp;quot; | &amp;quot;4&amp;quot; | &amp;quot;5&amp;quot; | &amp;quot;6&amp;quot; | &amp;quot;7&amp;quot;
            | &amp;quot;8&amp;quot; | &amp;quot;9&amp;quot; ;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That is, a polynomial consists of a number of terms separated by a sign.
A term consists of three cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only a coefficient, e.g. &lt;code&gt;2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;An optional coefficient and a variable, e.g. &lt;code&gt;2x&lt;/code&gt; or &lt;code&gt;x&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;An optional coefficient, followed by a variable and an exponent, e.g.
&lt;code&gt;2x^2&lt;/code&gt; or &lt;code&gt;x^100&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are some example polynomials:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; 1
 x^2 + 3
 x^1000 - 6x + 2
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;implementation:246fed17df2da0f5021c2932efc2e0a9&#34;&gt;Implementation&lt;/h2&gt;

&lt;p&gt;The students are given some handout code that specifies which functions
and data types should be implemented:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-c&#34;&gt;typedef struct poly_t poly_t;

/* Parse the input string and return a new poly_t. */
poly_t* new_poly_from_string(const char*);
/* Free the input poly_t. */
void free_poly(poly_t*);
/* Multiply the two input poly_t&#39;s. */ 
poly_t* mul(poly_t*, poly_t*);
/* Print the input poly_t in the same format we parsed above. */ 
void print_poly(poly_t*);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thus, the students need to implement one data type (&lt;code&gt;poly_t&lt;/code&gt;) and four
functions (&lt;code&gt;new_poly_from_string()&lt;/code&gt;, &lt;code&gt;free_poly()&lt;/code&gt;, &lt;code&gt;mul()&lt;/code&gt;,
&lt;code&gt;print_poly()&lt;/code&gt;). The only error checking the students are required to do
is to detect the error, print a message about it and call
&lt;code&gt;exit(EXIT_FAILURE)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since the students aren&amp;rsquo;t given any limit on the number of terms their
implementations should handle, it is expected that their solution should
build on a linked list (I believe this is mentioned during one of the
lectures).  I.e. each term in a polynomial is represented by a node in
the linked list. The data structure looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-c&#34;&gt;/* Represents a term in a polynomial. */
struct poly_t {
	int	e;	/* Exponent of this term. */
	int	c;	/* Coefficient of this term.*/
	poly_t*	next;	/* The next term. */
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This seems like a fairly straight forward and simple, yet still
flexible, way to represent a polynomial. However, many students try to
define the data structure in much more creative ways which often involve
multiple arrays and a guinea pig. (By the way, do a Google Image search
for guinea pigs, they are absolutely adorable!)&lt;/p&gt;

&lt;p&gt;Next, we&amp;rsquo;ll get to the point of this post: The implementation of the
&lt;code&gt;new_poly_from_string&lt;/code&gt; function that parses a string containing a
polynomial. This solution is split into a couple of small and easily
understood helper functions. The students seem to have forgotten that
you don&amp;rsquo;t need to implement all functionality in a single function.&lt;/p&gt;

&lt;p&gt;The legibility is especially important since the students are required
to print out their solutions and we (as teaching assistants) have to
grade these printed versions&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:246fed17df2da0f5021c2932efc2e0a9:paper&#34;&gt;&lt;a rel=&#34;footnote&#34; href=&#34;#fn:246fed17df2da0f5021c2932efc2e0a9:paper&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. After realizing that basically
&lt;em&gt;all&lt;/em&gt; implementations of this function span at least 1.5 pages, I found
myself wishing that the students would think about readability for even
one second before handing in their solutions.&lt;/p&gt;

&lt;p&gt;The idea of my implementation is to do a simple one pass parse of the
string and implement an &lt;code&gt;accept_*&lt;/code&gt; function for each part it parses.
We&amp;rsquo;ll use a top-down approach so let&amp;rsquo;s start with the finished function
that parses the polynomial:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-c&#34;&gt;/* Struct to keep track of the position in the string. */
typedef struct parser_ctx_t {
	const char*	str;
} parser_ctx_t;

poly_t* new_poly_from_string(const char* str)
{
	poly_t*		poly;
	poly_t*		term;
	parser_ctx_t	ctx;

	poly	= NULL;
	term	= NULL;
	ctx.str	= str;

	while (*ctx.str) {
		if (term == NULL) {
			/* Parse the first term. */
			term = accept_term(&amp;amp;ctx);
			/* Keep a pointer to the first term. */
			poly = term;
		} else {
			term-&amp;gt;next = accept_term(&amp;amp;ctx);
			/* Advance to the new term. */
			term = term-&amp;gt;next;
		}
	}

	return poly;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Look how clean and easy to understand that function is (and it would
print nicely)!&lt;/p&gt;

&lt;p&gt;OK, let&amp;rsquo;s go through this code a bit. The first thing we do is to define
a type called &lt;code&gt;parser_ctx_t&lt;/code&gt; that holds a pointer to the current
position in the string. An instance of this type will be passed around
to the &lt;code&gt;accept_*&lt;/code&gt; functions in order for them to advance the string
pointer. This could be done by passing around a pointer to the pointer
to the string directly, but frankly I like this better. Mostly because
it looks nicer.&lt;/p&gt;

&lt;p&gt;The rest of the function is fairly straight forward. As long as there is
anything left to parse from the string, we parse another term by calling
&lt;code&gt;accept_term()&lt;/code&gt;. The loop simply builds up the linked list one term at a
time and keeps a reference to the first term.  The &lt;code&gt;poly&lt;/code&gt; pointer will
point to the first term (and thus be returned at the end) while &lt;code&gt;term&lt;/code&gt;
will point to the last parsed term. Next, let&amp;rsquo;s look at &lt;code&gt;accept_term()&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-c&#34;&gt;static poly_t* new_term(int c, int e)
{
	poly_t*	poly;

	poly	= malloc(sizeof(poly_t));
	if (poly == NULL)
		error(__FILE__, __LINE__, __func__,
		      &amp;quot;Failed to allocate poly.&amp;quot;);

	poly-&amp;gt;c		= c;
	poly-&amp;gt;e		= e;
	poly-&amp;gt;next	= NULL;

	return poly;
}

static poly_t* accept_term(parser_ctx_t* ctx)
{
	poly_t*	term;
	int	c;
	int	e;

	c	= accept_coefficient(ctx);
	e	= accept_exponent(ctx);
	term	= new_term(c, e);

	return term;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, that&amp;rsquo;s simple. We have a helper function to allocate a new term
and perform error checking on the memory allocation. The &lt;code&gt;error()&lt;/code&gt;
function is provided to the students in the handout code. It simply
prints the message in a nicely formatted way and exits the program with
exit code &lt;code&gt;EXIT_FAILURE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;accept_term()&lt;/code&gt; function is not very interesting. It uses two helper
functions to parse the coefficient and exponent of a term and then
creates and returns a new term. Let&amp;rsquo;s continue to the two helper
functions &lt;code&gt;accept_term()&lt;/code&gt; uses:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-c&#34;&gt;static int accept_coefficient(parser_ctx_t* ctx)
{
	int	c;	/* The coefficient to parse. */
	int	sign;	/* The sign of that coefficient. */

	sign	= accept_sign(ctx);
	c	= accept_number(ctx);

	return c * sign;
}

static int accept_exponent(parser_ctx_t* ctx)
{
	int	e;	/* The exponent to parse. */

	e	= 0;	/* Default exponent to zero. */

	accept_space(ctx);
	if (*ctx-&amp;gt;str == &#39;x&#39;) {
		e = 1;
		ctx-&amp;gt;str++;

		if (*ctx-&amp;gt;str == &#39;^&#39;) {
			ctx-&amp;gt;str++;
			e = accept_number(ctx);
		}
	}

	return e;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;accept_coefficient()&lt;/code&gt; is fairly uninteresting as well, we accept a sign
(i.e. a plus or a minus) and then a number. &lt;code&gt;accept_exponent()&lt;/code&gt; on the
other hand is a bit more interesting. For good measure, we use
&lt;code&gt;accept_space()&lt;/code&gt; to discard any whitespace before the actual exponent.
Now we have a couple of cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If we have no variable (i.e. an x), we default the exponent to zero.&lt;/li&gt;
&lt;li&gt;If we have a variable but no caret, we set the exponent to one.&lt;/li&gt;
&lt;li&gt;If we also have a caret, we parse the number succeeding the caret.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I should probably point out that the students are not required to handle
negative exponents although it would be trivial to add in my solution.&lt;/p&gt;

&lt;p&gt;The last helper functions are &lt;code&gt;accept_space()&lt;/code&gt;, &lt;code&gt;accept_sign()&lt;/code&gt; and
&lt;code&gt;accept_number()&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-c&#34;&gt;static void accept_space(parser_ctx_t* ctx)
{
	while (isspace(*ctx-&amp;gt;str))
		ctx-&amp;gt;str++;
}

static int accept_sign(parser_ctx_t* ctx)
{
	int	sign;	/* The sign to parse. */

	sign	= 1;	/* Default to positive sign. */

	accept_space(ctx);

	if (*ctx-&amp;gt;str == &#39;-&#39;) {
		sign = -1;
		ctx-&amp;gt;str++;
	} else if (*ctx-&amp;gt;str == &#39;+&#39;) {
		ctx-&amp;gt;str++;
	}

	return sign;
}

static int accept_number(parser_ctx_t* ctx)
{
	int	num;	/* The coefficient to parse. */
	char*	end;	/* The end pointer returned by strtol. */

	num	= strtol(ctx-&amp;gt;str, &amp;amp;end, 10);
	if (ctx-&amp;gt;str == end) {
		/* No number to parse, default to 1. */
		num	= 1;
	}
	ctx-&amp;gt;str	= end;

	return num;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;accept_space()&lt;/code&gt; simply discards any whitespace in the string.
&lt;code&gt;accept_sign()&lt;/code&gt; parses a sign and returns +/- 1 which allows us to
multiply it with a number when parsing the coefficient.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;accept_number()&lt;/code&gt; is a bit more interesting and I&amp;rsquo;m pretty satisfied
with the implementation. It leans heavily on &lt;code&gt;strtol()&lt;/code&gt; but using
functions in the C standard library is obviously OK in the course.
&lt;code&gt;strtol()&lt;/code&gt; discards any whitespace and then parses a number from the
string, stopping at the first non-digit. It stores the location at which
it stops in the pointer provided as the second argument. If the pointer
it set is the same as the one we provided, it didn&amp;rsquo;t parse any number.
If this is the case, we default the parsed number to 1. This works in
both our cases when we need to parse numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If we try to parse a coefficient and doesn&amp;rsquo;t have a number to parse,
we have a term with only a variable (e.g. &lt;code&gt;x&lt;/code&gt; or &lt;code&gt;x^23&lt;/code&gt;) which should
have the coefficient 1.&lt;/li&gt;
&lt;li&gt;If we try to parse an exponent and there&amp;rsquo;s no caret, then we know we
should skip calling &lt;code&gt;accept_number()&lt;/code&gt; since there&amp;rsquo;s no number to
parse. If we do have a caret in the string, there will be a number to
parse and &lt;code&gt;accept_number()&lt;/code&gt; will succeed in parsing it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that&amp;rsquo;s it! A simple implementation which is easy to understand and
follow.&lt;/p&gt;

&lt;h2 id=&#34;finishing-thoughts:246fed17df2da0f5021c2932efc2e0a9&#34;&gt;Finishing thoughts&lt;/h2&gt;

&lt;p&gt;While there are most likely some minor problems with this solution, it
is simple to understand and parses well-formatted polynomials which is
what the assignment requires. The main point I wanted to make here was
that it is possible to implement this function in a way that doesn&amp;rsquo;t
require complicated lookahead/lookbehind or multiple passes through the
string while making it readable at the same time.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr /&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:246fed17df2da0f5021c2932efc2e0a9:paper&#34;&gt;I have my reservations about this system as well but it&amp;rsquo;s the one we&amp;rsquo;re stuck with for various reasons
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:246fed17df2da0f5021c2932efc2e0a9:paper&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Run Free - The True Story of Caballo Blanco</title>
      <link>//erj.me/post/run-free-the-true-story-of-caballo-blanco/</link>
      <pubDate>Thu, 01 Jan 2015 13:00:53 +0100</pubDate>
      
      <guid>//erj.me/post/run-free-the-true-story-of-caballo-blanco/</guid>
      <description>&lt;p&gt;A while ago, I found the Kickstarter campaign for the documentary about
Micah True and decided to contribute to it. As part of the pledge, I was
given preview access to the film and I just watched it. It&amp;rsquo;s a great
film that commemorates Micah True&amp;rsquo;s life and the race he arranged in the
Copper Canyon in Mexico beautifully. The documentary should be coming
out later this year so keep your eyes on its
&lt;a href=&#34;http://www.runfreemovie.com/&#34;&gt;website&lt;/a&gt; if you&amp;rsquo;re interested.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>&#34;Öppenhet&#34; på SD:s villkor</title>
      <link>//erj.me/post/oppenhet-pa-sds-villkor/</link>
      <pubDate>Mon, 15 Dec 2014 16:33:08 +0000</pubDate>
      
      <guid>//erj.me/post/oppenhet-pa-sds-villkor/</guid>
      <description>&lt;p&gt;SD:s Björn Söder, nu vice talman i riksdagen, har hamnat i blåsväder
efter att ha vädrat sin ganska obehagliga människosyn i &lt;a href=&#34;http://dn.se/val/nyval-2015/den-leende-nationalismen/&#34;&gt;en intervju i
DN&lt;/a&gt;. Efter att ha
sett kommentarer flyga runt lite på Twitter bestämde jag mig för att
bryta min sedvanliga regel att inte läsa om politik (jag har högt
blodtryck så det räcker redan) och ögna igenom artikeln. Jag reagerade
speciellt på ett svar han gav:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Om många Malmöbor inte är en del av den nationella gemenskap som du
och ditt parti vill bygga – vad vill du göra med dem?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;– De får anpassa sig och bli en del av den svenska nationen. Vi har en
öppen svenskhet, en individ kan bli svensk oavsett bakgrund. Men det
kräver att de assimileras&amp;hellip;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Intressant sätt att definiera &amp;ldquo;öppen svenskhet&amp;rdquo; på. &amp;ldquo;Öppen&amp;rdquo; betyder
tydligen numera &amp;ldquo;öppen &lt;span style=&#34;font-size: 0.6em&#34;&gt;(med
begränsningar, på SD:s villkor)&lt;/span&gt;&amp;rdquo;. Att ens kalla det för
&amp;ldquo;öppenhet&amp;rdquo; känns bara som ett sätt att försöka måla över deras vanliga
politik med ett positivt ord.&lt;/p&gt;

&lt;p&gt;Och anpassa sig till vilken grad? Räcker det med att lära sig svenska?
Och vilken nivå av svenska ska folk behöva lära sig i så fall? Ska vi
kanske tvinga alla att konvertera till kristendom också? För säkerhets
skull borde vi nog även lagstifta om sill och nubbe på midsommar. För
allt som är främmande är ju obehagligt och förmodligen även
farligt.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:d4e5ccbb7b9dbe033da9808fa7a7debc:sarcasm&#34;&gt;&lt;a rel=&#34;footnote&#34; href=&#34;#fn:d4e5ccbb7b9dbe033da9808fa7a7debc:sarcasm&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr /&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:d4e5ccbb7b9dbe033da9808fa7a7debc:sarcasm&#34;&gt;Ja, det där var sarkasm.
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:d4e5ccbb7b9dbe033da9808fa7a7debc:sarcasm&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Rust Skåne Meetup</title>
      <link>//erj.me/post/rust-skane-meetup/</link>
      <pubDate>Mon, 17 Nov 2014 18:48:11 +0000</pubDate>
      
      <guid>//erj.me/post/rust-skane-meetup/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m on my way home from tonight&amp;rsquo;s Rust Skåne meetup in Malmö. There were
two presentations, one by Jakub Bukaj about Rust&amp;rsquo;s road to version 1.0
and one by Jens Nockert which dug into the worker queue implementation
in Servo.  Jakub&amp;rsquo;s presentation contained a lot of good information but
was unfortunately a bit time constrained. Jens&amp;rsquo; presentation was a bit
more free-form, he basically highlighted different parts of the file
implementing Servo&amp;rsquo;s work queue. It&amp;rsquo;s interesting to see some real world
Rust code with comments from someone who actually understands it.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m exited about Rust&amp;rsquo;s future development, it borrows a lot of great
features from e.g. Haskell and has some innovative ideas itself. I will
try to make time for some Rust development in the near future.&lt;/p&gt;

&lt;p&gt;Usually presentations at FooCafé (where the meetup took place) end up on
YouTube so keep an eye at &lt;a href=&#34;https://www.youtube.com/user/FooCafe&#34;&gt;FooCafé&amp;rsquo;s YouTube
channel&lt;/a&gt; if you&amp;rsquo;re interested.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Writing Regularly</title>
      <link>//erj.me/post/writing-more-often/</link>
      <pubDate>Tue, 04 Nov 2014 21:19:50 +0000</pubDate>
      
      <guid>//erj.me/post/writing-more-often/</guid>
      <description>&lt;p&gt;I have been wanting to get into the habit of writing more often, mostly
just to improve my own writing (since I doubt anyone would read what I
write anyway). I also have some ideas about writing some form of fiction
but that will probably not happen in the near future (if at all).&lt;/p&gt;

&lt;p&gt;I will basically follow the same rules that Gina Trapani&amp;rsquo;s post about
&lt;a href=&#34;http://scribbling.net/2014/10/16/short-form-blogging/&#34;&gt;short-form
blogging&lt;/a&gt; laid
out. I might add to those rules later if I actually do keep this habit
up (I know myself and I try to be realistic).&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Reply to Humans Need Not Apply by CGP Grey</title>
      <link>//erj.me/post/reply-to-humans-need-not-apply-by-cgp-grey/</link>
      <pubDate>Mon, 03 Nov 2014 19:11:39 +0000</pubDate>
      
      <guid>//erj.me/post/reply-to-humans-need-not-apply-by-cgp-grey/</guid>
      <description>

&lt;p&gt;I recently watched CGP Grey&amp;rsquo;s video titled &lt;a href=&#34;https://www.youtube.com/watch?v=7Pq-S557XQU&#34;&gt;Humans Need Not
Apply&lt;/a&gt; and I have some
nitpicking to do. While I agree with his general premise, robots will
take over more and more jobs and as a society we need to discuss the
consequences of this, I disagree on some specific points about the
robots he mentions. Particularly about self-driving cars (or autos as
Grey calls them, which I will adopt for this post).&lt;/p&gt;

&lt;h1 id=&#34;autos:abf796532c2e586198e79d28315c1705&#34;&gt;Autos&lt;/h1&gt;

&lt;p&gt;My main problem with the video is basically this: Watching the part
about self-driving cars makes it seem like they are basically done and
are waiting for legislative approval before going into mass production
(I might exaggerate slightly for dramatic effect). &lt;strong&gt;This is far from
true&lt;/strong&gt;. Let&amp;rsquo;s look at some quotes from the video.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Self-driving cars aren&amp;rsquo;t the future, they&amp;rsquo;re here and they work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, yes and no. Quite a few prototypes exists and it depends on your
definition of &amp;ldquo;work&amp;rdquo;. I&amp;rsquo;ll get back to this.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Self-driving cars have traveled hundreds of thousands of miles up and
down the California coast and through cities, all without human
intervention.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ah! Well I guess that&amp;rsquo;s technically true: There is no human intervention
&lt;em&gt;while&lt;/em&gt; they are driving. However, there is quite a lot of human
intervention before they drive (and I&amp;rsquo;m not just talking about
programming them). The problem with all of the existing autos being
developed right now can be summed up in two words: No SLAM.&lt;/p&gt;

&lt;p&gt;SLAM stands for &lt;a href=&#34;http://en.wikipedia.org/wiki/Simultaneous_localization_and_mapping&#34;&gt;Simultaneous Localization and
Mapping&lt;/a&gt;
which basically means that a robot (or auto in this case) starts with an
unknown environment and via sensors construct a map of the place while
simultaneously keeping track of its location in it. Few (if any, I
couldn&amp;rsquo;t find any when searching) self-driving cars currently do this.&lt;/p&gt;

&lt;p&gt;Take Google&amp;rsquo;s self-driving car project for example, it cannot navigate
on its own without a human first having driven the same route and built
a map of the area. And a Google Maps map is not sufficient. The map
basically needs to contain much of the same information as the auto has
access to while driving. This essentially means that a human must drive
the auto (or a vehicle with similar sensors) once initially to create
the map before it can do any navigation of its own.&lt;/p&gt;

&lt;p&gt;The astute reader will probably have realized the consequence of this:
In order for these autos to succeed in replacing human drivers,
essentially all roads will need to be mapped in this manner. This also
means that the maps has to be kept up to date continually. What if
intersections move?  If roads get built or shut down? While it is
possible for the auto to detect and cope with such problems when they
arise, they can for example make route planning sub-optimal.&lt;/p&gt;

&lt;p&gt;The alternative solution is SLAM, if autos could just draw a map and
localize themselves in it while driving, we wouldn&amp;rsquo;t need to hand them
prefabricated maps. The problem is that SLAM is a hard problem. And by
hard, I mean &lt;em&gt;hard&lt;/em&gt;. Like
people-have-been-cutting-their-teeth-on-this-problem-since-the-eighties-hard.
The Wikipedia page I linked to above has some details about what makes
it so difficult.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The question is not if they will replace cars but how quickly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nothing to argue against there. I agree it&amp;rsquo;s inevitable that autos will
replace cars eventually. What I basically disagree with is the timeline
I perceived from the video.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;They don&amp;rsquo;t need to be perfect, they just need to be better than us.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Again, I agree, but in order to even begin to replace human driven cars,
autos first need to master navigating in new environments at all.&lt;/p&gt;

&lt;h1 id=&#34;final-thoughts:abf796532c2e586198e79d28315c1705&#34;&gt;Final Thoughts&lt;/h1&gt;

&lt;p&gt;I&amp;rsquo;m not saying there isn&amp;rsquo;t some awesome research being done regarding
autos (because there is) and I would be the first person in line (budget
permitting) to buy one when they do get mass produced. I&amp;rsquo;m also not
complaining about Google&amp;rsquo;s research into self-driving cars. They had to
do some trade-offs in order for the project to move forward at all and I
can see why they chose to down-prioritize SLAM.&lt;/p&gt;

&lt;h1 id=&#34;tangential-side-note:abf796532c2e586198e79d28315c1705&#34;&gt;Tangential Side Note&lt;/h1&gt;

&lt;p&gt;I just wanted to point out that Baxter is a cool robot built on
&lt;a href=&#34;http://www.ros.org/&#34;&gt;ROS&lt;/a&gt; which I regularly work with in the robot lab
at Lund University. Without getting too technical, ROS provides lots of
ready-made functionality and communication primitives which allows you
to get started quickly when developing new robots.&lt;/p&gt;

&lt;p&gt;That said, there are some design issues with ROS that makes it more or
less impossible to use for critical real-time tasks, effectively
limiting what robots build on ROS can do. Unfortunately, this means that
much of the awesome functionality in ROS (such as geometry calculations,
localization, mapping etc.) can&amp;rsquo;t be used for more demanding tasks. Oh
well, can&amp;rsquo;t have it all.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>