<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>Hacker News Personal Blogs 2016 | Top 100 Blogs</title><link>https://hn-blogs.kronis.dev/feed-top100.xml</link><description>A collection of blog posts from users of Hacker News, based on RSS feeds.</description><language>en-US</language><lastBuildDate>Fri, 10 Jul 2026 04:03:21 GMT</lastBuildDate><generator>rfeed v1.1.1</generator><docs>https://github.com/svpino/rfeed/blob/master/README.md</docs><item><title>Walking through a basic Racket web service</title><link>http://notes.eatonphil.com/walking-through-a-basic-racket-web-service.html</link><description>&lt;p&gt;Racket is an impressive language and ecosystem. Compared to Python,
Racket (an evolution of Scheme &lt;a href="https://en.wikipedia.org/wiki/Scheme_(programming_language)"&gt;R5RS&lt;/a&gt; is three years younger. It is
as concise and expressive as Python but with much more reasonable
syntax and semantics. Racket is also faster in many cases due in part
to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.racket-lang.org/guide/performance.html#%28part._.J.I.T%29"&gt;JIT compilation&lt;/a&gt; on x86 platforms&lt;/li&gt;
&lt;li&gt;support for both
&lt;a href="https://docs.racket-lang.org/reference/threads.html"&gt;concurrency&lt;/a&gt; and &lt;a href="https://docs.racket-lang.org/reference/places.html"&gt;parallelism&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;support for &lt;a href="https://docs.racket-lang.org/ts-guide/optimization.html"&gt;optimizing&lt;/a&gt; statically-typed code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Furthermore, the built-in web server libraries &lt;strong&gt;and&lt;/strong&gt; database
drivers for MySQL and PostgreSQL are fully asynchronous. This last bit
drove me here from &lt;a href="https://www.playframework.com/documentation/2.6.x/ThreadPools#Knowing-when-you-are-blocking"&gt;Play / Akka&lt;/a&gt;.  (But strong reservations about
the complexity of Scala and the ugliness of Play in Java helped too.)&lt;/p&gt;
&lt;p&gt;With this motivation in mind, I'm going to break down the simple web
service &lt;a href="https://docs.racket-lang.org/web-server/stateless.html#%28part._stateless-example%29"&gt;example&lt;/a&gt; provided in the Racket manuals. If you don't see
the following code in the linked page immediately, scroll down a bit.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;lang&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/http&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;provide&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;interface-version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;stuffer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;interface-version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;'stateless&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;stuffer&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;stuffer-chain&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nv"&gt;serialize-stuffer&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;md5-stuffer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;build-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;find-system-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;'home-dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;.urls&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;response/xexpr&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;h2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Look ma, no state!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First we notice the #lang declaration. Racket libraries love to make
new "languages". These languages can include some entirely new syntax
(like the &lt;a href="http://docs.racket-lang.org/algol60/"&gt;Algol language implementation&lt;/a&gt;) or can simply include a
summary collection of libraries and alternative program entrypoints
(such as this web-server language provides). So the first thing we'll
do to really understand this code is to throw out the custom
language. And while we're at it, we'll throw out all typical imports
provided by the &lt;a href="http://docs.racket-lang.org/reference/"&gt;default racket language&lt;/a&gt; and use the racket/base
language instead. This will help us get a better understanding of the
Racket libraries and the functions we're using from these libraries.&lt;/p&gt;
&lt;p&gt;While we're throwing the language away, we notice the paragraphs just
below that &lt;a href="https://docs.racket-lang.org/web-server/stateless.html#%28part._stateless-example%29"&gt;original example&lt;/a&gt; in the manual. It mentions that the
web-server language also imports a bunch of modules. We can discover
which of these modules we actually need by searching in the Racket
manual for functions we've used.  For instance, &lt;a href="https://docs.racket-lang.org/search/index.html?q=response%2Fxexpr"&gt;searching&lt;/a&gt; for
"response/xexpr" tells us it's in the &lt;a href="https://docs.racket-lang.org/web-server/http.html#%28part._xexpr%29"&gt;web-server/http/xexpr&lt;/a&gt;
module. We'll import the modules we need using the "prefix-in" form to
make function-module connections explicit.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;lang&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;racket/base&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;xexpr:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/http/xexpr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;hash:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/stuffers/hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;stuffer:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/stuffers/stuffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;serialize:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/stuffers/serialize&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;provide&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;interface-version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;stuffer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;interface-version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;'stateless&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;stuffer&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;stuffer:stuffer-chain&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nv"&gt;serialize:serialize-stuffer&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hash:md5-stuffer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;build-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;find-system-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;'home-dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;.urls&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;xexpr:response/xexpr&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;h2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Look ma, no state!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we've got something that is a little less magical. We can run this
file by calling it: "racket server.rkt". But nothing happens. This is
because the web-server language would start the service itself using
the exported variables we provided. So we're going to have to figure
out what underlying function calls "start" and call it
ourselves. Unfortunately searching for "start" in the manual search
field yields nothing relevant. So we Google "racket web server
start". Down the page on the second &lt;a href="https://docs.racket-lang.org/web-server/run.html"&gt;search result&lt;/a&gt; we notice an
&lt;a href="https://docs.racket-lang.org/web-server/run.html#%28part._.Examples%29"&gt;example&lt;/a&gt; using the serve/servlet function to register the start
function.  This is our in.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;lang&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;racket/base&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;xexpr:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/http/xexpr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;hash:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/stuffers/hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;stuffer:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/stuffers/stuffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;serialize:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/stuffers/serialize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;servlet-env:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/servlet-env&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;provide&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;interface-version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;stuffer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;interface-version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;'stateless&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;stuffer&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;stuffer:stuffer-chain&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nv"&gt;serialize:serialize-stuffer&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hash:md5-stuffer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;build-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;find-system-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;'home-dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;.urls&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;xexpr:response/xexpr&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;h2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Look ma, no state!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;servlet-env:serve/servlet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run this version and it works! We are directed to a browser with our
HTML.  But we should clean this code up a bit. We no longer need to
export anything so we'll drop the provide line. We aren't even using
the interface-version and stuffer code. Things seem to be fine without
them, so we'll drop those too.  Also, looking at the serve/servlet
&lt;a href="https://docs.racket-lang.org/web-server/run.html#%28def._%28%28lib._web-server%2Fservlet-env..rkt%29._serve%2Fservlet%29%29"&gt;documentation&lt;/a&gt; we notice some other nice arguments we can tack
on.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;lang&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;racket/base&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;xexpr:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/http/xexpr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;servlet-env:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/servlet-env&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;xexpr:response/xexpr&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;h2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Look ma, no state!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;servlet-env:serve/servlet&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:servlet-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:servlet-regexp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;rx&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:stateless?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;#t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ah, that's much cleaner. When you run this code, you will no longer be
directed to the /servlets/standalone.rkt path but to the site root --
set by the #:servlet-path optional variable. Also, every other path
you try to reach such as /foobar will successfully map to the start
function -- set by the #:servlet-regexp optional variable. Finally, we
also found the configuration to set the servlet stateless -- set by
the optional variable #:stateless?.&lt;/p&gt;
&lt;p&gt;But this is missing two things we could really use out of a simple web
service. The first is routing. We do that by looking up the
documentation for the &lt;a href="https://docs.racket-lang.org/web-server/dispatch.html"&gt;web-server/dispatch&lt;/a&gt; module. We'll use this
module to define some routes -- adding a 404 route to demonstrate the
usage.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;lang&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;racket/base&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dispatch:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/dispatch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;xexpr:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/http/xexpr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;servlet:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/servlet-env&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;not-found-route&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;xexpr:response/xexpr&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;h2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Uh-oh! Page not found.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;home-route&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;xexpr:response/xexpr&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;h2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Look ma, no state!!!!!!!!!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define-values&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;route-dispatch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;route-url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dispatch:dispatch-rules&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;home-route&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;not-found-route&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;servlet:serve/servlet&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;route-dispatch&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:servlet-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:servlet-regexp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;rx&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:stateless?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;#t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run this version and check out the server root. Then try any other
path. Looks good.  The final missing piece to this simple web service
is logging. Thankfully, the &lt;a href="https://docs.racket-lang.org/web-server-internal/dispatch-log.html"&gt;web-server/dispatch-log&lt;/a&gt; module has
us covered with some request formatting functions. So we'll wrap the
route-dispatch function and we'll print out the formatted request.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;lang&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;racket/base&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dispatch:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/dispatch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dispatch-log:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/dispatchers/dispatch-log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;xexpr:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/http/xexpr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prefix-in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;servlet:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;web-server/servlet-env&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;not-found-route&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;xexpr:response/xexpr&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;h2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Uh-oh! Page not found.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;home-route&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;xexpr:response/xexpr&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;h2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Look ma, no state!!!!!!!!!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define-values&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;route-dispatch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;route-url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dispatch:dispatch-rules&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;home-route&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;not-found-route&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;route-dispatch/log-middleware&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;display&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dispatch-log:apache-default-format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;req&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;flush-output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;route-dispatch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;req&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;servlet:serve/servlet&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;route-dispatch/log-middleware&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:servlet-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:servlet-regexp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;rx&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:stateless?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;#t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run this version and notice the logs displayed for each request. Now
you've got a simple web service with routing and logging!  I hope this
gives you a taste for how easy it is to build simple web services in
Racket without downloading any third-party libraries. Database drivers
and HTML template libraries are also included and similarly
well-documented. In the future I hope to add an example of a slightly
more advanced web service.&lt;/p&gt;
&lt;p class="note"&gt;
  I have had huge difficulty discovering the source of Racket
  libraries.  These library sources are nearly impossible to Google
  and search on Github is insane.  Best scenario, the official
  racket.org docs would link directly to the source of a function when
  the function is documented. Of course I could just download the
  Racket source and start grepping... but I'm only so interested.
&lt;/p&gt;&lt;p&gt;&lt;blockquote class="twitter-tweet"&gt;&lt;p dir="ltr" lang="en"&gt;Walking through a basic Racket web service &lt;a href="https://t.co/J3us48kzga"&gt;https://t.co/J3us48kzga&lt;/a&gt; &lt;a href="https://twitter.com/racketlang?ref_src=twsrc%5Etfw"&gt;@racketlang&lt;/a&gt;&lt;/p&gt;&amp;mdash; Phil Eaton (@phil_eaton) &lt;a href="https://twitter.com/phil_eaton/status/814674473681121280?ref_src=twsrc%5Etfw"&gt;December 30, 2016&lt;/a&gt;&lt;/blockquote&gt; &lt;/p&gt;</description><author>Notes on software development</author><pubDate>Thu, 29 Dec 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">http://notes.eatonphil.com/walking-through-a-basic-racket-web-service.html</guid></item><item><title>Falsehoods Programmers Believe About CSVs</title><link>https://donatstudios.com/Falsehoods-Programmers-Believe-About-CSVs</link><description>&lt;p&gt;Much of my professional work for the last 10+ years has revolved around handling, importing and exporting CSV files. CSV files are frustratingly misunderstood, abused, and most of all underspecified. While &lt;a href="https://tools.ietf.org/html/rfc4180" title="RFC4180 Common Format and MIME Type for Comma-Separated Values (CSV) Files"&gt;RFC4180&lt;/a&gt; exists, it is far from definitive and goes largely ignored.&lt;/p&gt;
&lt;p&gt;Partially as a companion piece to my recent post about how CSV is an &lt;a href="https://donatstudios.com/CSV-An-Encoding-Nightmare"&gt;encoding nightmare&lt;/a&gt;, and partially an expression of frustration, I've decided to make a list of falsehoods programmers believe about CSVs. I recommend my previous post for a more in-depth coverage on the pains of CSVs encodings and how the default tooling (Excel) will ruin your day.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Everything on this list is a false assumption&lt;/strong&gt; that developers make.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;All CSVs are ASCII&lt;/li&gt;
&lt;li&gt;All CSVs are Win1252&lt;/li&gt;
&lt;li&gt;All CSVs are in 8-bit encodings&lt;/li&gt;
&lt;li&gt;All CSVs are UTF-8&lt;/li&gt;
&lt;li&gt;All CSVs are UTF-16&lt;/li&gt;
&lt;li&gt;All CSVs contains a single consistent encoding&lt;/li&gt;
&lt;li&gt;All records contain a single consistent encoding&lt;/li&gt;
&lt;li&gt;All fields contain a single consistent encoding&lt;/li&gt;
&lt;li&gt;All CSVs contain records&lt;/li&gt;
&lt;li&gt;All records contain fields &lt;/li&gt;
&lt;li&gt;Fields never contain record separators &lt;/li&gt;
&lt;li&gt;Fields never contain delimiters &lt;/li&gt;
&lt;li&gt;Fields never contain control characters&lt;/li&gt;
&lt;li&gt;Delimiters are escaped with a &lt;code&gt;\&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;All fields are enclosed by double quotes&lt;/li&gt;
&lt;li&gt;All records are a single line&lt;/li&gt;
&lt;li&gt;All lines contain a single record&lt;/li&gt;
&lt;li&gt;All records contain the same number of fields&lt;/li&gt;
&lt;li&gt;All records contain the same number of fields as the header&lt;/li&gt;
&lt;li&gt;All records contain the same number of fields or fewer than the header&lt;/li&gt;
&lt;li&gt;All CSVs contain a header&lt;/li&gt;
&lt;li&gt;All record separators are CRLF&lt;/li&gt;
&lt;li&gt;All record separators are LF&lt;/li&gt;
&lt;li&gt;All record separators are a single byte&lt;/li&gt;
&lt;li&gt;All record separators are a single rune&lt;/li&gt;
&lt;li&gt;All newlines are a single byte&lt;/li&gt;
&lt;li&gt;All CSVs are delimited with a comma&lt;/li&gt;
&lt;li&gt;All CSVs are delimited with a comma, tab or semicolon&lt;/li&gt;
&lt;li&gt;TSV isn't CSV&lt;/li&gt;
&lt;li&gt;All delimiters are a single byte&lt;/li&gt;
&lt;li&gt;All commas are a single byte&lt;/li&gt;
&lt;li&gt;All CSVs are readable with Excel&lt;/li&gt;
&lt;li&gt;Excel is a good tool for working with CSVs&lt;/li&gt;
&lt;li&gt;Excel is an OK tool for working with CSVs&lt;/li&gt;
&lt;li&gt;Excel can losslessly save CSVs it opens&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;="{value}"&lt;/code&gt; is a &lt;em&gt;good&lt;/em&gt; way to get around Excel auto-formatting&lt;/li&gt;
&lt;li&gt;The first line will never be a poorly supported instruction header&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;sep={char}&lt;/code&gt; is a &lt;em&gt;good&lt;/em&gt; way to get Excel to accept your delimiter&lt;/li&gt;
&lt;li&gt;Prepending a BOM is a good way to get Excel to read your encoding&lt;/li&gt;
&lt;li&gt;You can safely name your first column &amp;quot;ID&amp;quot;&lt;/li&gt;
&lt;li&gt;All CSVs follow &lt;a href="https://tools.ietf.org/html/rfc4180" title="RFC4180 Common Format and MIME Type for Comma-Separated Values (CSV) Files"&gt;RFC4180&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Most CSVs follow &lt;a href="https://tools.ietf.org/html/rfc4180" title="RFC4180 Common Format and MIME Type for Comma-Separated Values (CSV) Files"&gt;RFC4180&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;All CSVs follow the same defined standard&lt;/li&gt;
&lt;li&gt;All CSVs follow a defined standard&lt;/li&gt;
&lt;li&gt;All CSVs have a &lt;code&gt;.csv&lt;/code&gt; extension&lt;/li&gt;
&lt;li&gt;All CSV is human readable&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Please take these into consideration next time you find yourself working with CSV. If you can think of anything I may have missed I'd be happy to add it.&lt;/p&gt;
&lt;p&gt;As a suggested further reading, &amp;quot;The Art of Unix Programming&amp;quot; &lt;a href="https://www.catb.org/esr/writings/taoup/html/ch05s02.html#id2901882"&gt;http://www.catb.org/esr/writings/taoup/html/ch05s02.html#id2901882&lt;/a&gt; section on DSV style which notably says &amp;quot;CSV is a textbook example of how not to design a textual file format&amp;quot;&lt;/p&gt;
&lt;h4&gt;Updates:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Thanks to &lt;a href="https://donatstudios.com/Falsehoods-Programmers-Believe-About-CSVs#Comment216545"&gt;Max&lt;/a&gt; for pointing out the Excel supported &lt;code&gt;sep={value}&lt;/code&gt; header I was strangely entirely unaware of.&lt;/li&gt;
&lt;li&gt;Thanks to &lt;a href="https://donatstudios.com/Falsehoods-Programmers-Believe-About-CSVs#Comment216547"&gt;Don Hopkins&lt;/a&gt; for the note about not being able to start a header with ID&lt;/li&gt;
&lt;/ul&gt;</description><author>Donat Studios</author><pubDate>Wed, 28 Dec 2016 03:41:04 GMT</pubDate><guid isPermaLink="true">https://donatstudios.com/Falsehoods-Programmers-Believe-About-CSVs</guid></item><item><title>Vertically striping images for fun</title><link>https://rjp.is/blogging/posts/vertically-striping-images-for-comparison-2/</link><description>In which we create a montage.</description><author>infrequent oscillations</author><pubDate>Sat, 24 Dec 2016 10:46:10 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/vertically-striping-images-for-comparison-2/</guid></item><item><title>MH-Z19 CO2 sensor reader, logger and visualiser</title><link>https://smcleod.net/2016/12/mh-z19-co2-sensor-reader-logger-and-visualiser/</link><description>&lt;!-- markdownlint-disable MD025 --&gt;
&lt;h1 id="mh-z19-co2-sensor-reader-logger-and-visualiser"&gt;MH-Z19 CO2 sensor reader, logger and visualiser&lt;/h1&gt;
&lt;p&gt;&lt;img alt="plot" src="https://user-images.githubusercontent.com/862951/52826593-a98a5400-3115-11e9-868a-72a763b6d587.jpg" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reads data from UART(serial)-connected MH-Z19 (or MH-Z14) sensor using python 3.&lt;/li&gt;
&lt;li&gt;If you dare to install nodejs you can visualise the logged data (using html and plotly.js library).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Repository: &lt;a href="https://github.com/sammcj/CO2-Logger"&gt;sammcj/CO2-Logger&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="usage"&gt;Usage&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Note this post is from 2016, in 2021 I replaced my custom Co2 loggers with an &lt;a href="https://aranet.com/products/aranet4/"&gt;Aranet4&lt;/a&gt;. While very expensive, is and excellent off-the-shelf solution, with many features.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="connection"&gt;Connection&lt;/h3&gt;
&lt;p&gt;Sensor can be queried using 3.3v UART at 9600 bps. Sensor main feed voltage is 5v.&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Wed, 21 Dec 2016 07:37:38 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2016/12/mh-z19-co2-sensor-reader-logger-and-visualiser/</guid></item><item><title>Annoying CSV and the JSON solution</title><link>https://rjp.is/blogging/posts/annoying-csv-and-the-json-solution-2/</link><description>In which we skirt a CSV problem by using JSON.</description><author>infrequent oscillations</author><pubDate>Wed, 07 Dec 2016 00:44:30 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/annoying-csv-and-the-json-solution-2/</guid></item><item><title>Belated ElixirConf 2016 Recap</title><link>https://www.brightball.com/articles/belated-elixirconf-2016-recap</link><description>This past September I took vacation time and paid out of pocket to drive to Orlando and attend ElixirConf with a few other programmers from Greenville who did the same thing. We weren't the only ones. Here is a belated recap from our combined notes and experiences.</description><author>Brightball Articles</author><pubDate>Wed, 30 Nov 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://www.brightball.com/articles/belated-elixirconf-2016-recap</guid></item><item><title>Vignettes</title><link>https://rjp.is/blogging/posts/vignettes-2/</link><description>In which we summarise through subtitles.</description><author>infrequent oscillations</author><pubDate>Tue, 29 Nov 2016 15:11:20 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/vignettes-2/</guid></item><item><title>Repeating History...on Purpose...with Elixir</title><link>https://www.brightball.com/articles/repeating-history-on-purpose-with-elixir</link><description>A dive into the highlights of Elixir that make it the ideal platform for the web...and how all these questions were answered figured out 30 years ago. Presented to Upstate Elixir in Greenville, SC on Nov 16.</description><author>Brightball Articles</author><pubDate>Tue, 29 Nov 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://www.brightball.com/articles/repeating-history-on-purpose-with-elixir</guid></item><item><title>The many methods of Decim8</title><link>https://rjp.is/blogging/posts/the-many-methods-of-decim8-2/</link><description>In which we try to provide a visual reference for Decim8.</description><author>infrequent oscillations</author><pubDate>Fri, 25 Nov 2016 19:16:51 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/the-many-methods-of-decim8-2/</guid></item><item><title>Syncing from Postgres to Salesforce - Data Mappings</title><link>/2016/11/23/syncing-from-postgres-to-salesforce-part-1/</link><description>&lt;p&gt;For the second time now I&amp;rsquo;ve had to implement a system that syncs from my system of record into Salesforce.com, the first at Heroku and now at &lt;a href="https://www.citusdata.com"&gt;Citus Data&lt;/a&gt;. The case here is pretty simple, I have a software-as-a-service, B2B product. It&amp;rsquo;s a homegrown application in these cases in Ruby, but could be Python, .Net, any language of your choosing. The problem is I don&amp;rsquo;t want to have to be rebuilding my own CRM, reporting, etc. on top of all of my internal database. And as soon as you&amp;rsquo;re at some reasonable size (sales guy of 1 or more) you need to be able to provide insights on what&amp;rsquo;s in that system of record database to others.&lt;/p&gt;
&lt;p&gt;While my tooling isn&amp;rsquo;t a full fledged product by any means, here&amp;rsquo;s a bit of how I&amp;rsquo;ve developed this process a few times over and some of the annoying bits of code to help get you started. In this post I&amp;rsquo;ll walk through some of the basic datatypes, then we&amp;rsquo;ll follow-up with the overall architecture and tweaks you need to make to Salesforce, and finally we&amp;rsquo;ll provide some example code to help you create this setup yourself.&lt;/p&gt;
&lt;h3 id="leads-contacts-accounts-oh-my"&gt;
&lt;div&gt;
Leads, Contacts, Accounts oh my
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Despite being some of the largest as-a-service vendors in the world, Salesforce is still primarily setup for traditional high touch sales. What this means is some of the data you&amp;rsquo;ll commonly have, or in this case not have, can make it difficult to figure out what maps from your internal system to Salesforce. Within Salesforce there&amp;rsquo;s really 4 key data models you&amp;rsquo;re going to care about.&lt;/p&gt;
&lt;h3 id="lead-vs-contact"&gt;
&lt;div&gt;
Lead vs. Contact
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;In every as a service product you&amp;rsquo;ll have some user that creates and account which usually has an email address tied to it. This seems simple enough to load up to Salesforce as there is a clear email field. Within Salesforce there are two key data types which have a default field for this lead and contact, in Salesforce terms a lead is someone &lt;a href="https://success.salesforce.com/answers?id=90630000000gvTiAAI"&gt;considering doing business with you&lt;/a&gt;, a contact someone who more so is doing business with you. If you have a freemium or timed trial model you might think to start classifying everyone that they&amp;rsquo;re a lead. Then, when they convert to a paying customer you turn them into a contact.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re anything like me, in running your SaaS business, you want a sign-up process that&amp;rsquo;s frictionless. This means give me an email address, password, and you&amp;rsquo;re off and running. Salesforce immediately starts to breakdown a bit in this regard. First you&amp;rsquo;re required for both lead and contact to provide a first and last name. In my case I do ask for name, and do a little bit of work on the code side to get values into both. You&amp;rsquo;ll see later that our process does result in some regular cleanup work needing to happen, but in our case we&amp;rsquo;re optimizing to get them signed up more than capturing every detail perfectly about them from the start.&lt;/p&gt;
&lt;p&gt;Leads are even more broken than contacts though. Leads require you to enter a company. While you may be able to just drop a company form field onto your sign-up page you&amp;rsquo;re likely to end up with junk data at least, if not actually driving some sign-ups away. Some of my favorite pieces of junk data I&amp;rsquo;ve seen users enter for company name: &amp;ldquo;pissed off developer&amp;rdquo;, &amp;ldquo;Acme Inc.&amp;rdquo;, and the all too common &amp;ldquo;Test Co.&amp;rdquo;. In reality these are often real developers, with real problems, and real budget, they just don&amp;rsquo;t want to share details before they&amp;rsquo;re ready.&lt;/p&gt;
&lt;p&gt;So in this case the TLDR; is that leads require:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First name&lt;/li&gt;
&lt;li&gt;Last name&lt;/li&gt;
&lt;li&gt;Email&lt;/li&gt;
&lt;li&gt;Company name&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This results in contacts being a more favorable datatype because it only requires:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First name&lt;/li&gt;
&lt;li&gt;Last name&lt;/li&gt;
&lt;li&gt;Email&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="accounts-vs-opportunities"&gt;
&lt;div&gt;
Accounts vs. Opportunities
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;We have in some ways a similar but different dichotomy with Accounts and Opportunities as we did Leads and Contacts. Though this one can often map a bit more cleanly than we saw with leads. From a &lt;a href="https://success.salesforce.com/answers?id=90630000000gnvcAAA"&gt;pretty straight forward definition&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Account - A business entity. Contacts work for Accounts.&lt;/li&gt;
&lt;li&gt;Opportunities - Sales events related to an Account and one or more Contacts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This again can become problematic if you have no notion of Accounts at all in your system of record. Though if you are building a B2B application there is a good chance you may have something that makes sense. If you let uses free-form enter this instead of AT&amp;amp;T they may put &amp;ldquo;interactive team&amp;rdquo;, but you at least have some logical team that in their mind they roll up to.&lt;/p&gt;
&lt;p&gt;Opportunities is a much harder one in the SaaS world. In traditional marketing you have your standard stages of MQL (Marketing Qualified Lead), progressing to SQL (Sales Qualified Lead), etc. that you expect these potential customers to flow through. In the as-a-service world you may have people look from afar for weeks, then suddenly sign-up and give you a credit card and start paying within minutes. While there is still steps the customer may go through before buying you often have less insight into these. How you decide to structure your opportunities flow is entirely up to you. In my case I tend to opt to still have htem, but they&amp;rsquo;re an exception basis where a salesperson is actively engaged vs. the other 90%+ of fully self-service customers.&lt;/p&gt;
&lt;p&gt;Shifting back a little bit on accounts. The key with accounts is that if you have some notion of an team or org within your system of record then it makes sense to have that same structure setup in Salesforce. The most basic of this might be an idea of &amp;ldquo;Account owner&amp;rdquo; and &amp;ldquo;Team members&amp;rdquo;. You may have a person in there just for billing, an admin, and then users. Even if you don&amp;rsquo;t want to recreate the entire structure at least having all the contacts tied to the account is critical. I can&amp;rsquo;t count the number of times I&amp;rsquo;ve seen teams setup a &amp;ldquo;&lt;a href="mailto:billing@mycompany.com"&gt;billing@mycompany.com&lt;/a&gt;&amp;rdquo; email, seen people try to interact with that email when in reality they wanted to be talking to &amp;ldquo;&lt;a href="mailto:jane@mycompany.com"&gt;jane@mycompany.com&lt;/a&gt;&amp;rdquo; who logged in yesterday.&lt;/p&gt;
&lt;h3 id="in-summary"&gt;
&lt;div&gt;
In summary
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;For the most part Salesforce doesn&amp;rsquo;t quite let you map to what many of you&amp;rsquo;ll want to do in terms of mapping your data from your system of record to Salesforce. Expect to have to contort a bit and likely pump Salesforce with some garbage data. In general you&amp;rsquo;ll want to skip leads and go straight for contacts as contacts don&amp;rsquo;t require the same restrictions. Tying contacts to an account is the right level anyway, and from there up to you on how you&amp;rsquo;ll more manage the opportunities.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Wed, 23 Nov 2016 22:55:56 GMT</pubDate><guid isPermaLink="true">/2016/11/23/syncing-from-postgres-to-salesforce-part-1/</guid></item><item><title>From Developer to DevOps: My Story</title><link>https://benovermyer.com/blog/2016/11/from-developer-to-devops-my-story/</link><description>&lt;p&gt;In late 2014, the sole system administrator for the Star Tribune Digital department (let's call him John) turned in his two-weeks' notice. Thus began a panic as we realized we had no idea how our infrastructure worked. At the time, I was one of two senior software engineers there. I was in the middle of a large refactoring project for the mobile website. John had, thankfully, kept up an internal wiki that at least roughly documented how some of the legacy infrastructure worked. The new infra on AWS was very new and very undocumented, but at least we had a place to start. John's disciple, an eager but more junior developer who had originated as a copy-editor, did what he could to absorb as much knowledge as he could from John before he left. But his heart just wasn't in operations, and he didn't want to fall on that sword.&lt;/p&gt;
&lt;p&gt;In a one-on-one with my boss, we talked about the dilemma facing us. I mentioned that I had some experience with Linux in production environments. He gently suggested that I take on the system administration role, at least until they could hire someone to replace John. I blanched, knowing enough to know that I knew little about the world of operations. I was reluctant, but in the end he convinced me to at least try and hold down the fort until help arrived. I set the condition that I be immediately removed from all development projects I was assigned to. My boss agreed. At this point, we were about six months from launch of a scratch-built web platform that would replace our proprietary hosted CMS. None of the developers had experience in operational concerns at that scale, including myself. John had written some Chef cookbooks to provision the few things living on the new infrastructure, but only an outside contractor brought in to help in the interim with operations actually knew Chef. We struggled for a short period of time to maintain it. I learned enough of Ruby and Chef to get by, but it was always a battle to get the tool to do what I expected whenever I needed to do something slightly different from the existing process.&lt;/p&gt;
&lt;p&gt;I forget who originally suggested it, but we started to switch our orchestration code to Ansible. Ansible was far easier for me to wrap my head around, and at a time when I needed to learn as much as possible as fast as possible, that was a lifesaver. At this point, I'd been “the operations guy” for about a month. The hiring ad for a “devops engineer” had been open for a month and a half. We had had only a few interested parties, and none of them were anything close to what we needed. I saw the writing on the wall, and asked my boss for a meeting. I told him I was willing to permanently become the operations engineer for the team. His relief was obvious. Shortly after that, the engineer opening changed from operations to developer, and within a short space of time we had an awesome new junior developer on the team. Meanwhile, I dove headlong into the world of system administration and operations. No longer held back by my own thought of “this is only temporary,” I devoured anything and everything I could find on the subject of what Google would later call Site Reliability Engineering.&lt;/p&gt;
&lt;p&gt;After a couple short months, all of the Chef code was gone, a lot of our infrastructure had been deployed onto AWS, and we had hired a junior operations engineer to help out. Our on-call rotation was still a manually-maintained forwarded phone line, though, and fighting fires was always a panic moment… since usually, it was a problem that had been happening for hours, and we didn't even know about it until someone from the news floor informed us. But that's a story for another time. It was the launch of our web platform that completely changed operations for us, and for me. In early May 2015, the new website launched. And immediately crashed. And stayed down. We reverted to the old CMS. The next ten days saw both development and operations working feverishly to try and figure out what had gone wrong and how to fix it.&lt;/p&gt;
&lt;p&gt;We switched from using a clever-but-misleading traffic simulation to using a tool called &lt;a href="https://www.joedog.org/siege-home/" rel="external"&gt;siege&lt;/a&gt; to do load testing, and finally got to a point where we thought we could keep the new site online. At 3:00 AM ten days after the first attempt, the new platform went online again and stayed online. For the next three hours, the launch team (including myself as the sole operations engineer on the team) built and deployed multiple iterations of the new site, and finally at six in the morning, we all left the office. I greeted the post-launch engineering team as we passed each other in the office entrance. After a couple hours' sleep in a downtown hotel, the launch team returned to the office to assess the situation and help out with any problems that might have occurred.&lt;/p&gt;
&lt;p&gt;Let me be clear. When I was a developer, I pulled my share of sixteen-hour days to meet deadlines. But I never before this launch had experienced a shift this long or this rewarding. Before then, I had never cheered and exchanged high fives with the team as we saw the site working as expected in the wee hours of the morning. At this point, I was invested in operations. It had acquired my interest and not just my attention.&lt;/p&gt;</description><author>Ben Overmyer's Site</author><pubDate>Sun, 20 Nov 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://benovermyer.com/blog/2016/11/from-developer-to-devops-my-story/</guid></item><item><title>Sphinx Real Time Index How to Distribute and Hidden Gotcha</title><link>https://boyter.org/2016/11/sphinx-real-time-index-distribute-hidden-gotcha/</link><description>&lt;p&gt;I have been working on real time indexes with Sphinx recently for the next version of searchcode.com and ran into a few things that were either difficult to search for or just not covered anywhere.&lt;/p&gt;
&lt;p&gt;The first is how to implement a distributed search using real time indexes. It&amp;rsquo;s actually done the same way you would normally create an index. Say you had a single server with 4 index shards on it and you wanted to run queries against it. You could use the following,&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Fri, 11 Nov 2016 11:34:42 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/11/sphinx-real-time-index-distribute-hidden-gotcha/</guid></item><item><title>Death's End</title><link>https://nindalf.com/posts/deaths-end/</link><description>Liu Cixin's Death's End is a special set of books that puts as much Science as it can in Science Fiction.</description><author>Krishna's blog</author><pubDate>Thu, 10 Nov 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/deaths-end/</guid></item><item><title>Don’t build cockpits, become a coach</title><link>https://bytepawn.com/data-science-coaching.html</link><description>&lt;p&gt;I used to think that a good analogy for using data is the instrumentation of a cockpit in an airliner. Lots of instruments, and if they fail, the pilot can’t fly the plane and bad things happen. There’s no autopilot for companies. The problem with this analogy is that planes aren’t built in mid-air. Product teams and companies constantly need to build and ship new products.&lt;br /&gt;&lt;br /&gt;&lt;img alt="A big complicated cockpit" src="/images/hosszu-shane.jpg" style="width: 400px;" /&gt;&lt;/p&gt;</description><author>Bytepawn - Marton Trencseni</author><pubDate>Wed, 09 Nov 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://bytepawn.com/data-science-coaching.html</guid></item><item><title>Noisevember 2016</title><link>https://rjp.is/blogging/posts/noisevember-2016-2/</link><description>Having singularly failed with all of Juneathon, Inktober and Blogtober, I shall be picking myself up, dusting myself down, and having another crack at Noisevember.</description><author>infrequent oscillations</author><pubDate>Mon, 31 Oct 2016 11:20:07 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/noisevember-2016-2/</guid></item><item><title>Explaining VarnishHist – What Does it Tell Us</title><link>https://boyter.org/2016/10/explaining-varnishhist/</link><description>&lt;p&gt;The varnishhist tool is one of the most underused varnish tools that come with your standard varnish install. Probably because of how it appears at first glance.&lt;/p&gt;
&lt;p&gt;In short, you want as many &lt;code&gt;|&lt;/code&gt; symbols as possible and you want everything far toward the left hand side. The closer to the left the faster the responses are regardless if they are cached or not. The more &lt;code&gt;|&lt;/code&gt; symbols then more items were served from cache.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Thu, 27 Oct 2016 02:56:01 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/10/explaining-varnishhist/</guid></item><item><title>MySQL Dump Without Impacting Queries</title><link>https://boyter.org/2016/10/mysql-dump-impacting-queries/</link><description>&lt;p&gt;Posted more for my personal use (I have to look it up every time) but here is how to run a mysqldump without impacting performance on the box. It sets the ionice and nice values to be as low as possible (but still run) and uses a single transaction and ups the max packet size for MySQL.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ionice -c2 -n7 nice -n19 mysqldump -u root -p DATABASE --single-transaction --max_allowed_packet=512M &amp;gt; FILENAME
&lt;/code&gt;&lt;/pre&gt;</description><author>Ben E. C. Boyter</author><pubDate>Wed, 26 Oct 2016 04:11:01 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/10/mysql-dump-impacting-queries/</guid></item><item><title>Open DNS for when DNS outages occur</title><link>/2016/10/21/opendns/</link><description>&lt;p&gt;Open DNS is a DNS resolver that caches records beyond their TTL if the upstream DNS server cannot be found. In cases like today&amp;rsquo;s major outage it can be handy to swap your DNS settings out for this, or it may be worth using as a standard default. Resolution may be a bit slow as it will try to see if the upstream server cannot be found, but it at least can get you back to a working state.&lt;/p&gt;
&lt;p&gt;If you know what you&amp;rsquo;re doing then all you need to do is configure your DNS settings to: &lt;code&gt;208.67.220.220&lt;/code&gt; and &lt;code&gt;208.67.222.222&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you need a little more guidance you can go into your System Preferences on Mac, select Network, then Advanced and finally the DNS tab. You should set it up to look as follows:&lt;/p&gt;
&lt;p&gt;&lt;img alt="DNS Configuration" src="https://d3vv6lp55qjaqc.cloudfront.net/items/0c2T1M251T0D3r1D2Q3x/Network.png?X-CloudApp-Visitor-Id=e4475d145dcf11ebcffabf840edcc11f&amp;amp;v=cd767ce0" /&gt;&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Fri, 21 Oct 2016 23:55:56 GMT</pubDate><guid isPermaLink="true">/2016/10/21/opendns/</guid></item><item><title>Embedded Linux Conference Europe 2016</title><link>https://anisse.astier.eu/embedded-linux-conference-europe-2016.html</link><description>&lt;p&gt;I was in Berlin last week for ELCE, and it was great. It was a nice mix of talks on many different subjects, and as always you come back with lots of new ideas and improved motivation.&lt;/p&gt;
&lt;p&gt;As you know, I took some notes for &lt;a href="kernel-recipes-2016-notes.html"&gt;Kernel Recipes 2016&lt;/a&gt;, and lots …&lt;/p&gt;</description><author>Linux Engineer's random thoughts</author><pubDate>Fri, 21 Oct 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://anisse.astier.eu/embedded-linux-conference-europe-2016.html</guid></item><item><title>Elixir ETS + Mnesia vs Redis</title><link>https://www.brightball.com/articles/elixir-ets-and-mnesia-vs-redis</link><description>Learning Elixir has a way of challenging everything you know about programming. Redis is becoming an assumed part of many web stacks, in the same breath as your database. But with Elixir, do you need it? Do you even need a database?</description><author>Brightball Articles</author><pubDate>Sun, 09 Oct 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://www.brightball.com/articles/elixir-ets-and-mnesia-vs-redis</guid></item><item><title>Blogtober 2016, #2</title><link>https://rjp.is/blogging/posts/blogtober-2016-2-2/</link><description>Today&amp;rsquo;s #inktober prompt was &amp;ldquo;NOISY&amp;rdquo;. Not a great effort but at least he looks human.
Also had a decent Cathedral win on BoI:A even though the very first item was Dr Fetus - made for some tense dodging and shimmying! Still haven&amp;rsquo;t managed a win streak of more than one but the loss streaks are slowly getting shorter&amp;hellip;</description><author>infrequent oscillations</author><pubDate>Sun, 02 Oct 2016 23:39:33 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/blogtober-2016-2-2/</guid></item><item><title>Blogtober 2016, #1</title><link>https://rjp.is/blogging/posts/blogtober-2016-1-2/</link><description>Made some musical output using a couple of samples taken from a Tidal performance by Alex (with permission) - &amp;ldquo;Deconstructing Yaxu&amp;rdquo;
Mostly just a droney throbby glitchy noisescape thrown together using Samplr in a coffee shop.
Also did day 1, &amp;ldquo;fast&amp;rdquo;, of #inktober.</description><author>infrequent oscillations</author><pubDate>Sun, 02 Oct 2016 00:53:43 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/blogtober-2016-1-2/</guid></item><item><title>Kernel Recipes 2016 notes</title><link>https://anisse.astier.eu/kernel-recipes-2016-notes.html</link><description>&lt;p&gt;&lt;strong&gt;Update 2016-10-21:&lt;/strong&gt; I've added links to the &lt;a href="https://www.youtube.com/playlist?list=PLQ8PmP_dnN7L5OVT95uXJAE78qcGCcDVm"&gt;videos&lt;/a&gt; and &lt;a href="https://lwn.net/Archives/ConferenceByYear/#2016-Kernel_Recipes"&gt;LWN articles&lt;/a&gt;, which are of much higher quality than these live notes.&lt;/p&gt;
&lt;p&gt;This year I'm trying a live blog of &lt;a href="http://kernel-recipes.org/"&gt;Kernel Recipes 2016&lt;/a&gt;, live from Paris, at Mozilla's headquarters. You can watch the &lt;a href="https://air.mozilla.org/kernel-recipes-2016-09-28-AM-Session/"&gt;live stream here&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;The kernel report&lt;/h1&gt;
&lt;p&gt;by Jonathan …&lt;/p&gt;</description><author>Linux Engineer's random thoughts</author><pubDate>Wed, 28 Sep 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://anisse.astier.eu/kernel-recipes-2016-notes.html</guid></item><item><title>A tour of Postgres' Foreign Data Wrappers</title><link>/2016/09/11/a-tour-of-fdws/</link><description>&lt;p&gt;SQL can be a powerful language for reporting. Whether you&amp;rsquo;re just exploring some data, or generating reports that show &lt;a href="/2014/02/26/Tracking-MoM-growth-in-SQL/"&gt;month over month revenue growth&lt;/a&gt; it&amp;rsquo;s the &lt;a href="https://www.amazon.com/SQL-Relational-Theory-Write-Accurate/dp/1491941170/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1473612603&amp;amp;sr=1-1&amp;amp;keywords=sql+relational&amp;amp;tag=mypred-20"&gt;lingua franca&lt;/a&gt; for data analysis. But, your data isn&amp;rsquo;t always in a SQL database, even then if you&amp;rsquo;re using Postgres you can still likely use SQL to analyze, query, even joing with that data. Foreign data wrappers have been around for years in Postgres, but are continuing to mature and be a great option for joining disparate systems.&lt;/p&gt;
&lt;h3 id="overview-of-foreign-data-wrappers"&gt;
&lt;div&gt;
Overview of foreign data wrappers
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;re unfamiliar, foreign data wrappers, or FDW, allow you to connect from within Postgres to a remote system. Then you can query them from directly within Postgres. While there is an official Postgres FDW that ships with Postgres itself, that allows you to connect from one Postgres DB to another, there&amp;rsquo;s also a broad community of others.&lt;/p&gt;
&lt;p&gt;At the core of it Postgres provides certain APIs under the covers which each FDW extension can implement. This can include the ability to map SQL to whatever makes sense for a given system, push down various operators like where clauses, and as of Postgres 9.3 can even write data.&lt;/p&gt;
&lt;p&gt;To setup a FDW you first would install the extension, then provide the connection to the remote system, setup your schema/tables, and then you&amp;rsquo;re off to the races–or well ready to query. If you&amp;rsquo;ve got more than 2-3 databases or systems in your infrastructure, you&amp;rsquo;ll often benefit from FDWs as opposed to introducing a heavyweight ETL pipeline. Don&amp;rsquo;t mistake FDWs as the most performant method for joining data, but they are often the developer time efficient means of joining these data sets.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at just a few of the more popular and interesting ones.&lt;/p&gt;
&lt;h3 id="postgres-fdw"&gt;
&lt;div&gt;
Postgres FDW
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;The Postgres one is the easiest to get started with. First you&amp;rsquo;ll just enable it with &lt;code&gt;CREATE EXTENSION&lt;/code&gt;, then you&amp;rsquo;ll setup your remote server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE EXTENSION postgres_fdw;
CREATE SERVER core_db
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'foo', dbname 'core_db', port '5432');
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you&amp;rsquo;ll create the user that has access to that database:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE USER MAPPING FOR bi SERVER core OPTIONS (user 'bi', password 'secret');
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, create your foreign table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE FOREIGN TABLE core_users (
id integer NOT NULL,
username varchar(255),
password varchar(255),
last_login timestamptz
)
SERVER core;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you&amp;rsquo;ll see a new table in the database you created this in called &lt;code&gt;core_users&lt;/code&gt;. You can query this table just like you&amp;rsquo;d expect:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT *
FROM core_users
WHERE last_login &amp;gt;= now() - '1 day'::interval;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also join against local tables, such as getting all the invoices for users that have logged in within the last month:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT *
FROM invoices, core_users
WHERE core_users.last_login &amp;gt;= now() - '1 month::interval'
AND invoices.user_id = core_users.id
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hopefully this is all straight forward enough, but let&amp;rsquo;s also take a quick look at some of the other interesting ones:&lt;/p&gt;
&lt;h3 id="mysql-fdw"&gt;
&lt;div&gt;
MySQL FDW
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;For MySQL you&amp;rsquo;ll also have to &lt;a href="https://github.com/EnterpriseDB/mysql_fdw"&gt;download it&lt;/a&gt; and install it as well since it doesn&amp;rsquo;t ship directly with Postgres. This should be fairly straight forward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ export PATH=/usr/local/pgsql/bin/:$PATH
$ export PATH=/usr/local/mysql/bin/:$PATH
$ make USE_PGXS=1
$ make USE_PGXS=1 install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that you&amp;rsquo;ve built it you&amp;rsquo;d follow a very similar path to setting it up as we did for Postgres:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE EXTENSION mysql_fdw;
CREATE SERVER mysql_server
FOREIGN DATA WRAPPER mysql_fdw
OPTIONS (host '127.0.0.1', port '3306');
CREATE USER MAPPING FOR postgres
SERVER mysql_server
OPTIONS (username 'foo', password 'bar');
CREATE FOREIGN TABLE core_users (
id integer NOT NULL,
username varchar(255),
password varchar(255),
last_login timestamptz
)
SERVER mysql_server;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But MySQL while different than Postgres is also more similar in SQL support than say a more exotic NoSQL store. How well do they work as a foreign data wrapper? Let&amp;rsquo;s look at our next one:&lt;/p&gt;
&lt;h3 id="mongodb"&gt;
&lt;div&gt;
MongoDB
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;First you&amp;rsquo;ll go through much of the &lt;a href="https://github.com/EnterpriseDB/mongo_fdw"&gt;same setup&lt;/a&gt; as you did for MySQL. The one major difference though is in the final step to setup the &lt;code&gt;table&lt;/code&gt;. Since a table doesn&amp;rsquo;t quite map in the same way with Mongo you have the ability to set two items: 1. the database and 2. the collection name.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE FOREIGN TABLE core_users(
_id NAME,
user_id int,
user_username text,
user_last_login timestamptz)
SERVER mongo_server
OPTIONS (database 'db', collection 'users');
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this you can do some basic level of filtering as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT *
FROM core_users
WHERE user_last_login &amp;gt;= now() - '1 day'::interval;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also write and delete data as well now just using SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DELETE FROM core_users
WHERE user_id = 100;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course just putting SQL on top of Mongo doesn&amp;rsquo;t mean you get all the flexibility of analysis that you&amp;rsquo;d have directly within Postgres, this does go a long way towards allowing you to analyze data that lives across two different systems.&lt;/p&gt;
&lt;h3 id="many-more"&gt;
&lt;div&gt;
Many more
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;A few years ago there were some key ones which already made FDWs useful. Now there&amp;rsquo;s a rich list covering probably every system you could want. Whether it&amp;rsquo;s &lt;a href="http://www.craigkerstiens.com/2012/10/18/connecting_to_redis_from_postgres/"&gt;Redis&lt;/a&gt;, a simple &lt;a href="https://www.postgresql.org/docs/9.5/static/file-fdw.html"&gt;CSV&lt;/a&gt; one, or something newer like &lt;a href="https://github.com/snaga/monetdb_fdw"&gt;MonetDB&lt;/a&gt; chances are you can find an &lt;a href="https://wiki.postgresql.org/wiki/Foreign_data_wrappers#NoSQL_Database_Wrappers"&gt;FDW&lt;/a&gt; for the system you need that makes your life easier.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you&amp;rsquo;re looking for a deeper resource on Postgres I recommend the book &lt;a href="https://theartofpostgresql.com/?affiliate=cek"&gt;The Art of PostgreSQL&lt;/a&gt;. It is by a personal friend that has aimed to create the definitive guide to Postgres, from a developer perspective. If you use code CRAIG15 you&amp;rsquo;ll receive 15% off as well.&lt;/em&gt;&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Sun, 11 Sep 2016 23:55:56 GMT</pubDate><guid isPermaLink="true">/2016/09/11/a-tour-of-fdws/</guid></item><item><title>Making a Twitter bot that looks for hashes</title><link>https://anisse.astier.eu/making-a-twitter-bot-that-looks-for-hashes.html</link><description>&lt;p&gt;&lt;em&gt;This is a followup to &lt;a href="what-do-you-find-when-you-search-twitter-for-hashes.html"&gt;What do you find when you search Twitter for hashes ?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;Why ?&lt;/h1&gt;
&lt;p&gt;I'm not sure I remember how it started.&lt;/p&gt;
&lt;p&gt;It all started four years ago. Jon Oberheide was still an independent security researcher and not yet CTO of a successful product company. He posted some …&lt;/p&gt;</description><author>Linux Engineer's random thoughts</author><pubDate>Fri, 09 Sep 2016 19:00:00 GMT</pubDate><guid isPermaLink="true">https://anisse.astier.eu/making-a-twitter-bot-that-looks-for-hashes.html</guid></item><item><title>What do you find when you search Twitter for hashes ?</title><link>https://anisse.astier.eu/what-do-you-find-when-you-search-twitter-for-hashes.html</link><description>&lt;p&gt;This image:&lt;/p&gt;
&lt;p&gt;&lt;img alt="jpg" src="/images/accents-of-blue_small.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;This is what I found with &lt;a href="https://anisse.astier.eu/making-a-twitter-bot-that-looks-for-hashes.html"&gt;hashbot, a twitter bot that looks for hashes.&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;What is this image ?&lt;/h2&gt;
&lt;p&gt;Posted with the hash "2f404a288d1b564fadee944827a39a14" by japanese accounts (of which @furueru_zekkei used to be the top poster, now suspended).&lt;/p&gt;
&lt;p&gt;After a bit of research on google images and more, I …&lt;/p&gt;</description><author>Linux Engineer's random thoughts</author><pubDate>Fri, 09 Sep 2016 18:00:00 GMT</pubDate><guid isPermaLink="true">https://anisse.astier.eu/what-do-you-find-when-you-search-twitter-for-hashes.html</guid></item><item><title>To all Companies Currently Recruiting</title><link>https://boyter.org/2016/09/companies-recruiting/</link><description>&lt;p&gt;I am writing this on behalf of all developers/engineers out there. Please stop with the take home coding challenge questions. Really. Just stop it. They are a lazy and frankly an unprofessional way of sorting the wheat from the chaff. Before closing your browser in disgust hear me out on this one and hopefully I can convince you of the error of your ways.&lt;/p&gt;
&lt;p&gt;There has become an alarming trend these days of companies during the hiring process to issue lengthy coding challenges in order to prove that the individual they are hiring knows their stuff. I totally understand why you might be doing this but frankly its flawed. Lets go through several reasons why.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Fri, 09 Sep 2016 01:29:19 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/09/companies-recruiting/</guid></item><item><title>Guess the city</title><link>https://rjp.is/blogging/posts/guess-the-city-2/</link><description>In which the future is predicted.</description><author>infrequent oscillations</author><pubDate>Tue, 06 Sep 2016 11:23:06 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/guess-the-city-2/</guid></item><item><title>GPL Time-bomb an interesting approach to #FOSS licensing</title><link>https://boyter.org/2016/08/gpl-time-bomb-interesting-approach-foss-licensing/</link><description>&lt;p&gt;&lt;strong&gt;UPDATES&lt;/strong&gt; Following some &lt;a href="https://news.ycombinator.com/item?id=12459492"&gt;feedback&lt;/a&gt; I am going to rename my usage of &amp;ldquo;Time-Bomb&amp;rdquo; due to potential negative connotation on the words. I am going to call it &amp;ldquo;Eventually Open&amp;rdquo;. Also a few other things need mentioning. I am not looking for code submissions back into the source at this time. This was a move to show that there are no back-doors in the code sending source code back to a master server.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Mon, 29 Aug 2016 04:47:39 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/08/gpl-time-bomb-interesting-approach-foss-licensing/</guid></item><item><title>Test-Defective</title><link>https://cmdev.com/blog/2016-08-27-testdefective/</link><description>If you have automated tests, believe them or discard them.</description><author>The Cranky Developer on Crater Moon Development</author><pubDate>Sat, 27 Aug 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://cmdev.com/blog/2016-08-27-testdefective/</guid></item><item><title>searchcode server under fair source</title><link>https://boyter.org/2016/08/searchcode-server-fair-source/</link><description>&lt;p&gt;A very quick blog today. I have released &lt;a href="https://github.com/boyter/searchcode-server"&gt;searchcode server&lt;/a&gt; under the &lt;a href="https://fair.io/"&gt;fair source licence&lt;/a&gt;. This means that as of a few days ago you can view the source, change it modify it and run it as you see fit so long as you have less than 5 users.&lt;/p&gt;
&lt;p&gt;The source is hosted on github (I may move this to GitLab sometime in the future) and you can &lt;a href="https://github.com/boyter/searchcode-server"&gt;view it here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So what does this mean? Well the community edition still exists (run searchcode with as many users as you want) as do the paid versions with support and all the full features. The real advantage however is that you can now vet the source code to ensure that searchcode server is not secretly sending your most valuable asset to some hidden server somewhere. In addition it means I can now talk about the source openly and will be writing some posts about how I ran into some CPU branching issues which slowed down some code.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Thu, 25 Aug 2016 02:38:33 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/08/searchcode-server-fair-source/</guid></item><item><title>The Worst Individual I Ever Worked With</title><link>https://boyter.org/2016/08/worst-individual-worked/</link><description>&lt;p&gt;Taken from a comment I posted on HN in a thread about a &lt;a href="https://news.ycombinator.com/item?id=12337073"&gt;Soccer Con Man&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Not actually a programmer. The guy was hired to be a project manager.&lt;/p&gt;
&lt;p&gt;After joining things were as expected but after a few weeks we noticed that he was rarely around after lunch and never around after lunch on a Friday.&lt;/p&gt;
&lt;p&gt;We would email him at those times deliberately to catch him out and I recall starting to put sticky notes on his laptop &amp;ldquo;Came to see you a X time&amp;rdquo;. He would come back and just dump all the notes in the rubbish and claim he never got them. He would often claim to be working from home, despite his laptop being on his desk and usually closed. He would also never responding during those times to email or IM.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Tue, 23 Aug 2016 05:55:20 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/08/worst-individual-worked/</guid></item><item><title>Types of Testing in Software Engineering</title><link>https://boyter.org/2016/08/types-testing-software-engineering/</link><description>&lt;p&gt;There are many different types of testing which exist in software engineering. They should not be confused with the test levels, unit testing, integration testing, component interface testing, and system testing. However the different test levels may be used by each type as a way of checking for software quality.&lt;/p&gt;
&lt;p&gt;The following are all different types of tests in software engineering.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;A/B&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A/B testing is testing the comparison of two outputs where a single unit has changed. It is commonly used when trying to increase conversion rates for online websites. A real genius in this space is &lt;a href="http://www.kalzumeus.com/"&gt;Patrick McKenzie&lt;/a&gt; and a few very worthwhile articles to read about it are &lt;a href="http://www.kalzumeus.com/2012/08/06/stripe-and-ab-testing-made-me-a-small-fortune/"&gt;How Stripe and AB Made me A Small Fortune&lt;/a&gt; and &lt;a href="https://training.kalzumeus.com/newsletters/archive/ab_testing"&gt;AB Testing&lt;/a&gt;&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Thu, 18 Aug 2016 01:42:37 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/08/types-testing-software-engineering/</guid></item><item><title>Castle Hill Winter Trip 2016 Photos</title><link>https://smcleod.net/2016/08/castle-hill-winter-trip-2016-photos/</link><description>Castle Hill Winter Trip 2016 [Photos]</description><author>smcleod.net</author><pubDate>Sat, 06 Aug 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2016/08/castle-hill-winter-trip-2016-photos/</guid></item><item><title>Email as a Microservice</title><link>https://www.brightball.com/articles/email-as-a-microservice</link><description>Email might be one of the most often overlooked pieces of any web application. Usually the biggest discussion around it in a project begins and ends with “and we’ll send them an email when this happens…”.
A little thought and some minor adjustments can help us avoid some problems that will grow as your project does. Let’s talk about email as a microservice.</description><author>Brightball Articles</author><pubDate>Sat, 06 Aug 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://www.brightball.com/articles/email-as-a-microservice</guid></item><item><title>Syncing Stash/BitBucket with searchcode server</title><link>https://boyter.org/2016/08/syncing-stashbitbucket-searchcode-server/</link><description>&lt;p&gt;Recently it came up to perform a slight integration piece between a on premises Stash/BitBucket install and a searchcode server install. Thankfully both have an API and very thankfully there is a nice Python library for talking to Stash/BitBucket.&lt;/p&gt;
&lt;p&gt;Below is the code used. It pulls out all of the repositories from every project, checks if it exists in searchcode and if not adds it as a repository to be indexed. You need to install stashy (pip install stashy) and run it whenever you have new repositories. One idea is to set it as a cron task and ensure everything is in sync.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Thu, 04 Aug 2016 08:14:19 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/08/syncing-stashbitbucket-searchcode-server/</guid></item><item><title>Python Fabric: Getting File from Host as String</title><link>https://boyter.org/2016/08/python-fabric-file-host-string/</link><description>&lt;p&gt;When using fabric for deployments you will sometimes want check an existing file for the presence of a value before applying an update. A common example I run into is checking if an apt-source has already been added before adding it again. This is a little clunky in fabric, but thankfully you can write a simple helper which takes case of it for you.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-python"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;def&lt;/span&gt; &lt;span style="color: #a6e22e;"&gt;_get_remote&lt;/span&gt;(fileloc):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;    &lt;span style="color: #e6db74;"&gt;'''Pulls back a file contents from connection as string'''&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;    &lt;span style="color: #f92672;"&gt;from&lt;/span&gt; StringIO &lt;span style="color: #f92672;"&gt;import&lt;/span&gt; StringIO
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;    fd &lt;span style="color: #f92672;"&gt;=&lt;/span&gt; StringIO()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;    get(fileloc, fd)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;    content &lt;span style="color: #f92672;"&gt;=&lt;/span&gt; fd&lt;span style="color: #f92672;"&gt;.&lt;/span&gt;getvalue()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;    &lt;span style="color: #66d9ef;"&gt;return&lt;/span&gt; content&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Usage is fairly simple. Say we want to install the latest version of Varnish Cache on an Ubuntu server. Usage like so works,&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Tue, 02 Aug 2016 01:52:39 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/08/python-fabric-file-host-string/</guid></item><item><title>On Check Constraints and Whole Value</title><link>https://cmdev.com/blog/2016-08-01-wholevalueandcheckconstraints/</link><description>A business object with setters for attributes that are interdependent, will need check constraints on the setters. But there is a better way, using the Whole Value pattern.</description><author>The Cranky Developer on Crater Moon Development</author><pubDate>Mon, 01 Aug 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://cmdev.com/blog/2016-08-01-wholevalueandcheckconstraints/</guid></item><item><title>searchcode.com: The Architecture – migration 3.0</title><link>https://boyter.org/2016/07/searchcode-com-architecture-migration-3-0/</link><description>&lt;p&gt;27th July 2016 at about 9:30pm my local time (GMT +10) I updated the A records for searchcode&amp;rsquo;s nameservers to point at a new stack that has been several months in the making. As with most posts of this sort of nature a quick recap of where things were and where they are now.&lt;/p&gt;
&lt;p&gt;The previous searchcode stack consisted of two dedicated servers hosted by Hetzner. I have previously discussed this about &lt;a href="http://www.boyter.org/2014/06/searchcode/"&gt;two years ago when discussing searchcode next&lt;/a&gt;. The first server was a reasonably powerful machine running pretty much all of code required to deliver searchcode.com itself with the exception of the actual index. searchcode is a Django application and was using nginx to serve results directly out of memcached where possible to avoid consuming a running Gunicorn process. The move to have another server for the index came pretty quickly after searchcode was released as it was just not performant enough with everything on a single box which was the situation for a short time.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Thu, 28 Jul 2016 04:09:56 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/07/searchcode-com-architecture-migration-3-0/</guid></item><item><title>Counting Pizza with Python</title><link>https://tomforb.es/blog/counting-pizza-with-python/</link><description>I’m a full time nerd, even when I’m ordering pizza online I can’t stop myself from investigating how the websites I’m ordering from work. My latest investigation was Dominoes where I found a neat way to count the number of orders that they process throughout the day. This post is supposed to highlig...</description><author>Tom Forbes</author><pubDate>Thu, 28 Jul 2016 03:03:32 GMT</pubDate><guid isPermaLink="true">https://tomforb.es/blog/counting-pizza-with-python/</guid></item><item><title>PostgreSQL functions with Elixir Ecto</title><link>https://www.brightball.com/articles/postgresql-functions-with-elixir-ecto</link><description>Functions within PostgreSQL can be setup to return rows and included in queries just like any other table. Continuing with our theme of trying to push Elixir and Phoenix a little on this site rebuild, we will move our site search inside of a database function and experiment with different ways to call it from Ecto.</description><author>Brightball Articles</author><pubDate>Wed, 27 Jul 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://www.brightball.com/articles/postgresql-functions-with-elixir-ecto</guid></item><item><title>Syntax highlighting and CSS support added to wordinserter</title><link>https://tomforb.es/blog/syntax-highlighting-and-css-support-added-to-wordinserter/</link><description>I recently added syntax highlighting and support for CSS stylesheets to wordinserter , and the implementation was satisfying enough that I thought I would blog about it. Wordinserter is a library I maintain that lets you insert HTML documents/snippets into Word documents: It’s primary use case is wh...</description><author>Tom Forbes</author><pubDate>Tue, 26 Jul 2016 04:22:28 GMT</pubDate><guid isPermaLink="true">https://tomforb.es/blog/syntax-highlighting-and-css-support-added-to-wordinserter/</guid></item><item><title>How to Hide Methods From Fabric Task Listing</title><link>https://boyter.org/2016/07/hide-methods-fabric-task-listing/</link><description>&lt;p&gt;Occasionally you may want to hide a method from appearing inside the fabric listing of available tasks. Usually its some sort of helper method you have created that is shared by multiple tasks. So how to hide it? Simply prefix with _&lt;/p&gt;
&lt;p&gt;For example,&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-python"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;def&lt;/span&gt; &lt;span style="color: #a6e22e;"&gt;_apt_get&lt;/span&gt;(packages):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;    &lt;span style="color: #e6db74;"&gt;'''Makes installing packages easier'''&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;    sudo(&lt;span style="color: #e6db74;"&gt;'apt-get update'&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;    sudo(&lt;span style="color: #e6db74;"&gt;'apt-get -y --force-yes install &lt;/span&gt;&lt;span style="color: #e6db74;"&gt;%s&lt;/span&gt;&lt;span style="color: #e6db74;"&gt;'&lt;/span&gt; &lt;span style="color: #f92672;"&gt;%&lt;/span&gt; packages)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When listing the fabric tasks this method will no longer appear in the results.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Fri, 22 Jul 2016 01:34:49 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/07/hide-methods-fabric-task-listing/</guid></item><item><title>Python Fabric How to Show or List All Available Tasks</title><link>https://boyter.org/2016/07/python-fabric-show-list-tasks/</link><description>&lt;p&gt;Showing or displaying the available tasks inside a fabric fabfile is one of those things that almost everyone wants to do at some point and usually works out you can just request a task you know will not exist (usually found through a typo). However there is a way to list them built into fabric itself.&lt;/p&gt;
&lt;p&gt;The below are all methods which can be used to display the currently defined tasks.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Thu, 21 Jul 2016 01:30:51 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/07/python-fabric-show-list-tasks/</guid></item><item><title>Set Ubuntu Linux Swapfile Using Python Fabric</title><link>https://boyter.org/2016/07/set-ubuntu-linux-swapfile-python-fabric/</link><description>&lt;p&gt;Annoyingly most cloud providers have an irritating habit of not adding any swap memory to any instance you spin up. Probably because if they added swap to the instance the disk size would appear to be smaller then it is or if they had a dedicated swap partition they would have to bear the cost or again use some of your disk space.&lt;/p&gt;
&lt;p&gt;Thankfully adding swap to your Ubuntu linux instance is fairly easy. The following task when run will check if a swapfile already exists on the host and if not create one, mount it and set it to be remounted when the instance is rebooted. It takes in a parameter which specifies the size of the swap in gigabytes.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Wed, 20 Jul 2016 01:53:52 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/07/set-ubuntu-linux-swapfile-python-fabric/</guid></item><item><title>Python Fabric Set Host List at Runtime</title><link>https://boyter.org/2016/07/python-fabric-set-host-list-runtime/</link><description>&lt;p&gt;With the advent of cloud computing where you spin up and tear down servers at will it becomes extremely useful to pick the hosts you want fabric to run on at runtime rather then through the usual env.hosts setting. This allows you to query your servers through your cloud providers API without having to maintain a list. This can be a more powerful and flexible technique then using roles and in a devops world can save you a lot of time.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Tue, 19 Jul 2016 01:40:13 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/07/python-fabric-set-host-list-runtime/</guid></item><item><title>The State of Android in 2016 &amp;amp; The OnePlus 3 Phone</title><link>https://smcleod.net/2016/07/the-state-of-android-in-2016-the-oneplus-3-phone/</link><description>&lt;p&gt;I wanted to try Android for a couple of weeks, I like staying on top of technology, gadgets and making sure I never become a blind &amp;lsquo;zealot&amp;rsquo; for any platform or brand.&lt;/p&gt;
&lt;h2 id="the-oneplus-3"&gt;The OnePlus 3&lt;/h2&gt;
&lt;p&gt;I did a lot of research and decided to try the &amp;ldquo;Oneplus 3&amp;rdquo; as it was good bang-for-buck, ran the latest software had plenty of grunt with the latest 8 core, high clock speed Qualcomm processor coupled with 6GB of DDR4 - the specs really are very impressive, especially for a $400USD phone.&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Mon, 11 Jul 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2016/07/the-state-of-android-in-2016-the-oneplus-3-phone/</guid></item><item><title>Insanity with Elixir + Phoenix + PostgreSQL</title><link>https://www.brightball.com/articles/insanity-with-elixir-phoenix-postgresql</link><description>I'm at the borderline of obsessed with Elixir and Phoenix lately. I've avoided writing about it so far because it feels a bit too good to be true. In an effort to test my own enthusiam, I decided to rebuild this site with them in the most ridiculous way possible just to try to test some limits. Because I already have an unhealthy obsession with PostgreSQL, we're getting crazy with it too.
DISCLAIMER: This is not a "how to build a blog" article. If you do what I'm about to do, people will look at you funny (and probably should).</description><author>Brightball Articles</author><pubDate>Wed, 06 Jul 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://www.brightball.com/articles/insanity-with-elixir-phoenix-postgresql</guid></item><item><title>Update Delayed Serial STONITH Design</title><link>https://smcleod.net/2016/07/update-delayed-serial-stonith-design/</link><description>&lt;p&gt;&lt;em&gt;note: This is a follow up post from &lt;a href="https://smcleod.net/tech/2015/07/21/rcd-stonith/"&gt;2015-07-21-rcd-stonith&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="a-linux-cluster-base-stonith-provider-for-use-with-modern-pacemaker-clusters"&gt;A Linux Cluster Base STONITH provider for use with modern Pacemaker clusters&lt;/h3&gt;
&lt;p&gt;This has since been accepted and merged into Fedora&amp;rsquo;s code base and as such will make it&amp;rsquo;s way to RHEL.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Source Code: &lt;a href="https://github.com/sammcj/fence_rcd_serial"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diptrace.com/download/download-diptrace/"&gt;Diptrace&lt;/a&gt; CAD Design: &lt;a href="https://github.com/sammcj/fence_rcd_serial/tree/master/CAD/STONTH_CAD_DESIGN_V3"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I have open sourced the CAD circuit design and made this available within this repo under
&lt;a href="CAD/STONTH_CAD_DESIGN_V3"&gt;CAD Design and Schematics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Related RedHat Bug: &lt;a href="https://bugzilla.redhat.com/show_bug.cgi?id=1240868"&gt;https://bugzilla.redhat.com/show_bug.cgi?id=1240868&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="v1-vs-v2v3-versions-of-the-rcd_serial-stonith-system"&gt;&lt;code&gt;v1&lt;/code&gt; vs &lt;code&gt;v2/v3&lt;/code&gt; versions of the &lt;code&gt;rcd_serial&lt;/code&gt; STONITH system&lt;/h4&gt;
&lt;p&gt;The v2/v3 cables include the following improvements:&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Mon, 04 Jul 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2016/07/update-delayed-serial-stonith-design/</guid></item><item><title>What is Chaos Testing / Engineering</title><link>https://boyter.org/2016/07/chaos-testing-engineering/</link><description>&lt;p&gt;A blog post by the excellent technical people at Netflix about &lt;a href="https://web.archive.org/web/20141008152549/http://techblog.netflix.com/2014/09/introducing-chaos-engineering.html"&gt;Chaos Engineering&lt;/a&gt; and further posts about the subject by &lt;a href="http://azure.microsoft.com/blog/2015/07/01/inside-azure-search-chaos-engineering"&gt;Microsoft in Azure Search&lt;/a&gt; prompted me to ask the question, What is chaos engineering and how can chaos testing be applied to help me?&lt;/p&gt;
&lt;h2 id="what-is-chaos-testing"&gt;What is Chaos Testing?&lt;/h2&gt;
&lt;p&gt;First coined by the afore-mentioned Netflix blog post, chaos engineering takes the approach that regardless how encompassing your test suite is, once your code is running on enough machines and reaches enough complexity errors are going to happen. Since failure is unavoidable, why not deliberately introduce it to ensure your systems and processes can deal with the failure?&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Sat, 02 Jul 2016 10:48:29 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/07/chaos-testing-engineering/</guid></item><item><title>CSV: An Encoding Nightmare</title><link>https://donatstudios.com/CSV-An-Encoding-Nightmare</link><description>&lt;p&gt;&lt;strong&gt;UPDATE 2019-01-16&lt;/strong&gt;: In the three years since this article was written, parts of the article, in particular talking about UTF-8 are thankfully no longer accurate.&lt;/p&gt;
&lt;p&gt;It would appear in a recent update Microsoft has added support for safely reading and writing UTF-8 CSVs to Excel. There is a new format in the save dialog &lt;code&gt;CSV UTF-8 (Comma delimited)&lt;/code&gt; which is distinct from &lt;code&gt;Comma Separated Values&lt;/code&gt; which is also still in there. &lt;/p&gt;
&lt;p&gt;&lt;del&gt;In my testing it appears to safely both load and save. Best of all it appears if there is a BOM, it leaves it, if there isn't it doesn't add one. Very nice handling indeed.&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE 2022-07-22&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;It would appear that the stricken above was incorrect. Current versions of Excel will only reliably load a UTF-8 CSV if a UTF-8 BOM is in place.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;The company I work for manages a self-service data import system, handling information from school districts “Student Information Systems”. There are hundreds if not thousands of SIS’s out there, but what the vast majority have in common is the ability to export CSV. It is the lingua franca, everyone can get us CSVs. &lt;/p&gt;
&lt;p&gt;CSV to the casual observer seems a simple portable format, but its looks are deceiving. If the data is pure &lt;a href="https://www.asciitable.com/"&gt;&lt;strong&gt;ASCII&lt;/strong&gt;&lt;/a&gt; (bytes 0-127) you’ll be fine. However, if there is a need for any sort of non-ASCII character, there is some work ahead.&lt;/p&gt;
&lt;p&gt;In our case, handling school data from around the world, correctly handling non-ASCII characters is of the utmost importance. &lt;/p&gt;
&lt;h2&gt;Excel: A World of Hurt&lt;/h2&gt;
&lt;p&gt;The biggest problem is not CSV itself, but that the primary tool used to interact with it is Excel. Excel handles CSV encodings badly.&lt;/p&gt;
&lt;p&gt;Creating a new document in Excel and saving as ”Comma Separated Values (.csv)” it uses your locale’s Windows or Mac codepage. Win-1252 and MacRoman respectively in the United States. If your codepage doesn’t support a character in your document, it will be silently replaced with an underscore &lt;code&gt;_&lt;/code&gt; character.&lt;/p&gt;
&lt;p&gt;Because it uses codepages and not a Unicode encoding, it makes processing a painful chore. There is no way to tell the difference between different 8-bit codepages programatically. &lt;/p&gt;
&lt;p&gt;One can use heuristics to sort them into an order of likelihood, but there is no way to ever know for sure. We chose to present the user with previews of the most likely codepages, and let them pick the correct one.&lt;/p&gt;
&lt;h3&gt;Excel for Mac: Broken Beyond Belief&lt;/h3&gt;
&lt;p&gt;The Macintosh version of Microsoft Excel is particularly harrowing. &lt;/p&gt;
&lt;p&gt;As I mentioned above, Excel saves your CSV in your locales codepage. One should note that the Mac codepages fell out of use with OS 9, almost 15 years ago. Microsoft did not get that memo.&lt;/p&gt;
&lt;p&gt;While that by definition makes the CSVs the Mac version of Excel exports unusable on Windows, the problem is more unfortunate than that. The Mac version can only &lt;strong&gt;read&lt;/strong&gt; the locales &lt;strong&gt;Windows&lt;/strong&gt; codepage. &lt;/p&gt;
&lt;p&gt;That means the Mac version of Excel cannot read CSVs &lt;strong&gt;it&lt;/strong&gt; wrote. That's pathetic.&lt;/p&gt;
&lt;p&gt;If you had &lt;strong&gt;any extended characters&lt;/strong&gt; when you saved, they are scrambled when you reopen it. This problem has persisted in every version of Mac Excel up to the current Excel 2016. &lt;/p&gt;
&lt;p&gt;One simply &lt;strong&gt;cannot&lt;/strong&gt; safely open a CSV created with the Mac version of Excel, on any platform, anywhere.&lt;/p&gt;
&lt;h2&gt;UTF-8? What’s that?&lt;/h2&gt;
&lt;p&gt;UTF-8 is the encoding of the 21st Century. It was quick in  &lt;a href="https://en.wikipedia.org/wiki/File:UnicodeGrow2b.png"&gt;overtaking every other encoding&lt;/a&gt;. &lt;em&gt;Almost&lt;/em&gt; every modern application supports it. This will be easy and we’ll be fine? Not so fast. &lt;/p&gt;
&lt;p&gt;If one attempts to open a CSV file encoded as UTF-8 &lt;em&gt;without&lt;/em&gt; a Byte Order Mark (&lt;a href="https://en.wikipedia.org/wiki/Byte_order_mark"&gt;BOM&lt;/a&gt;) as &lt;a href="https://utf8everywhere.org/#faq.boms"&gt;recommended&lt;/a&gt;, any non-ASCII characters are again scrambled.&lt;/p&gt;
&lt;p&gt;This is the CSV format Apple’s &lt;em&gt;Numbers&lt;/em&gt; exports by default, UTF-8 sans BOM.&lt;/p&gt;
&lt;p&gt;If we try it again &lt;strong&gt;with&lt;/strong&gt; a UTF-8 BOM prepended to the file and Excel will read it. This is deceptive because once saved the text will remain correctly encoded UTF-8, but bizarrely the &lt;strong&gt;BOM will be stripped&lt;/strong&gt; causing the file to no longer be correctly readable.&lt;/p&gt;
&lt;p&gt;Many naïve application output UTF-8 + BOM CSVs, and they read correctly but do not write correctly. I’ve seen this cause all sorts of headaches because it appears to work but does not.&lt;/p&gt;
&lt;h2&gt;The &lt;strike&gt;Right Way&lt;/strike&gt; Functional Workaround&lt;/h2&gt;
&lt;p&gt;As of this writing, there exists a &lt;strong&gt;single&lt;/strong&gt; usable CSV format that Microsoft Excel can both &lt;em&gt;read&lt;/em&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;em&gt;write&lt;/em&gt; safely across platforms. Tab delimited UTF-16LE with leading Byte Order Mark. &lt;/p&gt;
&lt;p&gt;Using Excel to output into this format to begin with, you have to use the Save As dialog and choose “UTF-16 Unicode Text (.txt)”. Frustratingly, it includes a &lt;code&gt;.txt&lt;/code&gt; extension by default which can be confusing for non-technical users. However, if you provide clear instructions to Windows users to save their filename in quotes with a CSV extension such as &lt;code&gt;"example.csv"&lt;/code&gt; it is workable.&lt;/p&gt;
&lt;p&gt;If you operate an application with a CSV exporter &lt;strong&gt;please&lt;/strong&gt; use this as your default export format. It will save us all many headaches in the long run.&lt;/p&gt;</description><author>Donat Studios</author><pubDate>Tue, 21 Jun 2016 03:17:57 GMT</pubDate><guid isPermaLink="true">https://donatstudios.com/CSV-An-Encoding-Nightmare</guid></item><item><title>Starting a Snap site with Stack and Persistent</title><link>https://3059274a.danpalmer-me.pages.dev/2016-06-19-starting-snap/</link><description>Following on from my previous post about Haskell web frameworks, I&amp;rsquo;ve dived into making a non-trivial web application, with type-safe database access.</description><author>Dan Palmer</author><pubDate>Sun, 19 Jun 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://3059274a.danpalmer-me.pages.dev/2016-06-19-starting-snap/</guid></item><item><title>Five mistakes beginners make when working with databases</title><link>/2016/06/07/five-mistakes-databases/</link><description>&lt;p&gt;When you start out as a developer there&amp;rsquo;s an overwhelming amount of things to grasp. First there&amp;rsquo;s the language itself, then all the quirks of the specific framework you&amp;rsquo;re using,and after that (or maybe before) we&amp;rsquo;ll throw front-end development into the mix, and somewhere along the line you have to decide to store your data somewhere.&lt;/p&gt;
&lt;p&gt;Early on, with so many things to quickly master, the database tends to be an after-though in application design (perhaps because it doesn&amp;rsquo;t make an impact to end user experience). As a result there&amp;rsquo;s a number of bad practices that tend to get picked up when working with databases, here&amp;rsquo;s a rundown of just a few.&lt;/p&gt;
&lt;h3 id="1-storing-images"&gt;
&lt;div&gt;
1. Storing images
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Images don&amp;rsquo;t belong in your database. Just because you can do something, it doesn&amp;rsquo;t mean you should.Images take up a massive amount of space in databases, and slow applications down by unnecessarily eating your database&amp;rsquo;s IO resources. The most common way this mistake occurs is when new developers base64 encode an image and store it in a database large text/blob field.&lt;/p&gt;
&lt;p&gt;The better approach is to upload your images directly to a service like Amazon S3, then store the image URL (hosted by Amazon) in your database as a text field. This way, each time you need to load an image, you need to simply output the image URL into a valid &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag. This will greatly improve website responsiveness, and generally help scale web applications.&lt;/p&gt;
&lt;h3 id="2-limitoffset"&gt;
&lt;div&gt;
2. Limit/Offset
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Pagination is extremely common in a number of applications.As soon as you start to learn SQL, the most straight-forward way to handle pagination is to &lt;code&gt;ORDER BY&lt;/code&gt; some column then &lt;code&gt;LIMIT&lt;/code&gt; the number of results returned, and for each extra page you&amp;rsquo;ll &lt;code&gt;OFFSET&lt;/code&gt; by so many records. This all seems entirely logical, until you realize at any moderate scale:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The load this exerts on your database will be painful.&lt;/li&gt;
&lt;li&gt;It isn&amp;rsquo;t deterministic, should records change as the user flips between pages.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The unfortunate part is: pagination is quite complex, and there isn&amp;rsquo;t a one-size-fits-all solution. For more information on solving pagination problems, you can check &lt;a href="https://www.citusdata.com/blog/1872-joe-nelson/409-five-ways-paginate-postgres-basic-exotic"&gt;out numerous options&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="3-integer-primary-keys"&gt;
&lt;div&gt;
3. Integer primary keys
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;The default for almost all ORMs when creating a primary key is to create a serial field. This is a sequence that auto-increments and then you use that number as your primary key. This seems straight forward as an admin, because you can browse from /users/1 to /users/2, etc. And for most applications this can often be fine. And for most applications, this is fine. But, you&amp;rsquo;ll soon realize as you start to scale that integers primary keys can be exhausted, and are not ideal for large-scale systems. Further you&amp;rsquo;re reliant on that single system generating your keys. If a time comes when you have to scale the pain here will be huge. The better approach is to start &lt;a href="https://til.hashrocket.com/posts/31a5135e19-generate-a-uuid-in-postgresql"&gt;taking advantage of UUIDs&lt;/a&gt; from the start.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;There&amp;rsquo;s also the bonus advantage of not secretly showcasing how many users/listings/whatever the key references directly to users on accident.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="4-default-values-on-new-columns"&gt;
&lt;div&gt;
4. Default values on new columns
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;No matter how long you&amp;rsquo;ve been at it you won&amp;rsquo;t get the perfect schema on day 1. It&amp;rsquo;s better to think of database schemas as continuously evolving documents. Fortunately, it&amp;rsquo;s easy to add a column to your database, but: it&amp;rsquo;s also easy to do this in a horrific way. By default, if you just add a column it&amp;rsquo;ll generally allow NULL values. This operation is fast, but most applications don&amp;rsquo;t truly want null values in their data, instead they want to set the default value.&lt;/p&gt;
&lt;p&gt;If you do add a column with a default value on the table, this will trigger a full re-write of your table. &lt;em&gt;Note: this is very bad for any sizable table on an application.&lt;/em&gt; Instead, it&amp;rsquo;s far better to allow null values at first so the operation is instant, then set your default, and then, with a background process go and retroactively update the data.&lt;/p&gt;
&lt;p&gt;This is more complicated than it should be, but fortunately there are some &lt;a href="http://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/"&gt;handy guides&lt;/a&gt; to help.&lt;/p&gt;
&lt;h3 id="5-over-normalization"&gt;
&lt;div&gt;
5. Over normalization
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;As you start to learn about normalization it feels like the right thing to do. You create a &lt;code&gt;posts&lt;/code&gt; table, which contains &lt;code&gt;authors&lt;/code&gt;, and each post belongs in a category. So you create a &lt;code&gt;categories&lt;/code&gt; table, and then you create a join table &lt;code&gt;post_categories&lt;/code&gt;. At the real root of it there&amp;rsquo;s not anything fundamentally wrong with normalizing your data, but at a certain point there are diminishing returns.&lt;/p&gt;
&lt;p&gt;In the above case categories could very easily just be an array of varchar fields on a post. Normalization makes plenty of sense, but thinking through it a bit more every time you have a many to many table and wondering if you really need a full table on both sides is worth giving a second thought.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Edit: It&amp;rsquo;s probably worth saying that under-normalization is also a problem as well. There isn&amp;rsquo;t a one size fits all here. In general there are times where it does make sense to have a completely de-normalized and a completely normalized approach. As &lt;a href="https://twitter.com/fuzzychef/status/740248400243785728"&gt;@fuzzychef&lt;/a&gt; described: &amp;ldquo;use an appropriate amount of normalization i.e. The goldilocks principle&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="conclusion"&gt;
&lt;div&gt;
Conclusion
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;When I asked about this on twitter I got a pretty great responses, but they were all over the map. From the basics of never looking at the queries the ORM is generating, to much more advanced topics such as isolation levels. The one I didn&amp;rsquo;t hit on that does seem to be a worthwhile one for anyone building a real world app is indexing. Knowing how &lt;a href="http://www.craigkerstiens.com/2012/10/01/understanding-postgres-performance/"&gt;indexing works&lt;/a&gt;, and understanding &lt;a href="http://www.craigkerstiens.com/2013/05/30/a-collection-of-indexing-tips/"&gt;what indexes&lt;/a&gt; you need to create is a critical part of getting good database performance. There&amp;rsquo;s a number of posts on indexing that teach the basics, as well as &lt;a href="http://www.craigkerstiens.com/2013/01/10/more-on-postgres-performance/"&gt;practical steps&lt;/a&gt; for analyzing performance with Postgres.&lt;/p&gt;
&lt;p&gt;In general, I encourage you to treat the database as another tool in your chest as opposed to a necessary evil, but hopefully, the above tips will at least prevent you from making some initial mistakes as you dig in as a beginner.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Special thanks to &lt;a href="https://twitter.com/mdeggies"&gt;@mdeggies&lt;/a&gt; and &lt;a href="https://twitter.com/rdegges"&gt;@rdegges&lt;/a&gt; for the initial conversation to spark the post at PyCon.&lt;/em&gt;&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Tue, 07 Jun 2016 23:55:56 GMT</pubDate><guid isPermaLink="true">/2016/06/07/five-mistakes-databases/</guid></item><item><title>On Maps</title><link>https://rjp.is/blogging/posts/on-maps-2/</link><description>In which we criticise Apple Maps.</description><author>infrequent oscillations</author><pubDate>Mon, 06 Jun 2016 13:33:05 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/on-maps-2/</guid></item><item><title>First week of Juneathon</title><link>https://rjp.is/blogging/posts/first-week-of-juneathon-2/</link><description>Being lazy and repurposing the Gyroscope report.</description><author>infrequent oscillations</author><pubDate>Mon, 06 Jun 2016 11:44:33 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/first-week-of-juneathon-2/</guid></item><item><title>Beautiful A/B testing</title><link>https://bytepawn.com/beautiful-ab-testing.html</link><description>&lt;p&gt;I gave this talk at the O’Reilly Strata Conference London in 2016 June, mostly based on what  I learned at Prezi from 2012-2016.&lt;br /&gt;&lt;br /&gt;&lt;img alt="14. slide" src="/images/strata-2016/14.png" style="width: 400px;" /&gt;&lt;/p&gt;</description><author>Bytepawn - Marton Trencseni</author><pubDate>Sun, 05 Jun 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://bytepawn.com/beautiful-ab-testing.html</guid></item><item><title>Haskell Web Frameworks</title><link>https://3059274a.danpalmer-me.pages.dev/2016-06-04-haskell-web-frameworks/</link><description>A quick overview of 5 of the popular Haskell web frameworks, and what they can do to improve the state of web development.</description><author>Dan Palmer</author><pubDate>Sat, 04 Jun 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://3059274a.danpalmer-me.pages.dev/2016-06-04-haskell-web-frameworks/</guid></item><item><title>May's Gyroscope Report</title><link>https://rjp.is/blogging/posts/mays-gyroscope-report-2/</link><description>In which we look at some graphs.</description><author>infrequent oscillations</author><pubDate>Fri, 03 Jun 2016 21:45:37 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/mays-gyroscope-report-2/</guid></item><item><title>Fixing the Ansible 2.1 Temporary File Permissions Issue</title><link>https://benovermyer.com/blog/2016/06/fixing-the-ansible-21-temporary-file-permissions-issue/</link><description>&lt;p&gt;In Ansible 2.1 and later, Ansible will not allow the creation of world-readable temporary files. It does this for a good reason, but it's a change from how it was before. If you're experiencing this problem, you'll see an error when trying to become_user other than root, and it'll look like this:&lt;/p&gt;
&lt;pre class="giallo" style="color: #F8F8F2; background-color: #282A36;"&gt;&lt;code&gt;&lt;span class="giallo-l"&gt;&lt;span&gt;fatal: [12.34.567.8]: FAILED! =&amp;gt; {&amp;quot;failed&amp;quot;: true, &amp;quot;msg&amp;quot;: &amp;quot;Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user. For information on working around this, see https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user&amp;quot;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The documentation offers solutions. The one that worked for me was this: add the installation (and enablement) of ACL as part of your common tasks for a given playbook. Everything else will then work behind the scenes to make sure those temporary files are handled securely and silently.&lt;/p&gt;</description><author>Ben Overmyer's Site</author><pubDate>Thu, 02 Jun 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://benovermyer.com/blog/2016/06/fixing-the-ansible-21-temporary-file-permissions-issue/</guid></item><item><title>The disappointment of OutRun</title><link>https://rjp.is/blogging/posts/the-disappointment-of-outrun-2-2/</link><description>In which we fail a goal but that's ok.</description><author>infrequent oscillations</author><pubDate>Wed, 01 Jun 2016 06:31:54 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/the-disappointment-of-outrun-2-2/</guid></item><item><title>A couple of ambient tracks from the noise of a train ticket</title><link>https://rjp.is/blogging/posts/a-couple-of-ambient-tracks-from-the-noise-of-a-train-ticket-2/</link><description>In which we make something from nothing.</description><author>infrequent oscillations</author><pubDate>Tue, 24 May 2016 10:55:26 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/a-couple-of-ambient-tracks-from-the-noise-of-a-train-ticket-2/</guid></item><item><title>Monitoring SystemD Units With Nagios</title><link>https://smcleod.net/2016/05/monitoring-systemd-units-with-nagios/</link><description>&lt;p&gt;&lt;em&gt;Ever forgotten to add a critical service to monitoring?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Want to know if a service or process fails without explicitly monitoring every service on a host?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;hellip;Then why not use SystemD&amp;rsquo;s existing knowledge of all the enabled services? Thanks to &amp;lsquo;Kbyte&amp;rsquo; who made a simple Nagios plugin to do just this!&lt;/p&gt;
&lt;p&gt;&lt;img src="http://kbyte.snowpenguin.org/portal/wp-content/uploads/2014/11/nagios.png" /&gt;&lt;/p&gt;
&lt;h2 id="requirements"&gt;Requirements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Python3 (For RHEL/CentOS 7 &lt;code&gt;yum install python34&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;python-nagiosplugin &lt;a href="https://packagecloud.io/app/s_mcleod/centos7/search?q=python-nagiosplugin"&gt;My pre-built RPMs&lt;/a&gt; or &lt;code&gt;pip3 install nagiosplugin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kbytesys/pynagsystemd/blob/master/bin/pynagsystemd.py"&gt;PyNagSystemD&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><author>smcleod.net</author><pubDate>Mon, 23 May 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2016/05/monitoring-systemd-units-with-nagios/</guid></item><item><title>Online Conversion from SQL_ASCII to UTF8 in PostgreSQL</title><link>https://smcleod.net/2016/05/online-conversion-from-sql_ascii-to-utf8-in-postgresql/</link><description>&lt;p&gt;Scripts and source available here: &lt;a href="https://github.com/sammcj/sql_ascii_to_utf8"&gt;sql_ascii_to_utf8&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="the-goal"&gt;The Goal&lt;/h2&gt;
&lt;p&gt;To be able to take a Postgres Database which is in SQL_ASCII encoding, and import it into a UTF8 encoded database.&lt;/p&gt;
&lt;p&gt;Requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python3 (For RHEL/CentOS 7 &lt;code&gt;yum install python34&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;python-nagiosplugin &lt;a href="https://packagecloud.io/app/s_mcleod/centos7/search?q=python-nagiosplugin"&gt;My pre-built RPMs&lt;/a&gt; or &lt;code&gt;pip3 install nagiosplugin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kbytesys/pynagsystemd/blob/master/bin/pynagsystemd.py"&gt;PyNagSystemD&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-problem"&gt;The Problem&lt;/h2&gt;
&lt;p&gt;PostreSQL will generate errors like this if it encounters any non-UTF8 byte-sequences during a database restore:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="chroma" tabindex="0"&gt;&lt;code class="language-shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pg_dump -Fc test_badchar | pg_restore -d test_badchar_utf8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_restore: &lt;span class="o"&gt;[&lt;/span&gt;archiver &lt;span class="o"&gt;(&lt;/span&gt;db&lt;span class="o"&gt;)]&lt;/span&gt; Error &lt;span class="k"&gt;while&lt;/span&gt; PROCESSING TOC:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_restore: &lt;span class="o"&gt;[&lt;/span&gt;archiver &lt;span class="o"&gt;(&lt;/span&gt;db&lt;span class="o"&gt;)]&lt;/span&gt; Error from TOC entry 2839&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;26852&lt;/span&gt; TABLE DATA table101 postgres
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_restore: &lt;span class="o"&gt;[&lt;/span&gt;archiver &lt;span class="o"&gt;(&lt;/span&gt;db&lt;span class="o"&gt;)]&lt;/span&gt; COPY failed &lt;span class="k"&gt;for&lt;/span&gt; table &lt;span class="s2"&gt;"table101"&lt;/span&gt;: ERROR:  invalid byte sequence &lt;span class="k"&gt;for&lt;/span&gt; encoding &lt;span class="s2"&gt;"UTF8"&lt;/span&gt;: 0x91
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CONTEXT:  COPY table101, line &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;WARNING: errors ignored on restore: &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And the corresponding data will be omitted from the database (in this case, the whole table, even the rows which did not have a problem):&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Mon, 23 May 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2016/05/online-conversion-from-sql_ascii-to-utf8-in-postgresql/</guid></item><item><title>More Victoria Line output</title><link>https://rjp.is/blogging/posts/more-victoria-line-output-2/</link><description>More ambient drones from the Victoria Line samples provided by TFL/Matt Rogers.</description><author>infrequent oscillations</author><pubDate>Fri, 20 May 2016 12:16:52 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/more-victoria-line-output-2/</guid></item><item><title>Hack, HHVM and avoiding the Second-system effect</title><link>https://bytepawn.com/hack-hhvm-second-system-effect.html</link><description>&lt;p&gt;I read this book on my first vacation after I started working at Facebook and thus became a semi-regular &lt;a href="http://hhvm.com/"&gt;Hack/HHVM&lt;/a&gt; user. I highly recommend reading (parts of) it. But not to learn Hack/PHP, which is irrelevant to most people. Instead, it’s to learn about how Facebook improved it’s www codebase and performance without rewriting the old PHP code in one big effort, and thus avoided the famous Second-system effect.&lt;br /&gt;&lt;br /&gt;&lt;img alt="Hack book" src="/images/hack_book.jpg" /&gt;&lt;/p&gt;</description><author>Bytepawn - Marton Trencseni</author><pubDate>Sat, 14 May 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://bytepawn.com/hack-hhvm-second-system-effect.html</guid></item><item><title>TFL and the Victoria Line samples</title><link>https://rjp.is/blogging/posts/tfl-and-the-victoria-line-samples-2/</link><description>In which we borrow some samples to make some tunes.</description><author>infrequent oscillations</author><pubDate>Tue, 10 May 2016 11:29:08 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/tfl-and-the-victoria-line-samples-2/</guid></item><item><title>Speeding Up rsync</title><link>https://smcleod.net/2016/05/speeding-up-rsync/</link><description>&lt;p&gt;The most common way to use rsync is probably as such:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="chroma" tabindex="0"&gt;&lt;code class="language-shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rsync -avr user@&amp;lt;source&amp;gt;:&amp;lt;source_dir&amp;gt; &amp;lt;dest_dir&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Resulting in 30-35MB/s depending on file sizes&lt;/p&gt;
&lt;p&gt;This can be improved by using a more efficient, less secure encryption algorithm, disabling compression
and telling the SSH client to disable some unneeded features that slow things down.&lt;/p&gt;
&lt;p&gt;With the settings below I have achieved 100MB/s (at work between VMs) and over 300MB/s at home between SSD drives.&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Tue, 03 May 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2016/05/speeding-up-rsync/</guid></item><item><title>Benchmarking IO with FIO</title><link>https://smcleod.net/2016/04/benchmarking-io-with-fio/</link><description>&lt;h2 id="this-is-a-quick-tldr-there-are-many-other-situations-and-options-you-could-consider"&gt;This is a quick tldr there are &lt;em&gt;many&lt;/em&gt; other situations and options you could consider&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://linux.die.net/man/1/fio"&gt;FIO man page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;IOP/s = Input or Output operations per second&lt;/li&gt;
&lt;li&gt;Throughput = How many MB/s can you read/write continuously&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="variables-worth-tuning-based-on-your-situation"&gt;Variables worth tuning based on your situation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--iodepth&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The iodepth is very dependant on your hardware.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Rotational drives without much cache and high latency (i.e. desktop SATA drives) will not benefit from a large iodepth, Values between 16 to 64 could be sensible.&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Fri, 29 Apr 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2016/04/benchmarking-io-with-fio/</guid></item><item><title>3 Reasons why I gave up the Ghost</title><link>https://benovermyer.com/blog/2016/04/3-reasons-why-i-gave-up-the-ghost/</link><description>&lt;p&gt;This's about why I quit paying $10/month for a hosted Ghost blog and migrated everything back to a self-hosted WordPress blog. It wasn't easy, and I lost all images in the process, but here's why I made that leap.&lt;/p&gt;
&lt;h1 id="getting-my-finances-in-order"&gt;Getting my finances in order&lt;/h1&gt;
&lt;p&gt;$10.00 USD per month isn't much for someone in my socioeconomic class. It covers two deluxe lattés. However, I recently got hit with the Hammer of Reality, and I'm culling all unnecessary expenses. My definition of "unnecessary" got a big revision. As someone who makes roughly six figures a year, I can afford to spend money on things that have no real bearing on my happiness but satisfy temporary impulses. But I don't want to do that anymore. My family (id est, my dad) has always done that, and I inherited that behavior. But I'm not cool with it anymore. Not when over 30% of my take-home income is spent on debt. So, with &lt;a href="http://www.daveramsey.com/get-started/debt" rel="external"&gt;the teachings of Dave Ramsey&lt;/a&gt; once again firmly in my mind, and the experience of life recently burned in there, I'm improving the efficiency of my expenses. In this case, that means self-hosting my blog, since I already pay for a &lt;a href="https://www.digitalocean.com/" rel="external"&gt;Digital Ocean droplet&lt;/a&gt; to host other sites I manage.&lt;/p&gt;
&lt;h1 id="wordpress-is-more-mature"&gt;WordPress is more mature&lt;/h1&gt;
&lt;p&gt;Over the past year, not much has changed with Ghost. It's still the same basic Markdown-based blog engine that it was two years ago. Its market share (and, more importantly, developer mind share) has not significantly increased. By comparison, WordPress has seen thousands of new plugins, hundreds of new themes, and unmeasurable numbers of code contributions to plugins, themes, and WordPress core over the same time period. I could hate WordPress. It's written in PHP and follows code practices that are a decade out of date. However, I must recognize the stability of the platform, and the passion and strength of its community. There are a number of people much smarter and more experienced than myself who've made significant contributions to WordPress just over the past year. When it comes to maintaining a system on your own, the predictability and resilience of that system are very important metrics to consider.&lt;/p&gt;
&lt;h1 id="i-am-in-full-control-of-my-content"&gt;I am in full control of my content&lt;/h1&gt;
&lt;p&gt;This is not really so much a dig on Ghost as it is a dig on self-hosting versus hosted blogs. My reason for going with a self-hosted WordPress blog is the same reason I discounted going with WordPress.com hosting. I run the database behind the blog. I am in full control of every byte stored there. Whether it's backed up or not, where it's backed up, how it's backed up, that's all in my realm of control. I determine the version of PHP, the version of MySQL, and the version of Linux that hosts it all. I alone control access to the server, and how incoming (and outgoing) connections are treated. As someone who's spent the last year and a half as a site reliability engineer/manager, that has suddenly become of vital concern to me. And renting a VPS (Virtual Private Server) is much different than trusting someone else to manage your environment for you. The next step up, fully controlling the environment from bare metal on up, is too expensive for someone like me to handle on my own.&lt;/p&gt;
&lt;h1 id="so-to-sum-up-or-tl-dr"&gt;So, to sum up (or TL/DR)...&lt;/h1&gt;
&lt;p&gt;I changed back to self-hosted WordPress from Ghost because A) I spend less money, B) I believe that WordPress is more likely to be supported in the future, and C) I like being able to control (almost) every aspect of how my blog exists.&lt;/p&gt;</description><author>Ben Overmyer's Site</author><pubDate>Mon, 25 Apr 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://benovermyer.com/blog/2016/04/3-reasons-why-i-gave-up-the-ghost/</guid></item><item><title>A Collection of O'rly book Covers</title><link>https://boyter.org/2016/04/collection-orly-book-covers/</link><description>&lt;p&gt;A quick collection of all the fake Orly book covers I find around on the internet.&lt;/p&gt;
&lt;p&gt;I am seriously considering writing content for the &amp;ldquo;Expert Excuses for Not Writing Unit Tests&amp;rdquo; one.&lt;/p&gt;
&lt;p&gt;EDIT - I actually did write content and publish it as a book! &lt;a href="https://leanpub.com/expertexcusesfornotwritingunittests"&gt;Expert Excuses for Not Writing Unit Tests&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cj0Up_hUUAAn8-g.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ChnulxvW0AEUs1J.jpg-large.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cn1rWcbWcAAgsCA.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cg0x8vnXEAEB2Le.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ChsfXudXAAA__sz.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Co3D6-xWEAA8eYW.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Co8UV3xWgAALxmN.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cp03W2QWAAAMuMK.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cp6WqQdWAAEpvFt.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CphhR1GW8AAeOkg.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CprNb0PWEAAFS3F.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CpvvUyXW8AQgO1K.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CpWvVOoW8AAjYmB.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CmDdopVXIAAujQK.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CmIDaoVXEAA2y7g.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CmtLI0GWYAAGavB.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CnDD1t0XgAQMXJA.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CnrAQj8XYAAVYB2.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cf7eHZ1W4AEeZJA.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cfdj5HCWIAAAzFU.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cfh9oRrXIAAiA2Y.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CfNJTAHWAAAik5I.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CfSQdwUW8AErog1.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CfxJxUzWQAAs0nw.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CfYA-8BXEAAtz2k.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cg-zWsMWwAEJ-Zn.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CgbR1wkXEAAMjqP.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CgGkN6YVAAAZ3_1.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CgkllENU0AI0tQK.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CgQNvaIWQAQ_dGk.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CgVtA2IWQAAWBrd.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Ch8KJiEWsAA9hY-.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ChdhDa5XEAAK36t.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ChDzLqTWUAA2jtr.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ChinzjeWgAAeS2x.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ChJzv9lUYAA9D5E.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ChN6FVeWwAAwP_z.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ChnManpWwAANzGq.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ChUn34OU0AAQkvf.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CiBRPWPXEAAsXM8.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CiHHf9-UYAA6aVB.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CilkrypWEAArFfo.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CiQ0haFWgAARgpx.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cjyp4gAWgAAVxZo.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CkNF9qtWUAAO3D_.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cllb9urWMAAKaz4.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Crrj1blWYAAkNN_.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CtVNivsWgAAKhKA.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/pRDPMx2.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/OD3hWSR.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CxzX0scXUAA21uo.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/CyDDghxUcAAqrNx.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/C1_sRq9XgAADMzY.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/C1hNdR9XUAEtlmP.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/C1QCiNuUoAAYESs.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/C3cX4w5VcAENYA7.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/C3d7VlsUcAE4Vkh.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Cr7mS_OWcAA7Hzt.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/download.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/C59ScRHVMAA5nin.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/Image-uploaded-from-iOS.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/C8lePKsXcAAt5Fc.jpg-large.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/a0f278b167ec23c35fe091f38096571a.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/DVfL0c-VoAEFs1R.jpg-large.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/another.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/rust1.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/rust2.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/waf.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/new1.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/new2.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/new3.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/new4.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/new5.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/containers.jpg" /&gt;
&lt;img alt="Infinidash Book Cover" src="https://boyter.org/static/books/infinidash.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/1.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/2.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/3.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/4.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/5.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/6.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/11532f7a4fc4de43b864d8b85a433294.gif" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/1a3abd00b73f0f17288a4e70c3b7bfaf.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/1ade592a58b959311c458696cbc7369d.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/1b5d04eb0c26541260e53e7abb4a489c.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/277a0f2733bc01ec7710a51faca1de31-2.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/28abe64b81f7561535be220824fa8103.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/2ab5cf8939174ad9f15e37b5c3b3455d.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/2c4c9b3070518409dd3bb60866376e94.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/32c547d3a60c154f1fb64aa839595ae0.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/3469a019cffdcb02b7c6c2c988d5e262.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/3773aca56954ca81e5a0a4a2b8e57a7c.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/3b6f0699bfc1861a72a1d08fbaad2c72.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/3caf4bf9aa8beb1e62823036a0b0a512.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/42e693e90db078e00e7936c702dcd958.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/4b1ed080f643e3e5562f05f6d6bd26f9-2.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/4cecc403e48d3602d0266f70ce9707cd.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/4d10ff3f2dc4d74dcb6005e1d955024a.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/502ca10c8dbcbd2329970a72c3dd9691.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/53d09aba945d976a2ea690d6f5e5a146.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/59248dad5f27b1c9ecbbf1598cdbe8e0-2.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/5edb2981ac2f117f5516c8dc57b5520b.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/6b4b2578b56c906e43905b6f3eacb188.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/6dbac0c61d6ea675f35c3c8cd702643d.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/73c16e3aeb3a5ebc7a5eddf2ad816e34.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/7688ba098f2541663e0aca3b636e40ce-2.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/7b45b468fdbfbffe7a7b491baebd2223.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/7d4b7c5e2eb02223e2a1dc99502c8024.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/84c9c66c6aae83c9bf7df98e30868901.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/8b9bb089f6f4d9e2bb34219db7c6e4de.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/8e4884dc8c7889b870e4ef9090aec92f-2.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/93bdca38eae9abc46cb51eb651600f8b.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/a003ef423713a4bbe5c99699b91d1b36.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/a19a39a26066b4dd253e19d801247db5.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/a3e3c5061c3bcc51e6012d58986d03b7.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ad1f9bed6a6fffa6bcf2910d118c7e79.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/aecf5a2fe6f759c86a71b3287e0928db.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/af15681769d0a18acb338ca15e6f3d61.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/afeb22a3feebbcaddb776834ef5edbbf.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/b86a4508477fec723e94599d97560a6e.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/c17b82922cbcd232c901a251d09676c4.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/cbb11cdd02d03ce2e1d412c71530f96e.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ce4376ffcb7e04b59e4bfc70b7f6917d.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ce8d47902f84b0188979ffb7b265007c-2.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/d7b5d66c5a2a787986b91792db48ec7d.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/d82e9f3ef8800bbb7d11bad32aac4d97.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/dbc8738228a3abe37136fcc6fdd6eec8-2.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/e011c9c775c8168f45248d77626addfd.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/e1120a9e3abfecff3ac50527e1b3556f-2.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/ee6ab48856007bb7aee35446391474b3.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/f063fd899d4dfc5b77bf6a29cb6ef9ef.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/f7598a1d0e03c6bcaab55ca4160898ac.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/f8153cfdbe0a117e6386fa7051976063-2.jpeg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/fe79f4a4b464936db0762e1ee53427c7.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/FGMeVj7VEAM7Zni.png" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/b1.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/b2.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/b3.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/b4.jpg" /&gt;
&lt;img alt="Book Cover" src="https://boyter.org/static/books/gpt.jpg" /&gt;&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Fri, 22 Apr 2016 03:48:41 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/04/collection-orly-book-covers/</guid></item><item><title>Moving back to WordPress.</title><link>https://benovermyer.com/blog/2016/04/moving-back-to-wordpress/</link><description>&lt;p&gt;I'm transitioning away from hosted Ghost back to WordPress. More about this later.&lt;/p&gt;</description><author>Ben Overmyer's Site</author><pubDate>Fri, 22 Apr 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://benovermyer.com/blog/2016/04/moving-back-to-wordpress/</guid></item><item><title>Switching away from iPhone</title><link>https://benovermyer.com/blog/2016/04/switching-away-from-iphone/</link><description>&lt;p&gt;Yesterday I went on the Google Fi site and signed up for a Nexus 6P and a data plan roughly equivalent to what I spend at Verizon. My iPhone 6 Plus, despite not (yet) being paid off, is going to sit in a drawer collecting dust starting late next week when the Nexus arrives. Am I displeased with the iPhone? No, not especially. Am I unhappy with Verizon? Well yeah, that's kind of a given for any Verizon customer. I have personal reasons for needing a new phone on a new carrier, but I also have a professional interest in Google Fi and the way it handles mobile phones. We'll see where this goes.&lt;/p&gt;</description><author>Ben Overmyer's Site</author><pubDate>Fri, 15 Apr 2016 03:00:00 GMT</pubDate><guid isPermaLink="true">https://benovermyer.com/blog/2016/04/switching-away-from-iphone/</guid></item><item><title>searchcode server released</title><link>https://boyter.org/2016/03/searchcode-server-released/</link><description>&lt;p&gt;searchcode server the &lt;a href="https://searchcode.com/product/"&gt;downloadable self hosted version of searchcode.com&lt;/a&gt; is now available. A large amount of work went into the release with a variety of improvements based on feedback from the general beta releases.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;searchcode server has a number of advantages over searchcode.com that will eventually be back-ported in. The full list of things to check out is included below,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New Single Page Application UI for smooth search experience&lt;/li&gt;
&lt;li&gt;Ability to split on terms so a search for &amp;ldquo;url signer&amp;rdquo; will match &amp;ldquo;UrlSigner&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Massively improved performance 3x in the worst case and 20x in the best&lt;/li&gt;
&lt;li&gt;Configurable through UI and configuration&lt;/li&gt;
&lt;li&gt;Spelling suggestion that learns from your code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A few things of note,&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Fri, 01 Apr 2016 00:19:33 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2016/03/searchcode-server-released/</guid></item><item><title>Weekend Panoramas</title><link>https://rjp.is/blogging/posts/weekend-wandering-panoramas-2/</link><description>Some panoramas from my weekend wandering.</description><author>infrequent oscillations</author><pubDate>Wed, 16 Mar 2016 13:52:00 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/weekend-wandering-panoramas-2/</guid></item><item><title>So, You Want to Leave America</title><link>https://benovermyer.com/blog/2016/03/so-you-want-to-leave-america/</link><description>&lt;p&gt;Many people (more people than ever before, apparently) are declaring their intention to move away from America permanently if Candidate X wins the election for President of the United States in November.&lt;/p&gt;
&lt;p&gt;I won't lie, I was one of those. But then I started digging into what that meant.&lt;/p&gt;
&lt;p&gt;See, I've done it before. In 2000, my parents, sister, and I all moved together to New Zealand when George W. Bush won the election. It was more than a little bit of a political decision.&lt;/p&gt;
&lt;p&gt;Don't get me wrong, New Zealand was amazing. Most of the best memories of my entire life happened in the four years I lived there. But I also acutely remember the cost.&lt;/p&gt;
&lt;p&gt;New Zealand was a relatively safe choice. The primary language was English. The legal system was fairly similar to the United States'. Most of the culture was familiar, if a little different. But it was really expensive, and not just in the material cost of goods. New Zealand is a remote island nation at the end of the world. Internet usage at the time was far more expensive than in the USA. My family lost touch with almost everyone we had known. I experienced my first real sense of profound loss as a result.&lt;/p&gt;
&lt;p&gt;If you choose to leave the United States for political reasons, you need to seriously consider a few things. All of the following assumes that you and yours are leaving because you're appalled at the political situation, and not in immediate physical danger because of the election's result. If you fall into the latter category, this post doesn't apply to you, and you should get your family to safety as soon as possible.&lt;/p&gt;
&lt;p&gt;If you are leaving because you disagree with the country's choice of leader, then you need to make damn sure that the country you're choosing to emigrate to follows your own political beliefs. If you pick a country that's MORE extreme than the president apparent, then you may as well have just saved yourself the trouble and stayed home, because you're in for a world of hurt.&lt;/p&gt;
&lt;p&gt;On the other hand, if your host country of choice is politically favorable, you have a ton of other considerations to keep in mind. If you've spent your entire life in one part of the USA, then you're basically f***ed, in terms of culture shock. It will hurt, and it will hurt bad, to discover that everything you're familiar with is either A) extremely different, B) absent, or worse, C) slightly different. Let me elaborate.&lt;/p&gt;
&lt;p&gt;My sister was brought to tears by all pickles in New Zealand being basically sweet miniature-as-in-quark-sized pickles. The straw that shattered the camel's back, as it were. I saw the same kind of reaction by most of the American ex-pats I met in NZ. Not to pickles, mind you, but to the little things.&lt;/p&gt;
&lt;p&gt;A relatively small portion of the world has English as its mother tongue. Sure, it's spoken just about everywhere, and you'll get on OK in most developed or even developing nations. But there is a marked difference in communicating with someone in identical preferred languages and in your preferred language but the other person's second language. This is particularly true in countries where English is recognized as a business necessity but not a cultural one, such as eastern Asian countries.&lt;/p&gt;
&lt;p&gt;Let's say you're able to adapt to the language barrier, and to the availability barrier. Congratulations on defying the two biggest hurdles. Now how are you going to deal with the fact that people in your host country don't understand your pet peeves, or your quirks that you thought were common, or your personal passions that have no support locally? How about the prejudice that the locals feel towards Americans, which is basically universal in all countries that are aware of the USA? Are you ready for that? Are you willing to subject your family to that?&lt;/p&gt;
&lt;p&gt;OK, so you're still ready to go. You've got your passports, and you've secured your visas. You understand the financial and cultural pitfalls. You still think that leaving the USA is the best choice, given the alternative. OK, that's fine. Before you commit to a particular country, then you better damn well visit each of your prospective host countries for at least a month each (you DO have multiple options, right?) before making the big move.&lt;/p&gt;
&lt;p&gt;Because I will tell you, as someone who has done it and is considering doing it again, leaving your home country is one of the hardest goddamn things you can do to yourself or your family.&lt;/p&gt;
&lt;p&gt;On the other hand, you might be of the YOLO type, in which case ignore everything I've warned you about above. It might be the most amazing adventure of your entire life.&lt;/p&gt;</description><author>Ben Overmyer's Site</author><pubDate>Mon, 14 Mar 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://benovermyer.com/blog/2016/03/so-you-want-to-leave-america/</guid></item><item><title>Segfaulting Python with afl-fuzz</title><link>https://tomforb.es/blog/segfaulting-python-with-afl-fuzz/</link><description>American Fuzzy Lop is both a really cool tool for fuzzing programs and an adorable breed of bunny. In this post I’m going to show you how to get the the tool (rather than the rabbit) up and running and find some crashes in the cPython interpreter. Fuzzing? Explaining in detail what fuzzing is would ...</description><author>Tom Forbes</author><pubDate>Mon, 07 Mar 2016 00:31:37 GMT</pubDate><guid isPermaLink="true">https://tomforb.es/blog/segfaulting-python-with-afl-fuzz/</guid></item><item><title>I Am Done With the Mac App Store</title><link>https://donatstudios.com/IAmDoneWithTheAppStore</link><description>&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; Do not depend on App Store Apps, Apple can and will pull the carpet out from under you.&lt;/p&gt;
&lt;p&gt;Reading &lt;a href="https://news.ycombinator.com/item?id=11219208"&gt;Hacker News&lt;/a&gt; today there is an article about how &lt;a href="https://tidbits.com/article/16302"&gt;OS X Installers&lt;/a&gt; stopped working on February 14th, 2016. This is due to an expired certificate Apple used to sign the binaries with.  &lt;/p&gt;
&lt;p&gt;In that same time range I had a handful of Apps &lt;strong&gt;purchased&lt;/strong&gt; from the App store suddenly and &lt;em&gt;mysteriously&lt;/em&gt; stop working. They just quit. No dialog, no error mesasage, nothing at all. Apps I &lt;strong&gt;paid for&lt;/strong&gt; and &lt;strong&gt;depend on&lt;/strong&gt; just stopped working.&lt;/p&gt;
&lt;p&gt;The thing they all these Apps have in common is they are no longer available from the App store and have not been updated in several years. I am nearly certain that this is the same signing issue.&lt;/p&gt;
&lt;p&gt;If this is the case, this means all Apps from the app store are signed &lt;strong&gt;built-in self destruct&lt;/strong&gt; date. One which only Apple or the original author can fix.&lt;/p&gt;
&lt;p&gt;I have been careful to keep backups of the &lt;code&gt;.app&lt;/code&gt;’s.  Apple dropped the ability to re-download App's removed from the App store.&lt;/p&gt;
&lt;p&gt;This gives way too much power over my work to third parties. Software I paid for should not stop working because someone else stopped supporting it.  How can someone build a reliable work-flow when any program stop working at any time? You can't, that’s simply insanity.&lt;/p&gt;
&lt;p&gt;One of the apps I used daily, the author &lt;a href="https://sophiestication.com/sevenyears/"&gt;took down&lt;/a&gt; a few years ago because it “flopped and [was] plagued with technical issues”. I have encountered no technical issues with it until this point, and it an important part of my work-flow.&lt;/p&gt;
&lt;p&gt;I, as well as others have asked the author to open source it on many occasions. &lt;a href="https://twitter.com/donatj/status/459357498462326784"&gt;[1]&lt;/a&gt;, &lt;a href="https://twitter.com/donatj/status/560141498478383104"&gt;[2]&lt;/a&gt;, &lt;a href="https://twitter.com/donatj/status/565658296087248896"&gt;[3]&lt;/a&gt;, &lt;a href="https://twitter.com/donatj/status/613455514563801088"&gt;[4]&lt;/a&gt; … &lt;small&gt;There’s more&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Her only response to our cries has been a cringe-worthy &lt;code&gt;LOL&lt;/code&gt;. I wish I were joking.&lt;/p&gt;
&lt;p&gt;The moral of my story comes down to the following life lessons.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don’t depend on things that others can take from you. &lt;/li&gt;
&lt;li&gt;Be able to scratch your own itch; seek open source when at all possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I will no longer be purchasing things from the Mac App Store. The convenience is not worth the incredible down sides.&lt;/p&gt;
&lt;p&gt;Richard Stallman has been warning us for years, I should have listened.&lt;/p&gt;</description><author>Donat Studios</author><pubDate>Fri, 04 Mar 2016 07:44:46 GMT</pubDate><guid isPermaLink="true">https://donatstudios.com/IAmDoneWithTheAppStore</guid></item><item><title/><link>/2016/02/28/</link><description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;Notice&lt;/strong&gt;: Much of this post still applies, but now applies more directly to Citus. Since this post originally published, pg_shard is now deprecated. You can find some further guidance for sharding on the Citus blog and docs&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Back in 2012 I wrote an overview of database sharding. Since then I&amp;rsquo;ve had a few questions about it, which have really increased in frequency over the last two months. As a result I thought I&amp;rsquo;d do a deeper dive with some actual hands on for sharding. Though for this hands on, because I do value my time I&amp;rsquo;m going to take advantage of &lt;code&gt;pg_shard&lt;/code&gt; rather than creating mechanisms from scratch.&lt;/p&gt;
&lt;p&gt;For those unfamiliar &lt;a href="https://github.com/citusdata/pg_shard/"&gt;pg_shard&lt;/a&gt; is an open source extension from &lt;a href="http://citusdata.com"&gt;Citus data&lt;/a&gt; who has a commerical product that you can think of is pg_shard++ (and probably much more). Pg_shard adds a little extra to let data automatically distribute to other Postgres tables (logical shards) and Postgres databases/instances (physical shards) thus letting you outgrow a single Postgres node pretty simply.&lt;/p&gt;
&lt;p&gt;Alright, enough talk about it, let&amp;rsquo;s get things up and running.&lt;/p&gt;
&lt;h3 id="build-install"&gt;
&lt;div&gt;
Build, install
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;The rest assume you have Postgres.app, version 9.5 setup and are on a Mac, much of these steps could be easily adapted for other Postgres installs or OSes.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;PATH=/Applications/Postgres.app/Contents/Versions/latest/bin/:$PATH make&lt;/p&gt;
&lt;p&gt;sudo PATH=/Applications/Postgres.app/Contents/Versions/latest/bin/:$PATH make install&lt;/p&gt;
&lt;p&gt;cp /Applications/Postgres.app/Contents/Versions/9.5/share/postgresql/postgresql.conf.sample /Applications/Postgres.app/Contents/Versions/9.5/share/postgresql/postgresql.conf.sample&lt;/p&gt;
&lt;p&gt;Edit your &lt;code&gt;postgresql.conf&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#shared_preload_libraries = ''
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TO:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shared_preload_libraries = 'pg_shard'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then create a file in &lt;code&gt;/Users/craig/Library/Application\ Support/Postgres/var-9.5/pg_worker_list.conf&lt;/code&gt; where &lt;code&gt;craig&lt;/code&gt; is your username:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# hostname port-number
localhost 5432
localhost 5433
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You&amp;rsquo;ll also need to create a new Postgres instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;initdb -D /Users/craig/Library/Application\ Support/Postgres/var-9.5-2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then edit that &lt;code&gt;postgresql.conf&lt;/code&gt; inside that newly created folder with two main edits:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;port = 5432
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;port = 5433
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally setup our database then start it up:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;createdb instagram
postgres -D /Users/craig/Library/Application\ Support/Postgres/var-9.5-2
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="setup"&gt;
&lt;div&gt;
Setup
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Now you should have two running instances of Postgres, now let&amp;rsquo;s finally turn on the pg_shard extension, create some tables and see what we have. First connect to your main running Postgres instance, so in this case the the instagram database we first created &lt;code&gt;psql instagram&lt;/code&gt;, then let&amp;rsquo;s set things up:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE EXTENSION pg_shard;
CREATE TABLE customer_reviews (customer_id TEXT NOT NULL, review_date DATE, review_rating INTEGER, product_id CHAR(10));
CREATE TABLE
Time: 4.734 ms
SELECT master_create_distributed_table(table_name := 'customer_reviews', partition_column := 'customer_id');
master_create_distributed_table
---------------------------------
(1 row)
SELECT master_create_worker_shards(table_name := 'customer_reviews', shard_count := 16, replication_factor := 2);
master_create_worker_shards
-----------------------------
(1 row)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="understanding-and-using"&gt;
&lt;div&gt;
Understanding and using
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;So that was a lot of initial setup. But now we have an application that could in theory scale to a shared application across 16 instances. If you want a refresher, there&amp;rsquo;s a difference between physical and logical shards. In this case above we have 16 logical ones and it&amp;rsquo;s replicated across 2 physical Postgres instances albeit on the same instance.&lt;/p&gt;
&lt;p&gt;Alright so a little more poking under the covers to see what happened before we actually start doing something with our data. If you&amp;rsquo;re still connected go ahead and run &lt;code&gt;\d&lt;/code&gt;, and you should see:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; List of relations
Schema | Name | Type | Owner
--------+------------------------+-------+-------
public | customer_reviews | table | craig
public | customer_reviews_10000 | table | craig
public | customer_reviews_10001 | table | craig
public | customer_reviews_10002 | table | craig
public | customer_reviews_10003 | table | craig
public | customer_reviews_10004 | table | craig
public | customer_reviews_10005 | table | craig
public | customer_reviews_10006 | table | craig
public | customer_reviews_10007 | table | craig
public | customer_reviews_10008 | table | craig
public | customer_reviews_10009 | table | craig
public | customer_reviews_10010 | table | craig
public | customer_reviews_10011 | table | craig
public | customer_reviews_10012 | table | craig
public | customer_reviews_10013 | table | craig
public | customer_reviews_10014 | table | craig
public | customer_reviews_10015 | table | craig
(17 rows)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see that under the cover there&amp;rsquo;s a lot more &lt;code&gt;customer_reviews&lt;/code&gt; tables, in reality you don&amp;rsquo;t have to think about these or do anything with them. But just for reference they&amp;rsquo;re just plain ole Postgres tables under the cover. You can query them and poke at the data. The now mystical &lt;code&gt;customer_reviews&lt;/code&gt; will actually roll up the data across all your logical shards (tables) and physical shards (spanning across machines).&lt;/p&gt;
&lt;p&gt;&lt;em&gt;It&amp;rsquo;s also of note that in production you might not actually use your primary DB as a worker, we did this more for expediency in setting it up on a local Mac. More typically you&amp;rsquo;d have 2 or more workers which are not the same a the primary, these were the ports we setup in our &lt;code&gt;pg_worker_list.conf&lt;/code&gt;.&lt;/em&gt; A common setup would look something more like:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://s3.amazonaws.com/f.cl.ly/items/3T2N2Q1K041g0a0L0j03/Untitled.png?v=7df00f6b" /&gt;&lt;/p&gt;
&lt;p&gt;So now start inserting away:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INSERT INTO customer_reviews (customer_id, review_rating) VALUES ('HN802', 5);
INSERT INTO customer_reviews (customer_id, review_rating) VALUES ('FA2K1', 10);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For extra homework on your own you can now go and poke at where the underlying data actually surfaced.&lt;/p&gt;
&lt;h3 id="conclusion"&gt;
&lt;div&gt;
Conclusion
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Yes, there&amp;rsquo;s a number of limitations that you can learn a bit more about over on the &lt;a href="https://github.com/citusdata/pg_shard#limitations"&gt;github repo for pg_shard&lt;/a&gt;. Though even with those it&amp;rsquo;s very usable as is, and let&amp;rsquo;s you get quite far in prepping an app for sharding. While I will say that all apps think they&amp;rsquo;ll need sharding and few actually do, given &lt;code&gt;pg_shard&lt;/code&gt; it&amp;rsquo;s minimal extra effort now to plan for such scaling should you need it.&lt;/p&gt;
&lt;p&gt;Up next we&amp;rsquo;ll look at how it&amp;rsquo;d work with a few languages, so you can get an idea of the end to end experience.&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Sun, 28 Feb 2016 22:55:56 GMT</pubDate><guid isPermaLink="true">/2016/02/28/</guid></item><item><title>$ curl poptart.spinda.net</title><link>https://spindas.dreamwidth.org/2765.html</link><description>&lt;img alt="" src="https://www.spinda.net/files/blog/nya.gif" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img alt="comment count unavailable" height="12" src="https://www.dreamwidth.org/tools/commentcount?user=spindas&amp;amp;ditemid=2765" style="vertical-align: middle;" width="30" /&gt; comments</description><author>spinda's dreamwidth</author><pubDate>Sun, 28 Feb 2016 02:17:14 GMT</pubDate><guid isPermaLink="true">https://spindas.dreamwidth.org/2765.html</guid></item><item><title>Unofficial witty cloud module documentation with nodemcu firmware</title><link>https://anisse.astier.eu/unofficial-witty-cloud-module-documentation-with-nodemcu-firmware.html</link><description>&lt;p&gt;I wanted to try my hand with ESP8266 modules, so I got &lt;a href="http://www.aliexpress.com/item/ESP8266-serial-WIFI-Witty-cloud-Development-Board-ESP-12F-module/32557886226.html"&gt;a witty cloud development board&lt;/a&gt;. It's running a proprietary firmware from gizwits which I &lt;a href="/static/witty-flash-backup.bin.gz"&gt;backed up&lt;/a&gt; if anyone wants to look at it.&lt;/p&gt;
&lt;p&gt;The board is in two parts: programming board("cape") with ch340g usb serial and 3 …&lt;/p&gt;</description><author>Linux Engineer's random thoughts</author><pubDate>Thu, 25 Feb 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://anisse.astier.eu/unofficial-witty-cloud-module-documentation-with-nodemcu-firmware.html</guid></item><item><title>A better rich text editor for Dreamwidth</title><link>https://spindas.dreamwidth.org/2452.html</link><description>&lt;p&gt;For whatever reason, Dreamwidth’s default rich text editor (built on an old version of FCKEditor) hides a lot of the available toolbar buttons. I’ve written a quick userscript that enables all available buttons in the editor, and also increases the height a bit to make writing more pleasant. I’ve tested it on Firefox with GreaseMonkey; presumably it should work on Chrome/Chromium as well.&lt;/p&gt;



&lt;pre class="prettyprint"&gt;&lt;code class="language-javascript hljs "&gt;&lt;span class="hljs-comment"&gt;// ==UserScript==&lt;/span&gt;
&lt;span class="hljs-comment"&gt;// @name        Better Dreamwidth Editor&lt;/span&gt;
&lt;span class="hljs-comment"&gt;// @namespace   betterdweditor&lt;/span&gt;
&lt;span class="hljs-comment"&gt;// @include     https://www.dreamwidth.org/update?usejournal=spindas&lt;/span&gt;
&lt;span class="hljs-comment"&gt;// @include     https://www.dreamwidth.org/editjournal*&lt;/span&gt;
&lt;span class="hljs-comment"&gt;// @version     1&lt;/span&gt;
&lt;span class="hljs-comment"&gt;// @grant       none&lt;/span&gt;
&lt;span class="hljs-comment"&gt;// ==/UserScript==&lt;/span&gt;

window.onload = &lt;span class="hljs-function"&gt;&lt;span class="hljs-keyword"&gt;function&lt;/span&gt; &lt;span class="hljs-params"&gt;()&lt;/span&gt; {&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;var&lt;/span&gt; frame = document.getElementById(&lt;span class="hljs-string"&gt;'draft___Frame'&lt;/span&gt;);
  frame.onload = &lt;span class="hljs-function"&gt;&lt;span class="hljs-keyword"&gt;function&lt;/span&gt; &lt;span class="hljs-params"&gt;()&lt;/span&gt; {&lt;/span&gt;
    document.getElementById(&lt;span class="hljs-string"&gt;'draft___Frame'&lt;/span&gt;).style.height = &lt;span class="hljs-string"&gt;'600px'&lt;/span&gt;;
  };
  frame.src = &lt;span class="hljs-string"&gt;'https://www.dreamwidth.org/stc/fck/editor/fckeditor.html?InstanceName=draft&amp;amp;Toolbar=Default'&lt;/span&gt;;
};&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;img alt="comment count unavailable" height="12" src="https://www.dreamwidth.org/tools/commentcount?user=spindas&amp;amp;ditemid=2452" style="vertical-align: middle;" width="30" /&gt; comments</description><author>spinda's dreamwidth</author><pubDate>Tue, 23 Feb 2016 03:39:29 GMT</pubDate><guid isPermaLink="true">https://spindas.dreamwidth.org/2452.html</guid></item><item><title>Reverse engineering the Firewatch.camera API (and pranking r/Firewatch)</title><link>https://spindas.dreamwidth.org/2244.html</link><description>&lt;a href="http://firewatchgame.com"&gt;Firewatch&lt;/a&gt; is a story-centric game by &lt;a href="http://camposanto.com"&gt;Campo Santo&lt;/a&gt; and &lt;a href="https://panic.com"&gt;Panic&lt;/a&gt;. I played it all the way through this weekend  and had a really great time with it. Besides the top-notch voice acting, gorgeous  visuals, and mystery-filled plot, one feature that&amp;rsquo;s been getting a lot of  attention is the disposable camera the player carries through most of the game.  Starting with 18 unused shots on the roll, you can fill it up with snaps of  trees and trails and plenty of sunsets peaking over the hills. At the end  they&amp;rsquo;re all uploaded to a personal page on &lt;a href="https://firewatch.camera"&gt;Firewatch.camera&lt;/a&gt;, where you can share them  or order prints from the &amp;quot;Fotodome&amp;quot;.&lt;br /&gt;&lt;br /&gt;&lt;img alt="Firewatch photo upload screen" height="401" src="https://www.spinda.net/files/blog/firewatch/photo_upload_screen.png" width="690" /&gt;&lt;br /&gt;&lt;br /&gt;At the end of my own playthrough, I uploaded my shots and logged onto the site  to see them.&lt;br /&gt;&lt;br /&gt;&lt;img alt="My camera roll" height="579" src="https://www.spinda.net/files/blog/firewatch/my_camera_roll.png" width="684" /&gt;&lt;br /&gt;&lt;br /&gt;But one of them came out&amp;hellip; weird.&lt;span class="cut-wrapper"&gt;&lt;span class="cuttag" id="span-cuttag___1" style="display: none;"&gt;&lt;/span&gt;&lt;b class="cut-open"&gt;(&amp;nbsp;&lt;/b&gt;&lt;b class="cut-text"&gt;&lt;a href="https://spindas.dreamwidth.org/2244.html#cutid1"&gt;Read more...&lt;/a&gt;&lt;/b&gt;&lt;b class="cut-close"&gt;&amp;nbsp;)&lt;/b&gt;&lt;/span&gt;&lt;div id="div-cuttag___1" style="display: none;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img alt="comment count unavailable" height="12" src="https://www.dreamwidth.org/tools/commentcount?user=spindas&amp;amp;ditemid=2244" style="vertical-align: middle;" width="30" /&gt; comments</description><author>spinda's dreamwidth</author><pubDate>Fri, 19 Feb 2016 01:22:05 GMT</pubDate><guid isPermaLink="true">https://spindas.dreamwidth.org/2244.html</guid></item><item><title>Identifying days with exercise automagically</title><link>https://rjp.is/blogging/posts/identifying-days-with-exercise-automagically-2/</link><description>In which we use heart rate to detect exercise.</description><author>infrequent oscillations</author><pubDate>Wed, 17 Feb 2016 19:00:17 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/identifying-days-with-exercise-automagically-2/</guid></item><item><title>Einstein's amazing theory</title><link>https://bytepawn.com/einsteins-amazing-theory.html</link><description>&lt;p&gt;This post is about the amazing success of Einstein's general theory of relativity. The theory predicts, among other things the accelerating Universe, black holes, gravitational lensing and gravitational waves. The real shocker is to remember that Einstein didn't invent general relativity to explain these. He didn’t know about these, they didn't exist at that time!&lt;/p&gt;</description><author>Bytepawn - Marton Trencseni</author><pubDate>Tue, 16 Feb 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://bytepawn.com/einsteins-amazing-theory.html</guid></item><item><title>2015 in Review</title><link>https://captnemo.in/blog/2016/02/15/2015-in-review/</link><description>&lt;p&gt;2015 was a good year for me. I accomplished a lot of things, and was happy for most part of the year. In no particular order, here are the things that stand out for me:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="/blog/2015/07/20/hillhacks/"&gt;Went to HillHacks&lt;/a&gt;, and made lots of friends. Helped organize the conference.&lt;/li&gt;
  &lt;li&gt;Joined &lt;a href="https://razorpay.com"&gt;Razorpay&lt;/a&gt; in June&lt;/li&gt;
  &lt;li&gt;Moved to Bangalore&lt;/li&gt;
  &lt;li&gt;Announced my book, &lt;a href="https://captnemo.in/blog/2015/06/07/on-writing/"&gt;The Joy of Software Development&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Did lots of speaker things:
    &lt;ul&gt;
      &lt;li&gt;&lt;a href="https://captnemo.in/talks/josd/"&gt;Joy of Software Development&lt;/a&gt; talk at IIT Roorkee&lt;/li&gt;
      &lt;li&gt;Flash Talks on &lt;a href="https://docs.google.com/presentation/d/1qR3JuGU7FXry333qGfVvapshDn72oCjEN8l7bShQl2Y/pub?start=false&amp;amp;loop=false&amp;amp;delayms=3000"&gt;SDSLabs&lt;/a&gt;, &lt;a href="http://slides.com/captn3m0/ctf/"&gt;CTFs&lt;/a&gt; and a few more things at HillHacks&lt;/li&gt;
      &lt;li&gt;A full-length talk on the book itself at HillHacks&lt;/li&gt;
      &lt;li&gt;Did the &lt;a href="https://speakerdeck.com/captn3m0/hillhacks-quiz-2015"&gt;HillHacks&lt;/a&gt; and &lt;a href="https://docs.google.com/presentation/d/1glE2G1xKGkSVELVaQ7YJ4JGul0NLzfHRl1xGgMIwi9Q/pub?start=false&amp;amp;loop=false&amp;amp;delayms=3000"&gt;HackBeach&lt;/a&gt; quizes&lt;/li&gt;
      &lt;li&gt;Announced my &lt;a href="/homeopathy/"&gt;Homeopathy Bug Bounty Program&lt;/a&gt; at hackbeach.&lt;/li&gt;
      &lt;li&gt;Gave a talk on &lt;a href="http://slides.com/captn3m0/fun-with-http"&gt;Fun with HTTP&lt;/a&gt; at Barcamp Bangalore.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Learnt some slacklining at hackbeach. Helped with conference scheduling as well.&lt;/li&gt;
  &lt;li&gt;Made &lt;a href="https://hasgeek.com"&gt;lots&lt;/a&gt; of &lt;a href="http://nilenso.com"&gt;new friends&lt;/a&gt; at Bangalore.&lt;/li&gt;
  &lt;li&gt;Started playing board games, including being a DM at several Dungeons and Dragons sessions.&lt;/li&gt;
  &lt;li&gt;Started quizzing in bangalore as well. Mostly at Cluesday, Vapors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="reading"&gt;Reading&lt;/h2&gt;

&lt;p&gt;I started with a goal of 20 books for this year, and ended up reading about 28. Tried experimenting with Audiobooks near the year end, and failed. Bought a Kindle paperwhite as well. I tend to read a lot of Fantasy and SF, and this continued in 2015 as well. The best books I read this year (in order):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Lions of Al Rassan [&lt;a href="https://www.goodreads.com/review/show/1241094426"&gt;review&lt;/a&gt;]&lt;/li&gt;
  &lt;li&gt;The Goblin Emperor [&lt;a href="https://www.goodreads.com/review/show/1400549503"&gt;review&lt;/a&gt;]&lt;/li&gt;
  &lt;li&gt;The Martian [&lt;a href="https://www.goodreads.com/review/show/1148506677"&gt;review&lt;/a&gt;]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A complete list is on &lt;a href="https://www.goodreads.com/user/year_in_books/2015/6170741"&gt;Goodreads&lt;/a&gt;&lt;/p&gt;

&lt;h2 id="tech"&gt;Tech&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Launched &lt;a href="https://hackercouch.com"&gt;hackercouch&lt;/a&gt; as a personal project.&lt;/li&gt;
  &lt;li&gt;Shifted to Arch Linux + i3wm setup for my laptop. See &lt;a href="/setup/"&gt;Setup&lt;/a&gt; page for more details.&lt;/li&gt;
  &lt;li&gt;Left facebook, mostly because of their stance on Net Neutrality and the FreeBasics debacle in India.&lt;/li&gt;
&lt;/ul&gt;</description><author>Nemo's Home</author><pubDate>Mon, 15 Feb 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://captnemo.in/blog/2016/02/15/2015-in-review/</guid></item><item><title>Heisengames and the importance of patience in business</title><link>https://bytepawn.com/heisengames-business.html</link><description>&lt;p&gt;Most bets businesses take, be it hiring, features, products or strategy don't  work out. Still, many businesses are successful despite setbacks. A negative attitude---even when the analysis of the situation is in fact correct---may be missing the bigger picture.&lt;/p&gt;</description><author>Bytepawn - Marton Trencseni</author><pubDate>Mon, 08 Feb 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://bytepawn.com/heisengames-business.html</guid></item><item><title>Modified Flapjacks</title><link>https://rjp.is/blogging/posts/modified-flapjacks-2/</link><description>In which we experiment with flapjacks.</description><author>infrequent oscillations</author><pubDate>Mon, 08 Feb 2016 00:04:09 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/modified-flapjacks-2/</guid></item><item><title>Cloud9: Cloud coding that actually works</title><link>https://bytepawn.com/cloud9.html</link><description>&lt;p&gt;For the past 2 months I've been using Cloud9 for writing code in the cloud, and I can wholeheartedly recommend it: it just works for me. It's basically Docker plus an IDE: you get a Docker container running Ubuntu that you can access over a web IDE.&lt;/p&gt;</description><author>Bytepawn - Marton Trencseni</author><pubDate>Sun, 07 Feb 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://bytepawn.com/cloud9.html</guid></item><item><title>Luigi vs Airflow vs Pinball</title><link>https://bytepawn.com/luigi-airflow-pinball.html</link><description>&lt;p&gt;A spreadsheet comparing the three opensource workflow tools for ETL.&lt;br /&gt;&lt;br /&gt;&lt;img alt="Comparison" src="/images/airflow-luigi-pinball.png" style="width: 400px;" /&gt;&lt;/p&gt;</description><author>Bytepawn - Marton Trencseni</author><pubDate>Sat, 06 Feb 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://bytepawn.com/luigi-airflow-pinball.html</guid></item><item><title>Pinball review</title><link>https://bytepawn.com/pinball.html</link><description>&lt;p&gt;Pinball is an ETL tool written by Pinterest. Like Airflow, it supports defining tasks and dependencies as Python code, executing and scheduling them, and distributing tasks across worker nodes. It supports calendar scheduling (hourly/daily jobs, also visualized on the web dashboard). Unfortunately, I found Pinball has very little documentation, very few recent commits in the Github repo and few meaningful answers to Github issues by maintainers, while it's architecture is complicated and undocumented.&lt;/p&gt;</description><author>Bytepawn - Marton Trencseni</author><pubDate>Sat, 06 Feb 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://bytepawn.com/pinball.html</guid></item><item><title>Mirroring a Gitlab project to Github</title><link>https://smcleod.net/2016/02/mirroring-a-gitlab-project-to-github/</link><description>&lt;p&gt;Let&amp;rsquo;s pretend you have a project on Gitlab called &lt;code&gt;ask-izzy&lt;/code&gt; and you want to mirror it up to Gitlab which is located at &lt;a href="https://github.com/ask-izzy/ask-izzy"&gt;https://github.com/ask-izzy/ask-izzy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Assuming you&amp;rsquo;re running Gitlab as the default user of &lt;code&gt;git&lt;/code&gt; and that your repositories are stored in &lt;code&gt;/mnt/repositories&lt;/code&gt; you can following something similar to the following instructions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Grant write access to Github&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Get your Gitlab install&amp;rsquo;s pubkey from the git user&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="chroma" tabindex="0"&gt;&lt;code class="language-shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat /home/git/.ssh/id_rsa.pub
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On Github add this pubkey as deploy key on the repo, make sure you tick the option to allow write access.&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Thu, 04 Feb 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2016/02/mirroring-a-gitlab-project-to-github/</guid></item><item><title>How to parse this?</title><link>https://rjp.is/blogging/posts/how-to-parse-this-2/</link><description>In which we wonder about Jim Henson.</description><author>infrequent oscillations</author><pubDate>Tue, 02 Feb 2016 12:23:57 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/how-to-parse-this-2/</guid></item><item><title>Jamathon 2016 #summary</title><link>https://rjp.is/blogging/posts/jamathon-2016-summary-2/</link><description>Almost a success - 27 tracks uploaded for 31 days.
All of them are in my Jamathon playlist.
One (#17) was a cheat because it didn&amp;rsquo;t involve any apps but was a recording using binaural microphones.
Favourites are marked thusly: ★
Jamathon #1: Created from a one minute recording of my bathroom fan Jamathon #2: Made with some previously recorded-with-Fieldscaper samples Jamathon #3: Samplr with various samples Jamathon #4: ★ Created from three iPhone Fieldscaper recordings of the DLR this morning Jamathon #5: I think this was mucking around with Dedalus.</description><author>infrequent oscillations</author><pubDate>Mon, 01 Feb 2016 17:02:31 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/jamathon-2016-summary-2/</guid></item><item><title>Janathon 2016 #summary</title><link>https://rjp.is/blogging/posts/janathon-2016-summary-2/</link><description>(All numbers from VeloViewer - a couple of days are missing from here because I only recorded them on the Fitbit, not the Garmin, which means they don&amp;rsquo;t end up in Strava.)
37 activities, 251.97km, 40:20:14 elapsed, 36:52:10 moving, 2215m elevation (421m max) 3 rides, 29.38km, 2:15:23 elapsed, 1:57:43 moving, 108m elevation (54m max) 10 runs, 103.5km, 12:21:18 elapsed, 11:46:35 moving, 1077m elevation (421m max) 24 walks, 119.08km, 25:43:32 elapsed, 23:07:36 moving, 1030m elevation (201m max)</description><author>infrequent oscillations</author><pubDate>Sun, 31 Jan 2016 23:38:58 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-summary-2/</guid></item><item><title>Janathon 2016 #31</title><link>https://rjp.is/blogging/posts/janathon-2016-31-2/</link><description>Yes! Survived! Finished! 31/31!
Today was recovery from Cakeathon by way of cycling from St. Pancras to Peckham Rye (I got lost again) and then walking home from there.
[Cycling] [Walking]
(Janathon summary in the next post)</description><author>infrequent oscillations</author><pubDate>Sun, 31 Jan 2016 22:58:45 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-31-2/</guid></item><item><title>Janathon 2016 #30</title><link>https://rjp.is/blogging/posts/janathon-2016-30-2/</link><description>A (hard) small (tiring) jaunt (hilly) around a country park.
With an excellent goody bag&amp;hellip;
[Winter Cakeathon 2016]</description><author>infrequent oscillations</author><pubDate>Sat, 30 Jan 2016 23:04:32 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-30-2/</guid></item><item><title>Janathon 2016 #29</title><link>https://rjp.is/blogging/posts/janathon-2016-29-2/</link><description>First bike ride of 2016.
Obviously I got lost even though it was almost a straight line between Peckham and St. Pancras.
But at least now I have some cycle miles for the year.
[A jaunt on a Brompy]</description><author>infrequent oscillations</author><pubDate>Fri, 29 Jan 2016 21:21:08 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-29-2/</guid></item><item><title>AskIzzy</title><link>https://smcleod.net/2016/01/askizzy/</link><description>&lt;h2 id="today-we-launched-a-mobile-website-for-homeless-people"&gt;Today we launched a mobile website for homeless people&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://askizzy.org.au"&gt;&lt;img src="askizzy.png" style="width: 600px;" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;hellip; and it was launched by &lt;a href="http://www.heraldsun.com.au/news/victoria/askizzy-app-connects-the-homeless-to-food-shelter-and-health-services/news-story/bfae67275552be421af4dd54bfd575a6?nk=ebd042d1d2789514c4e8553cb5633711-1454053888"&gt;one of Australia&amp;rsquo;s many recent Prime Ministers&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="today-alone-we-served-up-over-87000-requests"&gt;Today alone we served up over 87,000 requests&lt;/h3&gt;
&lt;p&gt;As many of you know, I work with &lt;a href="https://infoxchange.org"&gt;Infoxchange&lt;/a&gt; as the operations lead.&lt;/p&gt;
&lt;p&gt;When I first heard the idea of a website or app for people that have found or are worried about finding themselves homeless in Australia I really didn&amp;rsquo;t think it made sense - until I saw the stats showing how many homeless people in Australia have regular access to a smart phone and data either via a cellular provider or free WiFi.&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Fri, 29 Jan 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2016/01/askizzy/</guid></item><item><title>Janathon 2016 #28</title><link>https://rjp.is/blogging/posts/janathon-2016-2/</link><description>Three walks. Because I&amp;rsquo;m worth it. And also I didn&amp;rsquo;t plan my day off very well.
[Picking up new art] [Thames wander] [Picking up new shoes]</description><author>infrequent oscillations</author><pubDate>Thu, 28 Jan 2016 23:49:24 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-2/</guid></item><item><title>What being a PM is really like - Software is easy, People are hard</title><link>/2016/01/28/What-being-a-PM-is-really-like-Software-is-easy-People-are-hard/</link><description>&lt;p&gt;In recent months I&amp;rsquo;ve had the question nearly once a week about advice/tips for becoming a Product Manager or more commonly referred to as PM. These are generally coming from people that are either currently engineers, or previously were and are in some engineer/customer role such as a sales engineer or solution architect. There&amp;rsquo;s a number of &lt;a href="http://www.amazon.com/Inspired-Create-Products-Customers-Love/dp/0981690408?tag=mypred-20"&gt;high level&lt;/a&gt; pieces talking about PM and it often feels glorious, I mean you get to make product decisions right? You get to call some shots. Well that sometimes may be true, but don&amp;rsquo;t assume it&amp;rsquo;s all rainbows and sparkles.&lt;/p&gt;
&lt;p&gt;Especially as a first time PM what your day to day will look like won&amp;rsquo;t be debating strategy all day long. Here&amp;rsquo;s a few of the good and the bad sides of being a PM.&lt;/p&gt;
&lt;h3 id="plenty-of-grunt-work"&gt;
&lt;div&gt;
Plenty of grunt work
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;While you may get to make a decision or two, the bulk of your time will not be thinking about grandiose visions, instead you&amp;rsquo;ll be doing a lot to gather data. There&amp;rsquo;s a lot of means for gathering data across lots of sources, the more you use the better you&amp;rsquo;ll be. Knowing the ones you steer towards, as well as ones you steer away from is useful so you can balance a bias more fairly. For myself SQL is a go-to, then customer interactions both qualitative and quantitative such as surveys, following what media is saying about your space is important as well. And while user studies are often relegated to design and UX, as a PM you need to make sure it at least happens (&lt;a href="http://www.invisionapp.com/"&gt;Invision App&lt;/a&gt; is a favorite for lightweight tests).&lt;/p&gt;
&lt;p&gt;In a given week I probably spend 10 hrs interacting with customers, looking at data, and sadly that&amp;rsquo;s probably not enough.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;A few practical examples of this&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Each morning I send emails to 10-20 users who used the product for the first time, yes this is automated but carving out 30 minutes of my day to actually follow-up with each of them is less automated.&lt;/p&gt;
&lt;p&gt;Another example is keeping a health of business dashboard up to date. Personally I use google sheets for this. Within one spreadsheet I have monthly and weekly targets as well as how we’re tracking against them. These are all updated on actual real time data, powered by Heroku’s dataclips with a simple &lt;code&gt;=importCSV(‘http://dataclips.heroku.com/abcdefghij….csv’)&lt;/code&gt;. In total my google spreadsheets has 1 high level overview, with about 20 underlying sheets that do all of the computations. In any given month 1 of my key 4-5 goals may be missed, which then spawns digging in deeper to figure out why and what we can do about it.&lt;/p&gt;
&lt;h3 id="dictating-vs-consensus"&gt;
&lt;div&gt;
Dictating vs. consensus
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;From a product decision making perspective you can force alignment by explicitly making every decision, or you can allow decisions to be made as a group voting if needed. Expect to use some balance of both of these among the team, and neither is never perfect. When it comes to outside the team you may still use both, but steer more strongly one way or the other. For example with the executive team it may be more consensus, with marketing it may be dictating your product roadmap which they can help support.&lt;/p&gt;
&lt;p&gt;Even within the team there will be times a decision must be made and there will be some people that don&amp;rsquo;t align. It&amp;rsquo;s key that you make the decision clearly and explicitly. Even though some individuals don&amp;rsquo;t like it, they won&amp;rsquo;t fight against it&amp;hellip; unless you make a habit of taking the input, then discarding it and going along your &amp;lsquo;intuition&amp;rsquo;. Even when there&amp;rsquo;s a strong case based on the data it may not be as clear as you think.&lt;/p&gt;
&lt;p&gt;In contrast, decision making by consensus most people will feel happier that they provided input into the product. If you take everyone&amp;rsquo;s input expect to end up with a product that feels like 10 people designed it, needless to say incoherent.&lt;/p&gt;
&lt;p&gt;As a PM expect to do a lot of listening, a good bit of convincing, and some occasional big decision making.&lt;/p&gt;
&lt;h3 id="the-pain-you-feel-inside-the-building-doesnt-matter"&gt;
&lt;div&gt;
The pain you feel inside the building doesn&amp;rsquo;t matter
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;You may think you&amp;rsquo;re solving a problem that exists for users, when in reality there was no problem at all. This is just a reminder that you need to keep empathy in mind above so much else.&lt;/p&gt;
&lt;p&gt;As an example, once a data team put in place a tool, supposedly for me. I looked at the tool and more or less didn&amp;rsquo;t understand why it was in place. They proceeded to explain that my problem was it took me too long to write SQL, so this tool will help me get the reports I need without SQL. At that point I proceeded to actually list off all the issues I did have, none of which &lt;a href="http://www.craigkerstiens.com/categories/postgres/"&gt;were SQL&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Prescribing a solution without knowing clearly &lt;strong&gt;from customers&lt;/strong&gt; what the problem is will leave you in a bad spot. All this means you have to set aside building the tool you want to use, and make sure you know what the &lt;a href="http://headrush.typepad.com/creating_passionate_users/2005/01/keeping_users_e.html"&gt;customer wants&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="marketing-is-your-job"&gt;
&lt;div&gt;
Marketing is your job
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Not external marketing, though often that work may still fall to you, but rather internal marketing.&lt;/p&gt;
&lt;p&gt;It’s important that you internally market the wins for your &lt;em&gt;team&lt;/em&gt;. These wins should very much be for the team, and not for your own benefit. The best PMs seem to disappear into the background, this is because you’re more surfacing all the work your team is doing than any of the details you helped coordinate. This is often counter to our natural instinct to tout our own accomplishments. This is only exaggerated in PM role, one where things can still ship if you’re not there, so there can often be a tendency to try to highlight the roles value. Fight that urge to self market.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;Rest assured though–getting the team focused on solving the right problems, and then surfacing their wins will only help you go faster.&lt;/p&gt;
&lt;h3 id="on-leading"&gt;
&lt;div&gt;
On leading
&lt;/div&gt;
&lt;/h3&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;At the end of the day ensuring the product is advancing is your job, so be prepared to do what you need to whether it’s leading or not to accomplish that.&lt;/p&gt;
&lt;h3 id="its-not-all-rainbows-but-it-is-fun"&gt;
&lt;div&gt;
It’s not all rainbows, but it is fun
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;The range of things you’ll have to focus on can be diverse and complex. In the end if you get a rush out of shipping and launching products, then all the work that goes into it can make it all worthwhile. It’s as much about figuring out what customers want and then getting your team building the right thing. For a first time PM it can be summed up by the notion that software is easy, people are hard.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Special thanks to &lt;a href="http://www.twitter.com/lukasfittl"&gt;Lukas Fittl&lt;/a&gt; and &lt;a href="http://www.twitter.com/iamclovin"&gt;Arun Thampi&lt;/a&gt; for reviews and feedback on this post.&lt;/em&gt;&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Thu, 28 Jan 2016 22:55:56 GMT</pubDate><guid isPermaLink="true">/2016/01/28/What-being-a-PM-is-really-like-Software-is-easy-People-are-hard/</guid></item><item><title>Janathon 2016 #27</title><link>https://rjp.is/blogging/posts/janathon-2016-27-2/</link><description>Not quite as restful but the Jubilee Line was buggered which meant walking to Stratford instead made sense.
Yes.
[Just about 7.5km to Stratford]</description><author>infrequent oscillations</author><pubDate>Thu, 28 Jan 2016 01:32:19 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-27-2/</guid></item><item><title>Janathon 2016 #26</title><link>https://rjp.is/blogging/posts/janathon-2016-26-2/</link><description>Everything from now until Saturday is basically rest.
Because Saturday is a biggie - Winter Cakeathon.
[Short walk commute]</description><author>infrequent oscillations</author><pubDate>Tue, 26 Jan 2016 12:58:47 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-26-2/</guid></item><item><title>Janathon 2016 #25</title><link>https://rjp.is/blogging/posts/janathon-2016-25-2/</link><description>A heavy-legged recovery run to the local garage for some Red Bull and a KitKat Chunky. Bleugh.
[Heavy Legs Make Slow Running]</description><author>infrequent oscillations</author><pubDate>Mon, 25 Jan 2016 23:11:29 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-25-2/</guid></item><item><title>Garmin vs Fitbit</title><link>https://rjp.is/blogging/posts/garmin-vs-fitbit-2/</link><description>Preamble Garmin data from my TCX files via tapiriik sync Fitbit data downloaded using API with &amp;ldquo;1sec&amp;rdquo; resolution Only data points coincident on seconds are used Tools used Modified version of my TCX dumper FitBit.py Ploticus Various shell commands (awk, sort, etc.) Results 48 minutes of hill repeats; Garmin using smart recording; Fitbit in exercise mode. 39 minutes of walking; Garmin using 1sec recording; Fitbit in passive mode. 39 minutes of walking; Garmin using 1sec recording; Fitbit in passive mode.</description><author>infrequent oscillations</author><pubDate>Mon, 25 Jan 2016 08:33:09 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/garmin-vs-fitbit-2/</guid></item><item><title>Janathon 2016 #24</title><link>https://rjp.is/blogging/posts/janathon-2016-24-2/</link><description>A year ago, I did a short session of hill repeats (3 down, 4 up) on Greenwich Park hill and it was hard work.
By coincidence I ended up doing the same today and, oddly, almost exactly the same duration but this year I managed 6 down, 5 up on an empty stomach.
(If I can train my body to burn fat efficiently, I should be able to run non-stop for, oh, about 8000 miles.</description><author>infrequent oscillations</author><pubDate>Mon, 25 Jan 2016 01:25:40 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-24-2/</guid></item><item><title>Moving Apps to the External SD Card on Android</title><link>https://blog.nawaz.org/posts/2016/Jan/moving-apps-to-the-external-sd-card-on-android/</link><description>&lt;p&gt;Some months ago I bought a new Android phone. The internal storage was
only 16 &lt;span class="caps"&gt;GB&lt;/span&gt;, so I put in an external &lt;span class="caps"&gt;SD&lt;/span&gt; card of 32 &lt;span class="caps"&gt;GB&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;As I started installing apps, I began to move the larger ones to the &lt;span class="caps"&gt;SD&lt;/span&gt;
card using the Android Apps&amp;nbsp;menu.&lt;/p&gt;
&lt;p&gt;And I …&lt;/p&gt;</description><author>Beetle Space</author><pubDate>Sun, 24 Jan 2016 10:00:00 GMT</pubDate><guid isPermaLink="true">https://blog.nawaz.org/posts/2016/Jan/moving-apps-to-the-external-sd-card-on-android/</guid></item><item><title>Janathon 2016 #23</title><link>https://rjp.is/blogging/posts/janathon-2016-23-2/</link><description>Another rest-ish day with a small jaunt down the road in the Feelmax Kuuva 3 before picking up coffee and salad for tea.
THE EXCITEMENT IS NON-STOP. NON. STOP.
[5km to coffee]</description><author>infrequent oscillations</author><pubDate>Sat, 23 Jan 2016 21:33:28 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-23-2/</guid></item><item><title>Janathon 2016 #22</title><link>https://rjp.is/blogging/posts/janathon-2016-22-2/</link><description>Another brisk 10km but with a twist - this time I recorded the entire binaural soundscape using the PCM-M10 and the CS-10EM.
Here&amp;rsquo;s a snippet from Narrow Street - obviously you need stereo headphones to get the full effect.
Managed the 10km marker in 1:50:45 which isn&amp;rsquo;t bad but then forgot to stop the watch when I got to Charing Cross (because I&amp;rsquo;d lost one of the windshields for the CS-10EMs and was flustered - turned out to be attached to one of my gloves somehow!</description><author>infrequent oscillations</author><pubDate>Sat, 23 Jan 2016 00:54:46 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-22-2/</guid></item><item><title>Janathon 2016 #21</title><link>https://rjp.is/blogging/posts/janathon-2016-21-2/</link><description>A rest day which involved going to the Co-op to pick up a windshield (very effective but doesn&amp;rsquo;t really fit the PCM-M10 if you have headphones plugged in) and then home via Point Hill. Which is Quite Steep in places.
Windshield vs Muji fan Muji fan, full speed, pointed at the PCM-M10 mics from 4&amp;quot;.
10s with windshield; 10s without; 10s without on low sensitivity.</description><author>infrequent oscillations</author><pubDate>Fri, 22 Jan 2016 00:22:33 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-21-2/</guid></item><item><title>Janathon 2016 #20</title><link>https://rjp.is/blogging/posts/janathon-2016-20-2/</link><description>Into the last stretch! Just as the weather seems to pivoting out of &amp;ldquo;COR BLIMEY MY KNACKERS HAVE VANISHED&amp;rdquo; cold into &amp;ldquo;DON&amp;rsquo;T NEED A COAT MUM&amp;rdquo; mild as well.
Today was a rest day and if it hadn&amp;rsquo;t have been for those surprise Creme Eggs, it would have been a successful one.
Still, a walk up a hill in &amp;ldquo;brisk&amp;rdquo; conditions can&amp;rsquo;t hurt.</description><author>infrequent oscillations</author><pubDate>Thu, 21 Jan 2016 01:55:42 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-20-2/</guid></item><item><title>Janathon 2016 #19</title><link>https://rjp.is/blogging/posts/janathon-2016-19-2/</link><description>First run for 8 days and it was hard. Not because of the running but because Muji base layer + dare2b shell was FAR TOO HEAT EFFICIENT. I was burning up after half an hour.
Then got some twangy calf pre-cramps at 8km and it was an easy decision to abort at just over 10km by Deptford ASDA for some recovery food.
That included a banana - the eating of which made me feel proper ill.</description><author>infrequent oscillations</author><pubDate>Wed, 20 Jan 2016 01:07:34 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-19-2/</guid></item><item><title>Code Monkey or CAD Monkey?</title><link>https://blog.nawaz.org/posts/2016/Jan/code-monkey-or-cad-monkey/</link><description>&lt;a class="reference external image-reference" href="https://blog.nawaz.org/images/cadmonkey/codemonkey.jpg"&gt;
&lt;img alt="Monkey typing on a computer" src="https://blog.nawaz.org/images/cadmonkey/codemonkey.jpg" /&gt;
&lt;/a&gt;
&lt;p&gt;I recently came across this &lt;a class="reference external" href="https://www.reddit.com/r/financialindependence/comments/3y8x92/what_industries_do_people_get_into_for_the_money/cybmzcz"&gt;comment&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I can&amp;#8217;t tell you how many times I&amp;#8217;ve heard &amp;#8220;oh, I just &lt;span class="caps"&gt;COULDN&lt;/span&gt;&amp;#8217;T
stare at a computer all day&amp;nbsp;lol&amp;#8221;.&lt;/p&gt;
&lt;p&gt;If you want a decent job, it&amp;#8217;s probably going to be an office job
staring at a computer all&amp;nbsp;day …&lt;/p&gt;&lt;/blockquote&gt;</description><author>Beetle Space</author><pubDate>Tue, 19 Jan 2016 10:00:00 GMT</pubDate><guid isPermaLink="true">https://blog.nawaz.org/posts/2016/Jan/code-monkey-or-cad-monkey/</guid></item><item><title>Internships 2016</title><link>https://spindas.dreamwidth.org/1988.html</link><description>&lt;p&gt;After doing Google Summer of Code last year, this is my first year of applying for internships. So I&amp;rsquo;m nervous-yet-excited, and am really hoping that resumes actually get looked at as I don&amp;rsquo;t have any &amp;ldquo;employers&amp;rdquo; to put down so far.&lt;/p&gt; &lt;p&gt;Places I&amp;rsquo;ve applied to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="https://careers.mozilla.org/en-US/university/"&gt;&lt;strong&gt;Mozilla&lt;/strong&gt;&lt;/a&gt; in Mountain View &amp;ndash; open source, makers of Firefox and Rust!&amp;nbsp;This is kind of my dream job.&lt;/li&gt; &lt;li&gt;&lt;a href="https://www.adobe.com/careers/university/internships.html"&gt;&lt;strong&gt;Adobe&lt;/strong&gt;&lt;/a&gt; in San Jose &amp;ndash; they&amp;rsquo;re really easy to get to from home, which is great since I don&amp;rsquo;t have my driver&amp;rsquo;s license yet.&lt;/li&gt; &lt;li&gt;&lt;a href="https://careers.yahoo.com/us/students"&gt;&lt;strong&gt;Yahoo&lt;/strong&gt;&lt;/a&gt; in Sunnyvale &amp;ndash; also very reachable.&lt;/li&gt; &lt;li&gt;&lt;a href="https://www.facebook.com/careers/university/internships/engineering"&gt;&lt;strong&gt;Facebook&lt;/strong&gt;&lt;/a&gt; in Mountain View &amp;ndash; one at WhatsApp, where they use Erlang! And two elsewhere in the company.&lt;br /&gt;Lesson learned: if you have a Facebook account, make sure you log in before applying, &lt;s&gt;and use Chrome &amp;ndash; the &amp;ldquo;Skills&amp;rdquo; field is currently broken on Firefox&lt;/s&gt; &lt;em&gt;(this seems to be fixed now)&lt;/em&gt;. Also, some fields have character caps that aren't apparent unless you proceed to the next page and then go back.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Places I&amp;rsquo;ve looked at:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="https://www.janestreet.com/join-jane-street/internships/"&gt;&lt;strong&gt;Jane Street&lt;/strong&gt;&lt;/a&gt; &amp;ndash; it&amp;rsquo;d be fun to work in a functional language like OCaml, but they only have positions in NYC, London, and Hong Kong.&lt;/li&gt; &lt;li&gt;&lt;a href="https://galois.com/careers/software-engineer-intern/"&gt;&lt;strong&gt;Galois&lt;/strong&gt;&lt;/a&gt; &amp;ndash; another FP&amp;nbsp;(Haskell) shop that&amp;rsquo;s too far away (Portland).&lt;/li&gt; &lt;li&gt;&lt;a href="https://www.google.com/about/careers/students/"&gt;&lt;strong&gt;Google&lt;/strong&gt;&lt;/a&gt; &amp;ndash; they&amp;rsquo;re all closed up for the summer internships. I&amp;rsquo;ll have to apply earlier next year.&lt;/li&gt; &lt;li&gt;&lt;a href="https://nest.com/careers/"&gt;&lt;strong&gt;Nest&lt;/strong&gt;&lt;/a&gt; &amp;ndash; lots of positions open, but the closest office is in Palo Alto, which lacks good public transportation to and from San Jose.&lt;/li&gt; &lt;li&gt;&lt;a href="https://about.twitter.com/careers/teams/university"&gt;&lt;strong&gt;Twitter&lt;/strong&gt;&lt;/a&gt; &amp;ndash; again, the nearest office is in-state but not close enough (San Francisco).&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;As it turns out, location is a major limiting factor for me. I definitely need to start driving soon.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img alt="comment count unavailable" height="12" src="https://www.dreamwidth.org/tools/commentcount?user=spindas&amp;amp;ditemid=1988" style="vertical-align: middle;" width="30" /&gt; comments</description><author>spinda's dreamwidth</author><pubDate>Tue, 19 Jan 2016 08:29:51 GMT</pubDate><guid isPermaLink="true">https://spindas.dreamwidth.org/1988.html</guid></item><item><title>Janathon 2016 #18</title><link>https://rjp.is/blogging/posts/janathon-2016-18-2/</link><description>Recovery seems to be progressing - knocked out a brisk walk in decent cold without dying (average of 10:03 min/km is good going for me, even when fully fit.)
[Brisk as a monkey up a vicar&amp;rsquo;s noodle]</description><author>infrequent oscillations</author><pubDate>Tue, 19 Jan 2016 00:51:08 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-18-2/</guid></item><item><title>Midpoint Football</title><link>https://rjp.is/blogging/posts/midpoint-football-2/</link><description>In which we try to predict football results.</description><author>infrequent oscillations</author><pubDate>Mon, 18 Jan 2016 19:04:47 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/midpoint-football-2/</guid></item><item><title>Fix XenServer SR with corrupt or invalid metadata</title><link>https://smcleod.net/2016/01/fix-xenserver-sr-with-corrupt-or-invalid-metadata/</link><description>&lt;p&gt;If a disk / VDI is orphaned or only partially deleted you&amp;rsquo;ll notice that under the SR it&amp;rsquo;s not assigned to any VM.&lt;/p&gt;
&lt;p&gt;This can cause issues that look like metadata corruption resulting in the inability to migrate VMs or edit storage.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="chroma" tabindex="0"&gt;&lt;code class="language-shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@xenserver-host ~&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="c1"&gt;# xe vdi-destroy uuid=6c2cd848-ac0e-441c-9cd6-9865fca7fe8b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Error code: SR_BACKEND_FAILURE_181
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Error parameters: , Error in Metadata volume operation &lt;span class="k"&gt;for&lt;/span&gt; SR. &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opterr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;VDI delete operation failed &lt;span class="k"&gt;for&lt;/span&gt; parameters:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;  /dev/VG_XenStorage-3ae1df17-06ee-7202-eb92-72c266134e16/MGT, 6c2cd848-ac0e-441c-9cd6-9865fca7fe8b.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;  Error: Failed to write file with params &lt;span class="o"&gt;[&lt;/span&gt;3, 0, 512, 512&lt;span class="o"&gt;]&lt;/span&gt;. Error: 5&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="removing-stale-vdis"&gt;Removing stale VDIs&lt;/h2&gt;
&lt;p&gt;To fix this, you need to remove those VDIs from the SR after first deleting the logical volume:&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Mon, 18 Jan 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2016/01/fix-xenserver-sr-with-corrupt-or-invalid-metadata/</guid></item><item><title>Marketing definitions for developers</title><link>/2016/01/17/Marketing-definitions-for-developers/</link><description>&lt;p&gt;Marketing often feels like a dirty-icky thing to many developers. Well until you feel like you have a great product, but no one using it then you have to get a crash course in all of that. And while I might cover some of the actual basics in the future, just knowing what marketing people actually mean when they’re talking can be a huge jump start. Here&amp;rsquo;s a guide that distills many of the acronyms and terms down to what they actually mean in reality.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SEO - Search engine optimization.&lt;/strong&gt; There&amp;rsquo;s two sides to this, one where you&amp;rsquo;re attempting to game the system known known as black hat. The other is simply creating good content.&lt;/p&gt;
&lt;p&gt;Tip: Now, unlike several years ago social sharing helps impact this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SEM - Search engine marketing.&lt;/strong&gt; The short of this is adwords, but broadly it&amp;rsquo;s any search engine.&lt;/p&gt;
&lt;p&gt;Tip: Be wary here, you can spend a lot of money quickly. Properly managing it takes time and effort otherwise you&amp;rsquo;re wasting money.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Display ads&lt;/strong&gt; - Banner ads on websites. There&amp;rsquo;s a few common form factors in this world, so you&amp;rsquo;ll create a few then reuse them across lots of properties.&lt;/p&gt;
&lt;p&gt;Tip: Results may vary here, there are some hidden gems when advertising on various long tail sites.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Retargeting&lt;/strong&gt; - This is where you&amp;rsquo;re serving an ad (most commonly display) to someone that&amp;rsquo;s previously visited your site. The process happens due to you &amp;lsquo;pixeling&amp;rsquo; them, and a cookie being set so the ad server knows they&amp;rsquo;ve seen you.&lt;/p&gt;
&lt;p&gt;Tip: Generally good bang for the buck here, but you still need initial visitors to even retarget to.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Funnel&lt;/strong&gt; - The process of someone going from finding you to paying to paying more. Generally a process will look something like: Anonymous visitor by referral, sign ups, low money bucket, big money bucket.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Top of the funnel&lt;/strong&gt; - Hopefully clear from the previous one, top of the funnel would be the max of users you reach out to or get to your site, usually down to getting them to sign up.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bottom of the funnel&lt;/strong&gt; - This is usually going from time you have a user to customer and then growing that customer via cross-selling and upselling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Drip marketing&lt;/strong&gt; - This is the process of gradually sending emails/notifications to your customers to get them to engage and learn about the product. Think of it as a welcome email on day 1, an intro on day 3, and on day 5 a different email based on what they&amp;rsquo;ve done so far. Really good drip marketing will create a different email for the user based on what they have or haven&amp;rsquo;t done.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attribution (last/first/multi)&lt;/strong&gt; - Attribution relates to how you got the user or customer (via web referral). There&amp;rsquo;s a few different ways of looking at this, last touch is the last website they visited before signing up, first touch is the first referral they were sent from, and multi touch (often more complicated to put in place) attributes something to all referrals they&amp;rsquo;ve come from.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AR - Analyst relations&lt;/strong&gt;. Analysts cover particular products or areas in an industry, write reports, and often consult with large enterprises when making buying decisions. Analyst relations or AR is the common term for interacting with them, you can &lt;a href="/2015/07/25/A-guide-to-analyst-relations-for-startups/"&gt;learn more here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PR - Public relations&lt;/strong&gt;. This is generally the press/media side. It often involves launches, press releases, pitching media etc. You can read more of a &lt;a href="/2015/07/21/An-intro-PR-guide-for-startups/"&gt;guide on it here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Briefing&lt;/strong&gt; - This is normally with an analyst or press, and is typically a quick 30 minute call occasionally a demo of an upcoming launch.Usually&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inquiry&lt;/strong&gt; - This refers more to the analyst side. Where a briefing is often more one sided for you to pitch/update them on what you’ve been doing, an inquiry is more a back and forth where you can ask what they’re seeing in the market and for input on direction.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Campaign&lt;/strong&gt; - A collection of activities that go on around a certain thing focused on specific keywords or theme. This can be as little as a search engine marketing campaign which is the most common, or much larger and coordinated with billboards, webinars, etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lead Gen&lt;/strong&gt; - The sales funnel usually goes from just getting an email, to talking to them, to getting them to try a demo or run a POC, to eventually buying. Lead gen is the activity of just getting that initial contact so you can then further engage with them. In practice this can often involve giving something away, like a t-shirt in exchange for an email.&lt;/p&gt;
&lt;h3 id="conclusion"&gt;
&lt;div&gt;
Conclusion
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;While this doesn&amp;rsquo;t cover every marketing activity under the sun, hopefully it&amp;rsquo;s a good primer on things you may have heard but been confused by. If there&amp;rsquo;s important ones I&amp;rsquo;ve missed please feel free to let me know &lt;a href="http://www.twitter.com/craigkerstiens"&gt;@craigkerstiens&lt;/a&gt;&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Sun, 17 Jan 2016 22:55:56 GMT</pubDate><guid isPermaLink="true">/2016/01/17/Marketing-definitions-for-developers/</guid></item><item><title>Janathon Halfway Update</title><link>https://rjp.is/blogging/posts/janathon-halfway-update-2/</link><description>19 activities: 6 runs; 13 walks All Time: 21:04:44 elapsed; 18:56:31 moving Speed: 6.4km/h avg. Distance: 118.88km total; 6.26km avg. Mile: 16:41 avg. Running Time: 6:39:47 elapsed; 6:12:02 moving Speed: 9.4km/h avg. Distance: 55.04km total; 9.17km avg. Mile: 9:37 avg. Walking Time: 14:24:57 elapsed; 12:44:29 moving Speed: 5.0km/h avg. Distance: 63.85km total; 4.96km avg. Mile: 19:57 avg.</description><author>infrequent oscillations</author><pubDate>Sun, 17 Jan 2016 19:01:12 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-halfway-update-2/</guid></item><item><title>Janathon 2016 #17</title><link>https://rjp.is/blogging/posts/janathon-2016-17-2/</link><description>Having to fetch a new sink waste trap from B&amp;amp;Q and a new gadget from the Co-op locker is a good way to force yourself out into the world. Knocked out 5 miles of mostly OK walking with the proper walking boots on (there was a mild threat of rain/sleet/snow necessitating waterproof footwear).
Hopefully another week of rest* should quell the back pain sufficiently that Cakeathon remains a sensible option.</description><author>infrequent oscillations</author><pubDate>Sun, 17 Jan 2016 18:39:48 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-17-2/</guid></item><item><title>Janathon 2016 #16</title><link>https://rjp.is/blogging/posts/janathon-2016-16-2/</link><description>Bleurgh.
[Just over 2 miles to the shops]</description><author>infrequent oscillations</author><pubDate>Sun, 17 Jan 2016 01:32:32 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-16-2/</guid></item><item><title>Janathon 2016 #15</title><link>https://rjp.is/blogging/posts/janathon-2016-15-2/</link><description>The triple sledgehammer of illness, tiredness, and misery arrived in a conjunction of blather to the ankle of 2016, hobbling it.
Which means the Janathon is reduced to a slow trundle from Greenwich to home via the Sainsbury&amp;rsquo;s to fetch some kitchen roll and cake.</description><author>infrequent oscillations</author><pubDate>Fri, 15 Jan 2016 23:31:00 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-15-2/</guid></item><item><title>Janathon 2016 #14</title><link>https://rjp.is/blogging/posts/janathon-2016-14-2/</link><description>Today was the day everything hit in spades and laid me up in bed.
Apart from two slow and mildly painful walks, I&amp;rsquo;ve accomplished little except learning that MovieBob loves Ghostbusters and that Dedalus is definitely more fun with a nanoKONTROL2.
Maybe tomorrow, I&amp;rsquo;ll want to settle &amp;hellip; no, wait, wrong hobo.
[Walk from hot chocolate] [Walk to home]</description><author>infrequent oscillations</author><pubDate>Fri, 15 Jan 2016 00:48:17 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-14-2/</guid></item><item><title>Janathon 2016 #13</title><link>https://rjp.is/blogging/posts/janathon-2016-13-2/</link><description>The excesses of Christmas, the indolent misery of a new year, the weekend&amp;rsquo;s over-exertions, consequent excesses caused by misery, and the abysmal weather have all started to take a grinding toll on my physical (back, stomach) and mental (it&amp;rsquo;s not pretty) states. My emotional state remains, as ever, deep in the toilet and has been unaffected by 2016 thus far. Yay?
A chilly 10km with 2008-vintage Rich Conaty for company did little to alleviate matters.</description><author>infrequent oscillations</author><pubDate>Thu, 14 Jan 2016 00:37:00 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-13-2/</guid></item><item><title>golang Learnings</title><link>https://rjp.is/blogging/posts/golang-learnings-2/</link><description>Things in golang this week (Mostly falling out of the diggymoo rewrite into godiggy.)
[How to include version information]
[Changing the usage text from flag]
[Twitter library - anaconda]
[Simple but useful ORM - crud]
[Calling a method by name and returning a string] - I&amp;rsquo;m experimenting with post-statement hooks for crud in order to enable ON CONFLICT REPLACE or INSERT OR REPLACE support for SQLite.</description><author>infrequent oscillations</author><pubDate>Wed, 13 Jan 2016 17:08:38 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/golang-learnings-2/</guid></item><item><title>Janathon 2016 #12</title><link>https://rjp.is/blogging/posts/janathon-2016-12-2/</link><description>Finally a post that&amp;rsquo;s not late.
Today was a &amp;ldquo;mildly twinging back really tired why did I sign up for this bleugh&amp;rdquo; kind of day.
Made the best of a bad situation and dug the weights out for 20kg of 2x(10x 10x 10x) arm exercises in about 9 minutes.
Obviously there&amp;rsquo;s no point putting that on Strava - you&amp;rsquo;ll have to make do with the heart rate graph from ConnectStats instead.</description><author>infrequent oscillations</author><pubDate>Wed, 13 Jan 2016 01:46:13 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-12-2/</guid></item><item><title>Janathon 2016 #11</title><link>https://rjp.is/blogging/posts/janathon-2016-11-2/</link><description>Another delayed update - sorry everyone.
Yesterday was very much recovery from the weekend and, consequently, was limited to two short walks.
[Walk to Starbucks] [Walk home]</description><author>infrequent oscillations</author><pubDate>Tue, 12 Jan 2016 16:19:07 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-11-2/</guid></item><item><title>Janathon 2016 #10</title><link>https://rjp.is/blogging/posts/janathon-2016-10-2/</link><description>(Slightly delayed because I&amp;rsquo;m only now just recovering from the weekend.)
After Saturday&amp;rsquo;s insane hills (660ft in a single climb!), a recovery run was in order (and also because I wasn&amp;rsquo;t going to be in any mood for exercise by the time I got back to London.)
Except I thought it would be a good idea to try Twentywell Lane.
Now I am sorry. For everything. And anything.
But at least it was only 80m of climbing this time instead of 200m.</description><author>infrequent oscillations</author><pubDate>Mon, 11 Jan 2016 19:41:20 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-10-2/</guid></item><item><title>Janathon 2016 #9</title><link>https://rjp.is/blogging/posts/janathon-2016-9-2/</link><description>Crikey. Was planned to be 20 miles but only managed just over 16 miles. BECAUSE OF THE HILLS.
LOOK AT THIS BUGGER.
That&amp;rsquo;s about 660ft of climbing in 2 miles. &amp;ldquo;It&amp;rsquo;s levelling off&amp;rdquo; said my LYING running LIAR companion LIAR every 200 LYING yards.
No wonder I&amp;rsquo;m ruined.
[26km up Sheffield]</description><author>infrequent oscillations</author><pubDate>Sat, 09 Jan 2016 23:52:41 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-9-2/</guid></item><item><title>Writing more legible SQL</title><link>/2016/01/08/Writing-more-legible-SQL/</link><description>&lt;p&gt;A number of times in a crowd I&amp;rsquo;ve asked how many people enjoy writing SQL, and often there&amp;rsquo;s a person or two. The follow up is how many people enjoy reading other people&amp;rsquo;s SQL and that&amp;rsquo;s unanimously 0. The reason for this is that so many people write bad SQL. It&amp;rsquo;s not that it doesn&amp;rsquo;t do the job, it&amp;rsquo;s just that people don&amp;rsquo;t tend to treat SQL the same as other languages and don&amp;rsquo;t follow strong code formatting guidelines. So, of course here&amp;rsquo;s some of my own recommendations on how to make SQL more readable.&lt;/p&gt;
&lt;h3 id="one-thing-per-line"&gt;
&lt;div&gt;
One thing per line
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Only put a single column/table/join per line. This is going to make for slightly more verbose SQL, but it will be easier to read and edit.. Here&amp;rsquo;s a basic example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT foo,
bar
FROM baz
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="align-your-projections-and-conditions"&gt;
&lt;div&gt;
Align your projections and conditions
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;You can somewhat see this in the above with &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; being on the same line. This is reasonably common for columns you&amp;rsquo;re selecting, but it&amp;rsquo;s not applied as often in &lt;code&gt;AND&lt;/code&gt; or &lt;code&gt;GROUP BY&lt;/code&gt; clauses. As you can see there is a difference though between:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT foo,
bar
FROM baz
WHERE foo &amp;gt; 3
AND bar = 'craig.kerstiens@gmail.com'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And a cleaner version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT foo,
bar
FROM baz
WHERE foo &amp;gt; 3
AND bar = 'craig.kerstiens@gmail.com'
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="use-column-names-when-groupingordering"&gt;
&lt;div&gt;
Use column names when grouping/ordering
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;This is personally an awful habit of mine, but it is extremely convenient to just order by the column number. In the above query we could just &lt;code&gt;ORDER BY 1&lt;/code&gt;. This is especially easy when column 1 may be something like SUM(foo). However, ensuring you explicitly &lt;code&gt;ORDER BY SUM(foo)&lt;/code&gt; will help limit any misunderstanding of the data.&lt;/p&gt;
&lt;h3 id="comments"&gt;
&lt;div&gt;
Comments
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;You comment your code all the time, yet so few seem to comment their queries. A simple &lt;code&gt;--&lt;/code&gt; allows you to inline a comment, perhaps where there&amp;rsquo;s some oddities to what you&amp;rsquo;re joining or just anywhere it may need clarification. You can of course &lt;a href="/2013/07/29/documenting-your-postgres-database/"&gt;go much further&lt;/a&gt;, but at least some basic level of commenting should be required.&lt;/p&gt;
&lt;h3 id="casing"&gt;
&lt;div&gt;
Casing
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;As highlighted in these examples, having a standard for how you case your queries is especially handy. Sticking with all SQL keywords in caps allows you to easily parse what is SQL and what are columns or literals that you&amp;rsquo;re using in queries.&lt;/p&gt;
&lt;h3 id="ctes"&gt;
&lt;div&gt;
CTEs
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;First, yes they can be an optimisation boundary. But they can also make your query much more read-able and prevent you from doing the wrong thing because you couldn&amp;rsquo;t reason about a query.&lt;/p&gt;
&lt;p&gt;For those unfamiliar CTEs are like a view that exist just for the duration of that query being executed. You can have them reference previous CTEs so you can gradually build on them, much like you would code blocks. I won&amp;rsquo;t repeat too much of what &lt;a href="/2013/11/18/best-postgres-feature-youre-not-using/"&gt;I&amp;rsquo;ve already written about them&lt;/a&gt;, but if you&amp;rsquo;re unfamiliar with them or not using them &lt;a href="/2013/11/18/best-postgres-feature-youre-not-using/"&gt;they are a must&lt;/a&gt;. CTEs are easily one of the few pieces of SQL that I use on a daily basis.&lt;/p&gt;
&lt;h3 id="conclusion"&gt;
&lt;div&gt;
Conclusion
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Of course this isn&amp;rsquo;t the only way to make your SQL more readable and this isn&amp;rsquo;t an exhaustive list. But hopefully you find these tips helpful, and for your favorite tip that I missed&amp;hellip; let me know about it &lt;a href="http://www.twitter.com/craigkerstiens"&gt;@craigkerstiens&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;A special thanks to &lt;a href="http://www.twitter.com/Case"&gt;@Case&lt;/a&gt; for reviewing.&lt;/em&gt;&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Fri, 08 Jan 2016 22:55:56 GMT</pubDate><guid isPermaLink="true">/2016/01/08/Writing-more-legible-SQL/</guid></item><item><title>Janathon 2016 #8 - Sitting on trains doesn't count</title><link>https://rjp.is/blogging/posts/janathon-2016-8-sitting-on-trains-doesnt-count-2/</link><description>Since I&amp;rsquo;ll be doing many hours of that later and the insomnia prevents me from getting enough sleep to be able to get up sufficiently early to knock out a quick morning run before work and it&amp;rsquo;s cold and I&amp;rsquo;m tired and not feeling very well and WAH WAH WAH WAH WAH.
Anyway. Walking to Starbucks will have to do for today.
Tomorrow will make up for it&amp;hellip;
[Just over 2km]</description><author>infrequent oscillations</author><pubDate>Fri, 08 Jan 2016 14:11:08 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-8-sitting-on-trains-doesnt-count-2/</guid></item><item><title>Janathon 2016 #7 - Insomnia strikes</title><link>https://rjp.is/blogging/posts/janathon-2016-7-insomnia-strikes-2/</link><description>One of my (annoyingly frequent) bouts of insomnia struck leaving today a thorough write-off. No point trying to force through today&amp;rsquo;s run when it might risk the the weekend&amp;rsquo;s fun*.
* Not fun.
[Barely 2.5km from DLR to home]</description><author>infrequent oscillations</author><pubDate>Fri, 08 Jan 2016 00:08:48 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-7-insomnia-strikes-2/</guid></item><item><title>Janathon 2016 #6 - Slow Boat To Home</title><link>https://rjp.is/blogging/posts/janathon-2016-6-slow-boat-to-home-2/</link><description>Well, not a boat, but Shanks&amp;rsquo;s Pony (look it up.)
With the world&amp;rsquo;s tiniest game of football (ok, I kicked a ball back to someone by Island Gardens DLR) and a very brief stop in Greenwich Superdrug for some protein snacks.
All whilst carrying 2kg of biltong. I tell you, it&amp;rsquo;s 24/7 non-stop literally all out party time excitement.
[Biltong carrying trundle]</description><author>infrequent oscillations</author><pubDate>Thu, 07 Jan 2016 01:06:28 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-6-slow-boat-to-home-2/</guid></item><item><title>How to make a blog like this</title><link>https://bytepawn.com/how-to-make-a-blog-like-this.html</link><description>&lt;p&gt;Make a simple blog with Github Pages and Pelican.&lt;/p&gt;</description><author>Bytepawn - Marton Trencseni</author><pubDate>Thu, 07 Jan 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://bytepawn.com/how-to-make-a-blog-like-this.html</guid></item><item><title>Airflow review</title><link>https://bytepawn.com/airflow.html</link><description>&lt;p&gt;Airflow is a workflow scheduler written by Airbnb. It supports defining tasks and dependencies as Python code, executing and scheduling them, and distributing tasks across worker nodes. It supports calendar scheduling (hourly/daily jobs, also visualized on the web dashboard), so it can be used as a starting point for traditional ETL. It has a nice web dashboard for seeing current and past task state, querying the history and making changes to metadata such as connection strings.&lt;br /&gt;&lt;br /&gt;&lt;img alt="Airflow" src="/images/airflow-main-view.png" style="width: 400px;" /&gt;&lt;/p&gt;</description><author>Bytepawn - Marton Trencseni</author><pubDate>Wed, 06 Jan 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://bytepawn.com/airflow.html</guid></item><item><title>Systems thinking and system traps</title><link>https://bytepawn.com/systems-thinking.html</link><description>&lt;p&gt;Thinking in Systems, written by the late Donella Meadows, is a book about how to think about systems, how to control systems and how systems change and control themselves. A system can be anything from a heating furnace to a social system. The gem of the book is the part about system traps. System traps are ways a system can go wrong; examples are drift to low performance, seeking the wrong goals, shifting the burden, etc.&lt;br /&gt;&lt;br /&gt;&lt;img alt="Thinking in systems" src="/images/thinking-in-systems.png" style="width: 400px;" /&gt;&lt;/p&gt;</description><author>Bytepawn - Marton Trencseni</author><pubDate>Wed, 06 Jan 2016 01:00:00 GMT</pubDate><guid isPermaLink="true">https://bytepawn.com/systems-thinking.html</guid></item><item><title>Janathon 2016 #5 - A trundle t't Curp</title><link>https://rjp.is/blogging/posts/janathon-2016-5-a-trundle-tt-curp-2/</link><description>From work t't Curp I ran With the sounds of a labouring man My knees creaked like biscuits And I leaked like a whippet Until I resembled peach flan About 12km t&amp;rsquo;t Curp</description><author>infrequent oscillations</author><pubDate>Wed, 06 Jan 2016 00:12:16 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-5-a-trundle-tt-curp-2/</guid></item><item><title>Janathon 2016 #4 - Furshernchurps</title><link>https://rjp.is/blogging/posts/janathon-2016-4-furshernchurps-2/</link><description>A while back I decided I was going to have fish and chips on Fridays. Obviously, being old and senile, that fell by the wayside pretty quickly. Until I remembered earlier and designated today &amp;ldquo;Honorary (if I walk to Blackheath Station chippy) Friday&amp;rdquo;.
No heart strap today which means no heart rate data from the Garmin but here&amp;rsquo;s the data from the Fitbit.
(In theory, I could merge the TCX files from both but&amp;hellip;)</description><author>infrequent oscillations</author><pubDate>Mon, 04 Jan 2016 21:55:45 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-4-furshernchurps-2/</guid></item><item><title>Scraping websites with Cyborg</title><link>https://tomforb.es/blog/scraping-websites-with-cyborg/</link><description>I often find myself creating one-off scripts to scrape data off websites for various reasons. My go-to approach for this is to hack something together with Requests and BeautifulSoup , but this was getting tiring. Enter Cyborg , my library that makes writing web scrapers quick and easy. Cyborg is an...</description><author>Tom Forbes</author><pubDate>Mon, 04 Jan 2016 02:13:02 GMT</pubDate><guid isPermaLink="true">https://tomforb.es/blog/scraping-websites-with-cyborg/</guid></item><item><title>Janathon 2016 #3 - two runs, one cup (of coffee)</title><link>https://rjp.is/blogging/posts/janathon-2016-3-two-runs-one-cup-of-coffee-2/</link><description>Had to go and pick up some extra drone batteries (which may turn out to be a mistake - the 500mAh one it came with hadn&amp;rsquo;t died after 12 minutes and these are 680mAh - giving me at least an hour of cumulative flight) and I decided that running there and back would make up for lazing about watching Elementary all day.
(Plus it would earn me a coffee and croissant.</description><author>infrequent oscillations</author><pubDate>Sun, 03 Jan 2016 20:36:20 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-3-two-runs-one-cup-of-coffee-2/</guid></item><item><title>How Necessary Are Those Expenses?</title><link>https://tiltingatwindmills.dev/how-necesse-expenses/</link><description>One of the key elements of personal finance is separating "needs" from
"wants". Every guide to controlling your budget usually starts with…</description><author>Tilting at Windmills</author><pubDate>Sun, 03 Jan 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://tiltingatwindmills.dev/how-necesse-expenses/</guid></item><item><title>2015 Year in Review</title><link>https://benovermyer.com/blog/2016/01/2015-year-in-review/</link><description>&lt;p&gt;2015 was a year of big changes for me. The biggest was starting on the path to divorce and moving into my own apartment. For the first time in my life, I'm living completely on my own. That feels very different, and very exciting. I also had my first anxiety attack earlier in the year. Since then, while I haven't had any more, I've definitely felt more anxious and vulnerable than before. This is strange, since prior to the attack, I always felt like I didn't worry about anything. I'm still mystified as to why it happened.&lt;/p&gt;
&lt;p&gt;Continuing the health-related theme, in December I noticed that I had lost ten pounds since the last time I'd been weighed. I chalked it up to my new method of commuting since moving into the apartment - walking to work. I'm not convinced that was completely the case anymore, but it was probably a big contributor. The holidays erased half of that loss, but eh, I can recover from that. I established a habit of doing push-ups every morning after waking, I'm working on my nutrition, and I joined Bodyspace, a fitness social networking run by Bodybuilding.com.&lt;/p&gt;
&lt;p&gt;At work, I went from being sole operations engineer on a legacy platform to lead operations engineer on a team that helped launched a brand-new platform to, in October, digital operations manager. Granted, I'm a “working manager,” and still spend a lot of time on the engineering side of things. Starting in November, I began budgeting in earnest. I'm much more aware of where my money is going and for the first time in well over a decade I feel in control of my finances. I've kept it up, and by this point I think budgeting has become a daily habit. 2015 was very stressful. 2016 seems full of promise and I'm very optimistic about the future. Here's to a year of health and personal growth!&lt;/p&gt;</description><author>Ben Overmyer's Site</author><pubDate>Sun, 03 Jan 2016 02:00:00 GMT</pubDate><guid isPermaLink="true">https://benovermyer.com/blog/2016/01/2015-year-in-review/</guid></item><item><title>Janathon 2016 #2 - even slower and even easier</title><link>https://rjp.is/blogging/posts/janathon-2016-2-even-slower-and-even-easier-2/</link><description>Didn&amp;rsquo;t feel like parkrun (too tired, upset stomach) but eventually stirred for what was going to be a 5km coffee jaunt but which turned into a hilly* 10km coffee wander and then a 6km wet wander home for a total of just over 16km (10 miles for imperialistic loons.)
Elevation graph for the hilly jaunt, a la Buko, via Strava
Out to Woolwich&amp;hellip; And back</description><author>infrequent oscillations</author><pubDate>Sun, 03 Jan 2016 00:19:51 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-2016-2-even-slower-and-even-easier-2/</guid></item><item><title>Janathon 2016 #1 - Slow but easy</title><link>https://rjp.is/blogging/posts/janathon-1-2/</link><description>I was hoping to do a double-parkrun this morning but the start times were inconvenient - whilst I could get to (not-)Greenwich parkrun for 09:00 (Sunday bus service notwithstanding), getting from there to the other options (Hilly Fields, 10:00; Southwark, 10:30) wasn&amp;rsquo;t possible unless I cycled. And who wants to cycle 20km+ just for two parkruns?
Southwark won by dint of being easier to get to (and later).
Southwark parkrun, 29:05, Strava</description><author>infrequent oscillations</author><pubDate>Fri, 01 Jan 2016 20:35:46 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/janathon-1-2/</guid></item></channel></rss>