<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Christopher Prohm</title>
        <link>https://cprohm.de</link>
        <description></description>
        <generator>Zola</generator>
        <language>en</language>
        <atom:link href="https://cprohm.de/rss.xml" rel="self" type="application/rss+xml"/>
        <lastBuildDate>Sun, 05 Oct 2025 00:00:00 +0000</lastBuildDate>
        
            
            <item>
                <title>Reducing boilerplate in Serde serializers with nested Rust macros</title>
                <pubDate>Sun, 05 Oct 2025 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/nested-macros/</link>
                <guid>https://cprohm.de/blog/nested-macros/</guid>
                <description>&lt;p&gt;The implementation of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;serde_arrow&quot;&gt;&lt;code&gt;serde-arrow&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; features many serializers, one for each Arrow
data type and some additional serializers to connect everything. Each of these serializers requires
the implementation of all of the 28 required methods of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;serde&#x2F;1.0.228&#x2F;serde&#x2F;trait.Serializer.html&quot;&gt;&lt;code&gt;serde::Serializer&lt;&#x2F;code&gt; trait&lt;&#x2F;a&gt;. This
combination results in lots of repetitive code. In this post, I would like to explain my attempt to
simplify this setup using macros and a trick of writing nested macros I encountered along the way.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Building a custom elements Pomodoro timer: from React to Web Components</title>
                <pubDate>Sun, 30 Mar 2025 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/tomato-timer-v2/</link>
                <guid>https://cprohm.de/blog/tomato-timer-v2/</guid>
                <description>&lt;p&gt;For some time now, I&#x27;ve been using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pomodoro_Technique&quot;&gt;Pomodoro Technique&lt;&#x2F;a&gt; to structure myself and maintain
focus when working on complex tasks, such as programming or writing projects. Since 2014, I have
been using my &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;tomato-timer-the-pomodoro-technique.html&#x2F;&quot;&gt;own spin&lt;&#x2F;a&gt; on a Pomodoro timer written in React. Recently, I took some time to
rewrite it as a custom element. In this post, I would like to share my learnings.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Refactoring serde_arrow</title>
                <pubDate>Wed, 11 Sep 2024 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/serde-arrow-refactor/</link>
                <guid>https://cprohm.de/blog/serde-arrow-refactor/</guid>
                <description>&lt;p&gt;Currently, I am  in the midst of a major refactoring effort for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;serde_arrow&quot;&gt;&lt;code&gt;serde_arrow&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.
Prompted by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;serde_arrow&#x2F;pull&#x2F;218#issuecomment-2279127552&quot;&gt;this comment&lt;&#x2F;a&gt; by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;v1gnesh&quot;&gt;v1gnesh&lt;&#x2F;a&gt; on the related PR, I would like to
summarize the ideas behind the changes and outline future plans.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>ipytest.cov - Coverage.py in Jupyter notebooks</title>
                <pubDate>Sat, 27 Jan 2024 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/ipytest-cov/</link>
                <guid>https://cprohm.de/blog/ipytest-cov/</guid>
                <description>&lt;p&gt;Understanding which parts of your code is exercised by tests via code coverage can be essential.
Therefore, I am happy that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;&lt;code&gt;ipytest&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; supports coverage inside notebooks starting with release 0.14.1.
This release includes &lt;code&gt;ipytest.cov&lt;&#x2F;code&gt;, a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;coverage.readthedocs.io&#x2F;en&#x2F;7.4.4&#x2F;&quot;&gt;Coverage.py&lt;&#x2F;a&gt; plugin, that also allows to use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pytest-cov.readthedocs.io&#x2F;en&#x2F;latest&#x2F;&quot;&gt;&lt;code&gt;pytest-cov&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; in notebooks.
In this blog post I would like to describe the underlying &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nedbat&#x2F;coveragepy&#x2F;issues&#x2F;1762&quot;&gt;issue&lt;&#x2F;a&gt; and how &lt;code&gt;ipytest&lt;&#x2F;code&gt; solves it.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Whisper in ONNX with key value caching pt. 2</title>
                <pubDate>Mon, 18 Dec 2023 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/whisper-full/</link>
                <guid>https://cprohm.de/blog/whisper-full/</guid>
                <description>&lt;p&gt;As promised in the &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;blog&#x2F;whisper-kv-caching&#x2F;&quot;&gt;last post&lt;&#x2F;a&gt;, I will cover the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;onnx.ai&quot;&gt;ONNX&lt;&#x2F;a&gt; conversion
of the full &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;openai&#x2F;whisper&quot;&gt;Whisper&lt;&#x2F;a&gt; model, including key-value caching, in this post.
The full model resists a straightforward ONNX conversion due to its reliance on
hooks and branching control flow. In this post I will discuss how to patch the
model to make it exportable.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Whisper in ONNX with key value caching pt. 1</title>
                <pubDate>Sun, 19 Nov 2023 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/whisper-kv-caching/</link>
                <guid>https://cprohm.de/blog/whisper-kv-caching/</guid>
                <description>&lt;p&gt;This post continues my quest to convert the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;openai&#x2F;whisper&quot;&gt;Whisper&lt;&#x2F;a&gt; model to ONNX.
&lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;blog&#x2F;whisper&#x2F;&quot;&gt;Last time&lt;&#x2F;a&gt;, I discussed how to convert the model without the optional
performance optimization of key value caching. After some trial and error, I
managed to convert the full model. In this post, I will discuss how the Whisper
model implements key value caching, before I cover the actual conversion in the
next post.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Whisper in ONNX </title>
                <pubDate>Sun, 12 Nov 2023 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/whisper/</link>
                <guid>https://cprohm.de/blog/whisper/</guid>
                <description>&lt;p&gt;Recently, I have been looking into using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;openai&#x2F;whisper&quot;&gt;Whisper&lt;&#x2F;a&gt; text to speech
model from Rust. While packages like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;burn.dev&#x2F;&quot;&gt;burn&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;huggingface&#x2F;candle&quot;&gt;candle&lt;&#x2F;a&gt; do look
quite promising and do offer Whisper models, I decided to stick with
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;onnx.ai&#x2F;&quot;&gt;ONNX&lt;&#x2F;a&gt; for now, as it served me quite well in the past. In this post, I
would like to discuss the necessary steps to convert the Whisper model to ONNX.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Vega-Lite plots with HTMX using custom elements</title>
                <pubDate>Sun, 03 Sep 2023 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/vega-with-htmx/</link>
                <guid>https://cprohm.de/blog/vega-with-htmx/</guid>
                <description>&lt;p&gt;In this post I would like to describe how to create Vega-Lite plots that
integrate nicely into an HTMX application. A difficulty in the design is that
Vega requires asynchronous operations and the newly created element must ensure
updates are applied in the correct order. In the following I describe the issue
and a potential solution.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Nested declarative macros for enum dispatch in Rust</title>
                <pubDate>Mon, 14 Aug 2023 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/rust-macros/</link>
                <guid>https://cprohm.de/blog/rust-macros/</guid>
                <description>&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;serde_arrow&quot;&gt;&lt;code&gt;serde_arrow&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; relies heavily on Rust macros to remove code
duplication. One prominent example is the bytecode introduced in version &lt;code&gt;0.7&lt;&#x2F;code&gt;.
It compiles the underlying state machines into a list of instructions that are
then interpreted. Each instruction is one of a large number of variants in an
enum. In this post I would like to summarize how &lt;code&gt;serde_arrow&lt;&#x2F;code&gt; uses nested
declarative macross, that is macros defining macros, to avoid code duplication
in the interpreter.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Self contained task runners in Python</title>
                <pubDate>Thu, 08 Jun 2023 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/taskfiles/</link>
                <guid>https://cprohm.de/blog/taskfiles/</guid>
                <description>&lt;p&gt;Every coding project has recurring tasks, like test execution or code
generation. Over the years I been exploring a variety of ways to include these
tasks in an executable form as part of the repository. They range from
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Make_(software)&quot;&gt;&lt;code&gt;make&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pyinvoke.org&#x2F;&quot;&gt;&lt;code&gt;invoke&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;taskfile.dev&#x2F;&quot;&gt;&lt;code&gt;task&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;casey&#x2F;just&quot;&gt;&lt;code&gt;just&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. As of
late, I started to rely more and more on plain self-contained Python scripts for
my own projects. In this post, I would like to describe the technical details
and why I like this setup.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Plotting Polars data frames with Seaborn</title>
                <pubDate>Tue, 21 Feb 2023 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/polars-seaborn/</link>
                <guid>https://cprohm.de/blog/polars-seaborn/</guid>
                <description>&lt;p&gt;Recently, I found myself using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pola.rs&#x2F;&quot;&gt;Polars&lt;&#x2F;a&gt; more and more as my data frame
library of choice. Compared to Pandas, it has much better support for complex
column types, like list of structs, but also better performance.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pandas.pydata.org&#x2F;&quot;&gt;Pandas&lt;&#x2F;a&gt; however is  still clearly the most popular data frame library
in the ecosystem. Case in point, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;seaborn.pydata.org&quot;&gt;Seaborn&lt;&#x2F;a&gt; does not support  Polars
data frames out of the box. In this post, I would like to walk you through a
quick way to combine both libraries.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Mixing React and htmx</title>
                <pubDate>Tue, 18 Oct 2022 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/htmx-react/</link>
                <guid>https://cprohm.de/blog/htmx-react/</guid>
                <description>&lt;p&gt;A recent project required a complex HTML user interface with multiple
interdependent elements. With the goal of using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;htmx.org&#x2F;&quot;&gt;hmtx&lt;&#x2F;a&gt;, I implemented the
initial prototype using custom elements, but it grew in complexity quite fast.
In the end, I found this to be one occasion in which &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;reactjs.org&#x2F;&quot;&gt;React&lt;&#x2F;a&gt; provides a
clean and elegant way to structure code and data flow. Not content with giving
up on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;htmx.org&#x2F;&quot;&gt;htmx&lt;&#x2F;a&gt; for the rest of the application, I set out to combine both
libraries. In this blog post I would like to walk you through the resulting
setup.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>React &amp; htmx</title>
                <pubDate>Tue, 18 Oct 2022 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/gists/react-htmx/</link>
                <guid>https://cprohm.de/gists/react-htmx/</guid>
                <description>&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;html&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;script&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    src&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;unpkg.com&#x2F;react@18&#x2F;umd&#x2F;react.development.js&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    integrity&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;sha384-0HL&#x2F;VWVbwweJfp0saUL50fXRuSABCdVeinTBoJCDXprLkJ49VI0QMWNGMRt8ebnT&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    crossorigin&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;anonymous&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;script&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;script&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    src&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;unpkg.com&#x2F;react-dom@18&#x2F;umd&#x2F;react-dom.development.js&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    integrity&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;sha384-79Od0yhavbvtuP2nWl+Y6mwgs8AlknSIikYSw0+uOc65GTyH8SW7e2hCyCB303Y2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    crossorigin&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;anonymous&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;script&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;script&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    src&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;unpkg.com&#x2F;htmx.org@1.8.2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    integrity&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;sha384-+8ISc&#x2F;waZcRdXCLxVgbsLzay31nCdyZXQxnsUy++HJzJliTzxKWr0m1cIEMyUzQu&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    crossorigin&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;anonymous&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;script&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;customElements.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    &amp;quot;react-root&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    class extends&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; HTMLElement&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        constructor&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;            super&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;            this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;attachShadow&lt;&#x2F;span&gt;&lt;span&gt;({mode:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;open&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;            this&lt;&#x2F;span&gt;&lt;span&gt;.root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MutationObserver&lt;&#x2F;span&gt;&lt;span&gt;(()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;render&lt;&#x2F;span&gt;&lt;span&gt;()).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;observe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;                this&lt;&#x2F;span&gt;&lt;span&gt;,  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    subtree:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    childList:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    attributes:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    attributeFilter: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;props&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        render&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;                this&lt;&#x2F;span&gt;&lt;span&gt;.root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ReactDOM.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;createRoot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.shadowRoot);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; element&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; window[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.rootType];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt;(element&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                throw new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;`Could not find component ${&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;rootType&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;}`&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;            this&lt;&#x2F;span&gt;&lt;span&gt;.root.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;render&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                React.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;createElement&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    element, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    {root:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.rootProps},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        get&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; rootType&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; el&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;querySelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;react-element&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; (el&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; el.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;getAttribute&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        get&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; rootProps&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; el&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;querySelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;react-element&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; (el&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; JSON&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span&gt;(el.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;getAttribute&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;props&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        set&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; rootType&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; el&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;querySelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;react-element&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt;(el&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; throw new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;Not template element found&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            el.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;setAttribute&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        set&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; rootProps&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; el&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;querySelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;react-element&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt;(el&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; throw new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;Not template element found&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            el.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;setAttribute&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;props&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; JSON&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;stringify&lt;&#x2F;span&gt;&lt;span&gt;(value));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        disconnectedCallback&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;                this&lt;&#x2F;span&gt;&lt;span&gt;.root.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;unmount&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;                this&lt;&#x2F;span&gt;&lt;span&gt;.root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
            </item>
            
        
            
            <item>
                <title>Reusable htmx components with custom elements</title>
                <pubDate>Mon, 16 May 2022 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/htmx-custom-elements/</link>
                <guid>https://cprohm.de/blog/htmx-custom-elements/</guid>
                <description>&lt;p&gt;While working on my &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;blog&#x2F;rust-journey&#x2F;&quot;&gt;chat bot project&lt;&#x2F;a&gt;, I was recently looking for a
way to test locally on my laptop before pushing to my phone. To make inroads
quickly, I settled on a local web app. But neither manual dom manipulation nor a
full scale single page app felt particularly appealing. Luckily, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;htmx.org&#x2F;&quot;&gt;htmx&lt;&#x2F;a&gt;
offers a middle ground - as it turns out a quite productive one.&lt;&#x2F;p&gt;
&lt;p&gt;In this post I would like to showcase how custom elements allow to build
reusable components that encapsulate the htmx configuration and the handling of
htmx events.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>cargo without project</title>
                <pubDate>Wed, 11 Aug 2021 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/cargo-wop/</link>
                <guid>https://cprohm.de/blog/cargo-wop/</guid>
                <description>&lt;p&gt;Trying out ideas quickly and iterating on the details have become central to my
style of working ever since I started using Python. Exactly this kind of
interactivity I miss, when I use Rust. In the absence of a proper repl, I found
small scripts to be the next best thing. To support this setup, I wrote a crate
called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;cargo-wop&#x2F;&quot;&gt;cargo-wop&lt;&#x2F;a&gt; that I found quite helpful and would like to
showcase in this blog post in the hope that it may also be helpful to others.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Rust: the emergent complexity of a simple language</title>
                <pubDate>Fri, 19 Mar 2021 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/rust-followup/</link>
                <guid>https://cprohm.de/blog/rust-followup/</guid>
                <description>&lt;p&gt;As promised &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;blog&#x2F;rust-journey&#x2F;&quot;&gt;last time&lt;&#x2F;a&gt;, I would like to reflect a bit about Rust
after using it for the last year. This post is not meant to be an introduction
to Rust, rather I would like to give you subjective view of how it feels to use
Rust&lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;blog&#x2F;rust-followup&#x2F;#fn1&quot;&gt;1&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>The project that got me started with Rust</title>
                <pubDate>Mon, 15 Feb 2021 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/rust-journey/</link>
                <guid>https://cprohm.de/blog/rust-journey/</guid>
                <description>&lt;p&gt;When all these articles featuring &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt; as one of the most beloved
programming languages came out, I was rather sceptic. Coming from C++ I expected
a complex and hard to pick up language. At some point though, curiosity got the
better of me and after a bit over a year I have to admit: I am sold. In
the near future, I plan to write a bit more about my experience with Rust.
To set the stage, I would like to sketch how I ended up using Rust in this post
by tracing the evolution of a long-running personal project.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Linearizing graphs</title>
                <pubDate>Sun, 03 Jan 2021 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/graph-linearization/</link>
                <guid>https://cprohm.de/blog/graph-linearization/</guid>
                <description>&lt;p&gt;From my time to time I find myself in the situation of having to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Topological_sorting&quot;&gt;linearize
graphs&lt;&#x2F;a&gt;. Typically this issue comes up in the context of task
scheduling. When tasks have dependencies among themselves, they form a directed
acyclical graph. Finding an order of the tasks that respects their dependencies
is called a topological sorting or linearization. In the following, I will use
the term linearization, as it seems more self-explanatory. In this post I would
like to discuss  a simple algorithm for graph linearization and compare how this
problem is solved in the context of multiple inheritance in Python.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Hacking python&#x27;s import system for single file packages</title>
                <pubDate>Wed, 27 May 2020 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/blog/python-packages-in-a-single-file/</link>
                <guid>https://cprohm.de/blog/python-packages-in-a-single-file/</guid>
                <description>&lt;p&gt;The last couple of days I have been playing around with the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kaggle.com&#x2F;c&#x2F;halite&quot;&gt;Kaggle Halite
environment&lt;&#x2F;a&gt;. Quickly, I ran into issues with their requirement
that any agent has to be a single python file. Initially, my code was short and
easy to keep self-contained. However, after adding more and more functionality,
it soon became unwieldy and unintelligible. At this point, I decided to look
for alternatives. In this blog post, I describe how to hack Python&#x27;s import
system to embed full packages into a single python module.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
        
            
            <item>
                <title>asyncio testing inside notebooks</title>
                <pubDate>Sun, 28 Jul 2019 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/asyncio-testing-inside-notebooks.html/</link>
                <guid>https://cprohm.de/article/asyncio-testing-inside-notebooks.html/</guid>
                <description>&lt;p&gt;Recently I started to work on a project mixing lots of network IO and concurrent
tasks. Due to these requirements
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;asyncio.html&quot;&gt;asyncio&lt;&#x2F;a&gt; seemed like a prefect
fit. However this project was also my first big foray into the async world of
python and I needed a bit of time to learn the ropes. As mentioned in a
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;notebooks-and-modules.html&quot;&gt;previous post&lt;&#x2F;a&gt;, I do love
to familiarize myself with new technology by experimenting in a notebook and
only then to refactor the result into python packages.&lt;&#x2F;p&gt;
&lt;p&gt;In this blog post, I would like to show how to combine asyncio and pytest inside
notebooks. IPython has had an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.jupyter.org&#x2F;ipython-7-0-async-repl-a35ce050f7f7&quot;&gt;excellent async
support&lt;&#x2F;a&gt; for quite
some while now. However, running async tests inside IPython requires a bit of
care. Below I describe what changes in
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;&lt;code&gt;ipytest&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; were necessary.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Prototyping to tested code, or developing across notebooks and modules</title>
                <pubDate>Thu, 08 Nov 2018 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/notebooks-and-modules.html/</link>
                <guid>https://cprohm.de/article/notebooks-and-modules.html/</guid>
                <description>&lt;p&gt;Two weeks ago, I was lucky enough to attend the PyCon.DE 2018 in Karsruhe. I
also got the opportunity to present my ideas on the role of notebooks and
modules in Python development, with a particular focus on testing. Since the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;static&#x2F;slides&#x2F;IPyTestIntro.slides.html&quot;&gt;slides&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=8fg7AkvG-Oc&quot;&gt;video&lt;&#x2F;a&gt; are available online, I do not want to rehash the talk
here, but rather spend the bulk of this post to explain my setup in more detail.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Causality and function approximations</title>
                <pubDate>Sun, 26 Aug 2018 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/causality-and-function-approximations.html/</link>
                <guid>https://cprohm.de/article/causality-and-function-approximations.html/</guid>
                <description>&lt;p&gt;Motivated by the recent release of Judea Pearl&#x27;s Book of Why, I started to sort
my notes on causality and write some parts down in a more structured way. In
doing so, I stumbled over a question I bumped into repeatedly in past projects:
The simplest causal system is one in which features determine actions and the
combination of features and actions determine the outcome. One popular approach
for this system is to apply inverse probability of treatment weighting. My
intuition always was that this step should not be necessary. After some
research, the answer is a resounding &quot;Yes, but ...&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;In short: no causal treatment is necessary for this system according to theory.
However, causal treatment becomes important when applying function
approximations with limited capacity (or AI).&lt;&#x2F;p&gt;
&lt;p&gt;The options sketched above are often discussed under the names &quot;direct method&quot;
(no reweighting) and &quot;inverse propensity score method&quot; (reweighting). Both
methods can be used to estimate causal effects, but typically the latter is
preferred over the former [e.g., 6].  To investigate this issue, I turned
multiple times to simulated data in the past, but more often than not, failed to
observe shortcomings of the direct method. The goal of this post is to discuss
one particular way the direct method can fail, specifically in the case of model
regularization.&lt;&#x2F;p&gt;
&lt;p&gt;The rest of the blog post is structured as follows: After a brief reminder on
causality, I will apply Judea Pearl&#x27;s causal calculus and derive that
reweighting is not necessary.  I will demonstrate numerically that reweighting
becomes important however when applying function approximations with limited
capacity (here, linear models and gradient boosted trees).  Finally, I show how
the effects can be explained analytically for a linear model fitted with maximum
likelihood and \(L_2\)  regularization.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Better test output with AST rewriting and a patched standard library</title>
                <pubDate>Wed, 20 Jun 2018 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/better-test-output-with-ast-rewriting-and-a-patched-standard-library.html/</link>
                <guid>https://cprohm.de/article/better-test-output-with-ast-rewriting-and-a-patched-standard-library.html/</guid>
                <description>&lt;p&gt;Quite often, I prototype code in notebooks. To make it easier to transfer the
code outside, I also write tests using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;ipytest&lt;&#x2F;a&gt;, a small package I
&lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;ipytest-running-pytest-in-ipython-notebooks.html&#x2F;&quot;&gt;wrote a while back&lt;&#x2F;a&gt;. However, I never could get &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.pytest.org&#x2F;en&#x2F;latest&#x2F;&quot;&gt;pytest&lt;&#x2F;a&gt;&#x27;s
nice assertions to work properly. Prompted by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&#x2F;issues&#x2F;2&quot;&gt;this GH issue&lt;&#x2F;a&gt;, I decided
to have another look.&lt;&#x2F;p&gt;
&lt;p&gt;To cut a long story short: the current version of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;ipytest&lt;&#x2F;a&gt; offers the
full &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.pytest.org&#x2F;en&#x2F;latest&#x2F;&quot;&gt;pytest&lt;&#x2F;a&gt; experience from inside the notebook. Just run &lt;code&gt;pip install ipytest&lt;&#x2F;code&gt; and give it a try.&lt;&#x2F;p&gt;
&lt;p&gt;In the following paragraphs I would like to describe how I implemented the
assertion support. But first: did you ever wonder how Jupyter shows stack
traces? Bear with me. It is less obvious than it sounds. As a motivating
example, consider running the following code inside a notebook&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; foo&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    raise&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;foo()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you do, you get a nice stack trace similar to&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-------------------------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ValueError                  Traceback (most recent call last)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;Code&#x2F;misc-exp&#x2F;BuildingBlocks&#x2F;TimeSeries.ipynb in &amp;lt;module&amp;gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      2     raise ValueError()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;----&amp;gt; 4 foo()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;Code&#x2F;misc-exp&#x2F;BuildingBlocks&#x2F;TimeSeries.ipynb in foo()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      1 def foo():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;----&amp;gt; 2     raise ValueError()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      4 foo()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ValueError:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So far so good. But when you now try to use the builtin &lt;code&gt;exec&lt;&#x2F;code&gt; function, things
start to break down. Just execute&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;exec&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;def foo():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    raise ValueError()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;foo()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and the stack trace becomes a disappointing&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-------------------------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ValueError                  Traceback (most recent call last)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;Code&#x2F;misc-exp&#x2F;BuildingBlocks&#x2F;TimeSeries.ipynb in &amp;lt;module&amp;gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      5 foo()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;----&amp;gt; 6 &amp;#39;&amp;#39;&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;Code&#x2F;misc-exp&#x2F;BuildingBlocks&#x2F;TimeSeries.ipynb in &amp;lt;module&amp;gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;Code&#x2F;misc-exp&#x2F;BuildingBlocks&#x2F;TimeSeries.ipynb in foo()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ValueError:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It does neither show source code nor line numbers making debugging quite painful
(in the python interpreter you get line numbers, but still no source). However,
surely there has to be a way to fix this issue: in Jupyter most code is run via
&lt;code&gt;exec&lt;&#x2F;code&gt;, but exceptions reliably give nice stack traces.&lt;&#x2F;p&gt;
&lt;p&gt;Naively, I hoped to find a documented API somewhere in the python standard
library. After an hour of fruitless search, I decided to have a look into how
IPython is doing it (that you can is one of the reasons I love open source). As
it turns out there is no API after all and IPython relies on Python internals to
show stack traces.&lt;&#x2F;p&gt;
&lt;p&gt;The relevant code starts in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ipython&#x2F;ipython&#x2F;blob&#x2F;64afe4bb29863d109647fc79431bca31916cfcbe&#x2F;IPython&#x2F;core&#x2F;interactiveshell.py#L2636&quot;&gt;&lt;code&gt;InteractiveShell.run_cell&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; with the
skeleton&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cell_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.compile.cache(cell,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.execution_count)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;code_ast&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; compiler.ast_parse(cell,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; filename&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;cell_name)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;code_ast&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.transform_ast(code_ast)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.run_ast_nodes(code_ast.body, cell_name,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; ...&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the most part, the codes reads how I would have written it. Only the line
where the cell code is cached sticks out. When you dig deeper, you will find in
essence the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ipython&#x2F;ipython&#x2F;blob&#x2F;64afe4bb29863d109647fc79431bca31916cfcbe&#x2F;IPython&#x2F;core&#x2F;compilerop.py&quot;&gt;following code&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# Stdlib imports&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; linecache&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# Now, we must monkeypatch the linecache directly so that parts of the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# stdlib that call it outside our control go through our codepath&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# (otherwise we&amp;#39;d lose our tracebacks).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;linecache.checkcache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; check_linecache_ipython&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; cache&lt;&#x2F;span&gt;&lt;span&gt;(self, code, number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    Returns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    -------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    The name of the cached code (as a string). Pass this as the filename&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    argument to compilation, so that tracebacks are correctly hooked up.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To summarize: IPython gets nice stack traces by monkeypatching the stdlib
&lt;code&gt;linecache&lt;&#x2F;code&gt; module and registering fictitious files. Once a traceback is
constructed, the patched cache is queried and the content of this fictitious
file returned. I have to admit this process seems a bit brittle in my eyes.&lt;&#x2F;p&gt;
&lt;p&gt;But back to the issue at hand: how to get nicely formatted asserts when running
&lt;code&gt;pytest&lt;&#x2F;code&gt; inside a notebook? When run on the commandline, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.pytest.org&#x2F;en&#x2F;latest&#x2F;&quot;&gt;&lt;code&gt;pytest&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; will
modify your code to execute additional steps that will show the inputs of the
assert. All the code modification magic lives inside the &lt;em&gt;internal&lt;&#x2F;em&gt; package
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pytest-dev&#x2F;pytest&#x2F;blob&#x2F;08aed1a6bf90e2b8641aa464b41a41f1e400b59e&#x2F;_pytest&#x2F;assertion&#x2F;rewrite.py&quot;&gt;&lt;code&gt;_pytest.assertion.rewrite&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. This module includes a function
&lt;code&gt;rewrite_asserts&lt;&#x2F;code&gt; that modified the AST passed to it.&lt;&#x2F;p&gt;
&lt;p&gt;So how did I end up implementing the assertion rewriting in &lt;code&gt;ipytest&lt;&#x2F;code&gt;? As you
do, I ignored package boundaries and simply hooked into the &lt;code&gt;pytest&lt;&#x2F;code&gt; internals
(the hypocrisy is not lost on me). Ignoring issues of encapsulation, you will
run into the problem of missing stack traces with &lt;code&gt;exec&lt;&#x2F;code&gt;, once you try to
execute the modified AST. Thankfully, we can just piggy back on IPython&#x27;s
solution to this problem.&lt;&#x2F;p&gt;
&lt;p&gt;After putting everything together, this code&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# cell 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; ipytest.magics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;__file__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;#39;Untitled.ipynb&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# cell 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;%%&lt;&#x2F;span&gt;&lt;span&gt;run_pytest&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_foo&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    actual&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; actual&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;gives nicely formatted error messages (including stack traces):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[...]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;============================ FAILURES ===========================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---------------------------- test_foo ---------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    def test_foo():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        actual = [1, 2, 3]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt;       assert actual == [2, 3, 4]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;E       assert [1, 2, 3] == [2, 3, 4]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;E         At index 0 diff: 1 != 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;E         Full diff:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;E         - [1, 2, 3]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;E         + [2, 3, 4]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;ipython-input-3-8b817ee3c044&amp;gt;:4: AssertionError&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;==================== 1 failed in 0.56 seconds ====================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you feel &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;ipytest&lt;&#x2F;a&gt; could be useful to you, I would love for you to
give it a try. Just install it via &lt;code&gt;pip install ipytest&lt;&#x2F;code&gt;. If you have any issues
or feedback, please feel free to contact me via &lt;em&gt;@c_prohm&lt;&#x2F;em&gt; on twitter or
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>Efficient Labeling in IPython</title>
                <pubDate>Mon, 13 Nov 2017 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/efficient-labeling-in-ipython.html/</link>
                <guid>https://cprohm.de/article/efficient-labeling-in-ipython.html/</guid>
                <description>&lt;p&gt;In &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;keyword-detection-from-scratch.html&#x2F;&quot;&gt;my last post&lt;&#x2F;a&gt; I described how to
detect speech commands in continuous audio signals.  One important ingredient
was a good amount of labeled data. Quite early on, it became clear to me that an
efficient labeling interface would be extremely helpful.  The first iteration of
that interface was a simple command-line app, quickly to be replaced by an
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ipywidgets.readthedocs.io&#x2F;en&#x2F;latest&#x2F;&quot;&gt;ipywidgets&lt;&#x2F;a&gt;-based interface.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Keyword detection from scratch</title>
                <pubDate>Sun, 13 Aug 2017 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/keyword-detection-from-scratch.html/</link>
                <guid>https://cprohm.de/article/keyword-detection-from-scratch.html/</guid>
                <description>&lt;p&gt;Anybody speaking even with the slightest of accents knows the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.wired.com&#x2F;2017&#x2F;03&#x2F;voice-is-the-next-big-platform-unless-you-have-an-accent&#x2F;&quot;&gt;agony&lt;&#x2F;a&gt; that is talking to voice recognition systems.  I ran
head-long into this issue, when I recently tried to use voice commands with my
computer.  Both systems I tested, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.apple.com&#x2F;documentation&#x2F;appkit&#x2F;nsspeechrecognizer&quot;&gt;NSSPeechRecognizer API&lt;&#x2F;a&gt; of OSX
and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cmusphinx.github.io&quot;&gt;CMU Sphinx&lt;&#x2F;a&gt;, failed miserably when confronted with my German
accent.  Slightly annoyed by this experience, I wondered, would it be really
that hard to create a customized solution from scratch? As it turns out, not
really, as I hope to convince you in the following paragraphs.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Minimalist personal cross device notes</title>
                <pubDate>Sun, 12 Mar 2017 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/minimalist-personal-cross-device-notes.html/</link>
                <guid>https://cprohm.de/article/minimalist-personal-cross-device-notes.html/</guid>
                <description>&lt;!-- intro --&gt;
&lt;p&gt;For quite some time now, I have been trying to optimize my note taking setup. In
the end it took me longer than I expected, since I was looking for&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;plain text format, preferably markdown&lt;&#x2F;li&gt;
&lt;li&gt;robust sync between Android and OSX&lt;&#x2F;li&gt;
&lt;li&gt;no cloud of any form&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Finding a solution that fit all my needs was surprisingly hard.  In particular,
the no-cloud requirement seems to be somewhat exotic in the age of connected
scales and connected toothbrushes.&lt;&#x2F;p&gt;
&lt;p&gt;Alas, the solution itself is quite simple: use a proven editor on either
platform (vim on OSX, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;2appstudio.com&#x2F;jotterpad&#x2F;&quot;&gt;jotterpad&lt;&#x2F;a&gt; on Android) and sync files via git.
Getting this setup to work robustly however took some time.  In this post, I
want to sketch my solution.&lt;&#x2F;p&gt;
&lt;!-- mobile --&gt;
&lt;p&gt;On Android, the main complication was finding a markdown editor that could read
from and write to directly the device memory.  After some research I settled on
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;2appstudio.com&#x2F;jotterpad&#x2F;&quot;&gt;jotterpad&lt;&#x2F;a&gt;, a clean, minimalist writing app.  Jotterpad has both a
base and premium version, the latter being fully worth its price: you get
markdown preview, syntax highlighting, and the extended keyboard, that makes
typing pure text bearable on android.&lt;&#x2F;p&gt;
&lt;!-- desktop --&gt;
&lt;p&gt;For OSX the choice was much easier, since I have been using vim as my editor of
choice for quite some time now.  When looking into possible plugin support, I
stumbled upon the Swiss army knife of vim-note-taking plugins,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;vimwiki.github.io&#x2F;&quot;&gt;vimwiki&lt;&#x2F;a&gt;.  Fully feature packed, it supports for example table
editing, navigation, and rendering.  In the end, I shied away from it, since
vim&#x27;s markdown support is pretty great already and I prefer unix-style tools,
that do one job and do it well.&lt;&#x2F;p&gt;
&lt;p&gt;The only feature I truly missed was the ability to follow links.  After
discovering &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;prashanthellina&#x2F;follow-markdown-links&quot;&gt;follow-markdown-links&lt;&#x2F;a&gt; lacked some features, most notably
support for reference-style links, i.e., [...][...], I created
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;mdnav&quot;&gt;mdnav&lt;&#x2F;a&gt;.  mdnav is is designed to work nice with local markdown files
(opened in vim), external URLs (opened in the OS browser), and non- markdown
files, such as PDFs (opened via &lt;code&gt;open&lt;&#x2F;code&gt; on OSX).  For a full list of what is
supported, please look at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;mdnav&quot;&gt;Readme&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;!--  sync --&gt;
&lt;p&gt;With editors on both platforms in place, only sync is missing.  Initially, I
tried &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.resilio.com&#x2F;individuals&#x2F;&quot;&gt;resilio-sync&lt;&#x2F;a&gt;, hopeful its drop box like interface would
simplify operations.  After some research, however, I was completely
underwhelmed by its conflict management.  &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;help.getsync.com&#x2F;hc&#x2F;en-us&#x2F;articles&#x2F;204754209-What-if-several-people-make-changes-to-the-same-file-&quot;&gt;Last write wins&lt;&#x2F;a&gt; is
simply not good enough for files such as to-do lists, that often change on both
devices at the same time.  In general, a tool that silently overwrites my
changes is not an option.&lt;&#x2F;p&gt;
&lt;p&gt;The decidedly less user friendly, but much more reliable option is git.  On OSX,
the command line was the obvious choice.  On android, I went with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;maks&#x2F;MGit&quot;&gt;mgit&lt;&#x2F;a&gt;.
While its user interface takes some time getting used to, it does offer reliable
git support on a mobile phone - what more can I ask for? Since git is
decentralized, one question is always which system is the main copy.  Here, I
use my laptop as the copy to which I push my changes from mobile.  While using
this system, I found two details quite helpful: My home router is mapping MAC
addresses to fixed IPs, so I do not have to change the repository URL repeatedly
on my phone.  Also, nowadays, you can push into a checked out branch, after
adapting the repository configuration:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; git config receive.denyCurrentBranch updateInstead&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This way I can push and pull my notes from my phone to my laptop at will, when
inside my flat.&lt;&#x2F;p&gt;
&lt;!-- conclusion --&gt;
&lt;p&gt;I had this setup now running for about a month and am quite happy with the
results.  While there are some moving parts, each part individually is simple
enough to understand and tweak if necessary.  Currently, I started experimenting
with other tools built on top of my notes, e.g., a simple tag cloud created by a
python script or reading out tables for tracking habits. Since the content is a
collection of plain text files on disk, writing tools around them becomes quite
easy.&lt;&#x2F;p&gt;
&lt;p&gt;All in all, I can whole-heartedly recommend this setup: it is simple, robust,
and extremely flexible, not to mention there is no lock-in whatsoever.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>ipytest: running pytest in IPython notebooks</title>
                <pubDate>Sat, 31 Dec 2016 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/ipytest-running-pytest-in-ipython-notebooks.html/</link>
                <guid>https://cprohm.de/article/ipytest-running-pytest-in-ipython-notebooks.html/</guid>
                <description>&lt;p&gt;With &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;pytest.org&quot;&gt;pytest&lt;&#x2F;a&gt; becoming the de facto standard for writing tests in
python, I started to miss its functionality when prototyping code in
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jupyter.org&quot;&gt;jupyter&lt;&#x2F;a&gt; notebooks. Thanks to some free time between the years, I
decided to add support for running pytest tests inside notebooks to the most
recent release of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;ipytest&lt;&#x2F;a&gt; (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&#x2F;blob&#x2F;master&#x2F;example&#x2F;Magics.ipynb&quot;&gt;this example&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;As described in the &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;ipytest-a-ipython-test-runner.html&#x2F;&quot;&gt;original post&lt;&#x2F;a&gt;, my current workflow often
involves prototyping the implementation and its tests inside notebooks. They
allow for quick iteration cycles and interactive tests of ideas. Overall, I find
that notebooks offer a great developer experience, in particular for small
components.&lt;&#x2F;p&gt;
&lt;p&gt;On the test side, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;pytest.org&quot;&gt;pytest&lt;&#x2F;a&gt; greatly increases productivity, since it
allows for writing clear and succinct test code that is often much cleaner than
corresponding &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;unittest.html&quot;&gt;unittest&lt;&#x2F;a&gt; code. In my tests, I now routinely rely on
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;docs.pytest.org&#x2F;en&#x2F;latest&#x2F;fixture.html&quot;&gt;fixtures&lt;&#x2F;a&gt; for modularized tests, on &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;docs.pytest.org&#x2F;en&#x2F;latest&#x2F;skipping.html#xfail&quot;&gt;xfails&lt;&#x2F;a&gt; for
testing not yet implemented features, and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;docs.pytest.org&#x2F;en&#x2F;latest&#x2F;parametrize.html#parametrizemark&quot;&gt;parametrize&lt;&#x2F;a&gt; for
testing different variants of a single test.&lt;&#x2F;p&gt;
&lt;p&gt;With its recent release, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;ipytest&lt;&#x2F;a&gt; supports the combination of both
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jupyter.org&quot;&gt;jupyter notebooks&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;pytest.org&quot;&gt;pytest&lt;&#x2F;a&gt;. If you&#x27;d like to give ipytest
a spin, follow theses steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Install ipytest and pytest via pip (&lt;code&gt;pip install ipytest pytest&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Set &lt;code&gt;__file__&lt;&#x2F;code&gt; in your notebook to the notebook name&lt;&#x2F;li&gt;
&lt;li&gt;Import the ipytest magics (&lt;code&gt;import ipytest.magics&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Add &lt;code&gt;%%run_pytest&lt;&#x2F;code&gt; on top of any cell containing tests (
&lt;code&gt;%%run_pytest[clean]&lt;&#x2F;code&gt; to delete any previously defined tests).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A full example can be found below. If you find ipytest useful or have ideas for
improvements, I would love some feedback (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&#x2F;issues&quot;&gt;issue tracker&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The following, somewhat silly, example (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&#x2F;blob&#x2F;master&#x2F;example&#x2F;Magics.ipynb&quot;&gt;full notebook&lt;&#x2F;a&gt;)
demonstrates how to use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;ipytest&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# In[1]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# set the file name (required)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;__file__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;#39;Magics.ipynb&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# add ipython magics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; ipytest.magics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pytest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# In[2]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;%%&lt;&#x2F;span&gt;&lt;span&gt;run_pytest[clean]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;qq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_sorted&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; sorted&lt;&#x2F;span&gt;&lt;span&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# In[3]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;%%&lt;&#x2F;span&gt;&lt;span&gt;run_pytest[clean]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;qq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# fixtures work, too :)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;@pytest.fixture&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; dict_list&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;a&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;c&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;b&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_sorted__key_example_1&lt;&#x2F;span&gt;&lt;span&gt;(dict_list):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; sorted&lt;&#x2F;span&gt;&lt;span&gt;(dict_list,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=lambda&lt;&#x2F;span&gt;&lt;span&gt; d: d[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;a&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;a&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;b&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;c&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_sorted__key_example_2&lt;&#x2F;span&gt;&lt;span&gt;(dict_list):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; sorted&lt;&#x2F;span&gt;&lt;span&gt;(dict_list,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=lambda&lt;&#x2F;span&gt;&lt;span&gt; d: d[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;b&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;c&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;b&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;a&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# In[4]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;%%&lt;&#x2F;span&gt;&lt;span&gt;run_pytest[clean]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;qq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# as does parametrize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;@pytest.mark.parametrize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;input,expected&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;]),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;zasdqw&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; list&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;#39;adqswz&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_examples&lt;&#x2F;span&gt;&lt;span&gt;(input, expected):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    actual&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; sorted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; actual&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; expected&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
            </item>
            
        
            
            <item>
                <title>framequery - SQL on dataframes</title>
                <pubDate>Wed, 21 Sep 2016 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/framequery-sql-on-dataframes.html/</link>
                <guid>https://cprohm.de/article/framequery-sql-on-dataframes.html/</guid>
                <description>&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;pandas.pydata.org&#x2F;&quot;&gt;Pandas&lt;&#x2F;a&gt; is a superb tool for data handling and the de facto standard
for data science tasks in Python. Great as it is already, I always was a bit
surprised by its lack of an SQL interface. In Spark, for example, you can easily
reuse existing SQL statements on top of dataframes without having to resort to a
database.&lt;&#x2F;p&gt;
&lt;p&gt;A couple of days ago, I sat down and started to implement an SQL interpreter for
Pandas, called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;framequery&quot;&gt;framequery&lt;&#x2F;a&gt;. It relies heavily on the many
SQL-like operations implemented by Pandas already, but adds a SQL parser and
interpreter on top. While this package is similar in spirit to
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.yhat.com&#x2F;posts&#x2F;pandasql-sql-for-pandas-dataframes.html&quot;&gt;pandasql&lt;&#x2F;a&gt; by yhat, its implementation is quite different. With
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;framequery&quot;&gt;framequery&lt;&#x2F;a&gt;, data is never transferred between Pandas and a
database, but always maintained as a dataframe. Most directly, this choice
avoids conversions. In a more indirect way, it also offers the possibility of
using framequery with alternative implementations of the dataframe API, such as
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;dask.pydata.org&#x2F;en&#x2F;latest&#x2F;&quot;&gt;dask&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To test the current state, install the package via &lt;code&gt;pip install framequery&lt;&#x2F;code&gt; and
use the &lt;code&gt;select&lt;&#x2F;code&gt; function as in&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pandas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; framequery&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; fq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sales&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd.read_csv(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;sales.csv&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;products&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd.read_csv(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;products.csv&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;yearly_sales&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; fq.select(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    SELECT year, sum(sales) as sales&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    FROM sales&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    JOIN products&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    ON sales.product_id = products.id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    GROUP BY year&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Currently, the implementation has a number of shortcomings and quite some
features are still missing, but the core functionality is already usable. If you
find this package useful, I would love your feedback. Similarly, contributions
are also very welcome.&lt;&#x2F;p&gt;
&lt;p&gt;For details, please check the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;framequery&quot;&gt;GitHub page&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>Sharing data and control</title>
                <pubDate>Sun, 03 Apr 2016 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/sharing-data-and-control.html/</link>
                <guid>https://cprohm.de/article/sharing-data-and-control.html/</guid>
                <description>&lt;p&gt;The more time I spent building products that use machine learning at their core
the more it becomes clear to me that the ideal of a single data science language
and framework will never be fully realized. There will always be legacy code
that was written before the framework du jour arrived. Even without legacy code,
the reality looks already rather polyglot. Consider Spark. When using their
Python bindings one will almost surely end up with a mix of Scala and Python.&lt;&#x2F;p&gt;
&lt;p&gt;To support these polyglot architectures more and more effort is being spent to
ensure that the underlying algorithms are the same regardless of the programming
language or programming framework chosen. A good example of such an algorithm is
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dmlc&#x2F;xgboost&quot;&gt;xgboost&lt;&#x2F;a&gt;. The core algorithm is implemented in C++, but it also
supports current data processing frameworks, like Spark or Flink, and data
science languages, such as Python or R. As one central feature of its design,
xgboost uses its own framework for parallelization: even if you use Spark, the
parallelization will be fully handled by xgboost once the training starts.
Another example of this design is &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;yahoohadoop.tumblr.com&#x2F;post&#x2F;139916563586&#x2F;caffeonspark-open-sourced-for-distributed-deep&quot;&gt;CaffeOnSpark&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;However, I am wondering if this really the last step in the design of these
libraries. At its heart there is no fundamental reason why only data and not
control is flowing between parallelization framework and machine learning
library. For me, flow of control in this discussion means that both sides are
taking turns with executing code and notify each other when they are finished.
Think of JavaScript&#x27;s asynchronous HTTP API. Whenever the user code requests a
HTTP page, the browser takes over and performs the request. Once the request is
complete the browser hands both the result and the control back to the
JavaScript side for further actions.&lt;&#x2F;p&gt;
&lt;p&gt;If similarly control flow would be possible between machine learning library and
parallelization framework, the algorithm could use the native parallelization
mechanisms supplied by the framework. Think of an algorithm that is implemented
in terms of primitives such as allreduce and broadcast - as is
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dmlc&#x2F;xgboost&quot;&gt;xgboost&lt;&#x2F;a&gt;. Whenever the algorithm requests an allreduce, the
parallelization framework takes over, but hands back control once the reduction
has been performed. This way each part of the system could handle what it does
best: the algorithm library the actual algorithm, the parallelization framework
the parallelization.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>ipytest - a IPython test runner</title>
                <pubDate>Sun, 07 Feb 2016 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/ipytest-a-ipython-test-runner.html/</link>
                <guid>https://cprohm.de/article/ipytest-a-ipython-test-runner.html/</guid>
                <description>&lt;p&gt;From time to time, I find myself wanting to run unit-tests in IPython notebooks.
After writing the same code over and over again, I decided to publish it as a
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;pip-installable package&lt;&#x2F;a&gt;. This post aims to be a quick introduction
how I came to create this package and how it can be used.&lt;&#x2F;p&gt;
&lt;p&gt;Nowadays, the first thing I do when starting a new project is firing up an
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ipython.org&#x2F;notebook.html&quot;&gt;IPython notebook&lt;&#x2F;a&gt; to prototype an initial implementation. Since the
notebook interface offers instant feedback, it allows for rapid experimentation.
When dealing with large-ish datasets this feature becomes even more powerful.
Parsing and transforming data in python can take some time. Using the notebook
interface, one can perform this initial work once and then rapidly experiment
with code using this data.&lt;&#x2F;p&gt;
&lt;p&gt;However, for all the advantages of IPython, testing code placed in notebooks can
be hard. For this reason, I try move code into external python modules as soon
as possible to make it easy to import and test. Having said this, sometimes,
there is this twilight zone, where code  it not yet quite stable, but still
complex enough to warrant tests. In particular with pure algorithms test-driven
development can save a lot of time in the long run.&lt;&#x2F;p&gt;
&lt;p&gt;For this reason, I wrote the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;ipytest&lt;&#x2F;a&gt;, which allows to run tests in
IPython notebooks. As a silly example, consider the Fibonacci sequence. With
&lt;code&gt;ipytest&lt;&#x2F;code&gt;, one could have written the implementation and its tests as&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# In[1]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; fibonacci&lt;&#x2F;span&gt;&lt;span&gt;(i):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;Compute the fibonacci sequence.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    &amp;gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;[fibonacci(n) for n in range(7)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    [1, 1, 2, 3, 5, 8, 13]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; or&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; fibonacci(i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; fibonacci(i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# In[2]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; ipytest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ipytest.clean_tests(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;test_fibonacci*&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_fibonacci_example&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;unittest&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;TestCase&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_example&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.assertEqual(fibonacci(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_fibonacci_0&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; fibonacci(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_fibonacci_1&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; fibonacci(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_fibonacci_2&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; fibonacci(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_fibonacci_3&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; fibonacci(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_fibonacci_4&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; fibonacci(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; test_fibonacci_5&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; fibonacci(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ipytest.run_tests(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;doctest&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here, both the function computing the Fibonacci sequence and the tests are
written in the same notebook. After executing it, the notebook looks like
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&#x2F;blob&#x2F;master&#x2F;example&#x2F;Example.ipynb&quot;&gt;this&lt;&#x2F;a&gt;. If you want to give it a try, just install it with
&lt;code&gt;pip install ipytest&lt;&#x2F;code&gt;. A detailed reference is can be found on the project&#x27;s
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;ipytest&quot;&gt;github page&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>Debugging with q</title>
                <pubDate>Mon, 18 Jan 2016 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/debugging-with-q.html/</link>
                <guid>https://cprohm.de/article/debugging-with-q.html/</guid>
                <description>&lt;p&gt;Currently a lot of my time is spent on writing services controlling models or
generating reports. In these systems, the control flow moves from the user
facing HTTP server to a task queue (think of &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;celery.readthedocs.org&quot;&gt;celery&lt;&#x2F;a&gt;) that handles the
actual task. Depending on the setup the log output will be scattered over
multiple files and has to be painstakingly pieced together - one reason, I found
that debugging these kinds of applications becomes tiring quite fast.&lt;&#x2F;p&gt;
&lt;p&gt;From &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=OL3De8BAhME#t=25m14s&quot;&gt;his talk&lt;&#x2F;a&gt;, I gather Ka-Ping Yee had a similar problem when he
created &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pypi.python.org&#x2F;pypi&#x2F;q&quot;&gt;q&lt;&#x2F;a&gt;. This small python package is now my first import for a quick and
dirty debugging session. To use q, import it and call it like function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; q&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; qq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # qq is easier to search for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;qq(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;foo&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;bar&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When you use q, you may wonder where the output went? The beauty of q is that it
writes its output to the file &lt;code&gt;$TMPDIR&#x2F;q&lt;&#x2F;code&gt;. Thereby the debugging output is
collected in a single file and is not mixed with other output.&lt;&#x2F;p&gt;
&lt;p&gt;q can also easily be embedded into expressions, removing the need to rewrite the
code when debugging. Depending on the chosen operator q prints the full
expression or the next expression only:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;foo(qq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # prints 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;foo(qq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # prints 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Another feature of q is its ability to  trace function calls. Used as a
decorator, it prints out all arguments and the return value of function. With
nested function calls it is particular helpful because it indents the output
nicely. Unfortunately, the way q is implemented the renamed import breaks the
&lt;code&gt;@q&lt;&#x2F;code&gt; decorator. However, using the trace function explicitly works just fine:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@qq.trace&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;def say_hello(name):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    print(&amp;quot;hello {}&amp;quot;.format(name))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To sum up, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pypi.python.org&#x2F;pypi&#x2F;q&quot;&gt;q&lt;&#x2F;a&gt; is an incredibly useful package when debugging and I highly
recommend to check it out.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>Spring cleaning</title>
                <pubDate>Sun, 03 Jan 2016 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/spring-cleaning.html/</link>
                <guid>https://cprohm.de/article/spring-cleaning.html/</guid>
                <description>&lt;p&gt;Motivated by the unusually warm weather outside and finding myself with some
free time at my hand over the holidays, I decided to push up the spring cleaning
of this page.&lt;&#x2F;p&gt;
&lt;p&gt;Now half a year ago, I left academia and started to work as a Data Scientist at
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blue-yonder.com&quot;&gt;Blue Yonder&lt;&#x2F;a&gt;. With my attention directed towards this
interesting and challenging new role, I unfortunately neglected updating this
page.&lt;&#x2F;p&gt;
&lt;p&gt;So with renewed enthusiasm, I changed the content of these pages to reflect my
current situation and vowed to myself to adhere to a more regular writing
schedule.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>void for traits</title>
                <pubDate>Mon, 06 Apr 2015 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/void-for-traits.html/</link>
                <guid>https://cprohm.de/article/void-for-traits.html/</guid>
                <description>&lt;p&gt;One of the great things about high level languages, be it Java or Python, is
reflection and the ability to get information about objects and their type at
runtime. When you start to think about similar concepts in C++, you&#x27;ll quickly
find out that it&#x27;s tricky: I guess for performance reasons, the options for
reflection are severely limited in C++. One choice is template based reflection
using SFINAE techniques &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SFINAE&quot;&gt;(substitution failure is not an error)&lt;&#x2F;a&gt;. The
concept can be summarized as: when looking up names the C++ compiler will ignore
all templates which would result in an invalid type.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>End-to-end training of deep autoencoders in IPython</title>
                <pubDate>Mon, 02 Feb 2015 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/end-to-end-training-of-deep-autoencoders-in-ipython.html/</link>
                <guid>https://cprohm.de/article/end-to-end-training-of-deep-autoencoders-in-ipython.html/</guid>
                <description>&lt;p&gt;While working on my deep learning project, I hacked together a couple of simple
support methods for IPython that, at least for me, greatly increased its
usefulness for iterative optimization. In this post I will concentrate on
IPython, while I defer the discussion about the model and its design to a future
post. At the end of this post you&#x27;ll find a teaser&lt;sup&gt;&lt;a
href=&quot;#ac-2015-01-1&quot;&gt;[1]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and I also uploaded the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cprohm.de&#x2F;static&#x2F;20150202_autoencoder&#x2F;&quot;&gt;HTML
file&lt;&#x2F;a&gt; and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;MachineLearning&quot;&gt;notebook&lt;&#x2F;a&gt; of the current state.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>argmap available on PyPI</title>
                <pubDate>Sun, 11 Jan 2015 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/argmap-available-on-pypi.html/</link>
                <guid>https://cprohm.de/article/argmap-available-on-pypi.html/</guid>
                <description>&lt;p&gt;I just published my first package, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chmp&#x2F;argmap.git&quot;&gt;argmap&lt;&#x2F;a&gt;, on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pypi.python.org&#x2F;pypi&quot;&gt;python package
index&lt;&#x2F;a&gt;. Exciting - and much less complicated than I initially thought.
Using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pip.pypa.io&#x2F;en&#x2F;latest&#x2F;&quot;&gt;pip&lt;&#x2F;a&gt;, you can now install argmap by running&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;pip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; install argmap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the process I also improved the documentation and made it available online
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chmp.github.io&#x2F;argmap&#x2F;docs&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>Argmap: declarative argument parsing with Python</title>
                <pubDate>Mon, 08 Dec 2014 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/argmap-declarative-argument-parsing-with-python.html/</link>
                <guid>https://cprohm.de/article/argmap-declarative-argument-parsing-with-python.html/</guid>
                <description>&lt;p&gt;Python is a great tool for scientific computing and I use it on a regular basis
for a wide array of tasks, ranging from simulation setup, data analysis, to the
simulations themselves in some cases. For many of these tasks support for
command line arguments greatly increases the productivity:  for example, a
single script can analyze different simulations. The Python standard library
comes with an argument parser (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;2&#x2F;library&#x2F;argparse.html&quot;&gt;argparse&lt;&#x2F;a&gt;) out of the box. However, it
results in a lot if boilerplate code which is especially a problem when checking
some idea with only limited lifetime.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>tomato timer &amp; the pomodoro technique</title>
                <pubDate>Sat, 26 Apr 2014 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/tomato-timer-the-pomodoro-technique.html/</link>
                <guid>https://cprohm.de/article/tomato-timer-the-pomodoro-technique.html/</guid>
                <description>&lt;p&gt;For a while now, I&#x27;v been using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pomodorotechnique.com&#x2F;&quot;&gt;pomodoro technique&lt;&#x2F;a&gt;
(&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pomodoro_Technique&quot;&gt;Wikipedia&lt;&#x2F;a&gt;) to be more efficient when working. I found it to be
quite the efficient procrastination buster. Developed by Francesco Cirillo, the
pomodoro technique is based on the idea of structuring your work into fixed
intervals of roughly 25 minutes. While working avoid any distraction and keep
focussed on the current task. After each work interval take a short break (~5
minutes) and then continue with the next work interval. Every four work
intervals take a longer breaks (15 - 30 minutes).&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>jsonbind - guice configured with json</title>
                <pubDate>Sun, 12 Jan 2014 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/jsonbind-guice-configured-with-json.html/</link>
                <guid>https://cprohm.de/article/jsonbind-guice-configured-with-json.html/</guid>
                <description>&lt;p&gt;A big part of my PhD project are simulations of fluid flow under various
conditions. Often I am actually not sure what the correct setup is until the
paper is written. You try one hypothesis, then another - only to modify it yet
again. In this situation it comes in handy if your program allows you to swap
certain parts of the program, for example the geometry, without influencing the
other. If you can do this at runtime without recompiling the program - even
better.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Yet another short update</title>
                <pubDate>Mon, 30 Dec 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/yet-another-short-update.html/</link>
                <guid>https://cprohm.de/article/yet-another-short-update.html/</guid>
                <description>&lt;p&gt;Finally I finished up the RBM implementation and squashed the remaining bugs.
Running the RBM gives reasonable samples and the learned filters seem ok. So
everything is working just fine, albeit a bit slow due to the use of pure java
linear algebra. Luckily most of the algorithms are implemented using the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Basic_Linear_Algebra_Subprograms&quot;&gt;BLAS&lt;&#x2F;a&gt; interface so it should be rather simple to swap out those parts for
a faster implementation.&lt;&#x2F;p&gt;
&lt;p&gt;I really would like to have the option of switching the underlying
implementation when starting the program, which &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;sourceforge.net&#x2F;projects&#x2F;ujmp&#x2F;&quot;&gt;UJMP&lt;&#x2F;a&gt; seems to support.
However it does not support the full BLAS API, so I cannot multiply with the
transpose or do a rank-one update. All other libraries I found seem to focus on
running with a fixed BLAS implementation mostly on the CPU. However long-term I
will try to switch running in OpenCL to get the most performance even when
running in Java. Well, I would really hate to roll my own matrix library,
especially considering there are quite so many out there, but this seems to be
the best option at the moment.&lt;&#x2F;p&gt;
&lt;p&gt;On a more happy note, I got &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;google-guice&#x2F;&quot;&gt;Guice&lt;&#x2F;a&gt; working just the way I wanted it to.
I rolled my own little JSON configuration library which allows me to swap every
little piece of my program using configuration files. After cleaning up a bit
more, I will upload it to github and write a short bit about it.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>Short update</title>
                <pubDate>Sat, 14 Dec 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/short-update.html/</link>
                <guid>https://cprohm.de/article/short-update.html/</guid>
                <description>&lt;p&gt;Ok, as it turns out using javascript was not one of by best ideas. I learned the
hard way that I have to decide between speed and stability with the two browsers
I tested. With Firefox everything was stable, but quite slow. Using Chrome on
the other hand sped things up considerably, but it never survived running for
more than a couple of hours - without warning the tab would just crash. In the
end I figured it is time to use a language which is more stable - this time I
opted for Java - which is a nice fit due to its large ecosystem. Another
advantage compared to Javascript is the access to the file system, so I can
easily use the standard datasets such as MINST - to compare my implementation
against the literature.&lt;&#x2F;p&gt;
&lt;p&gt;So the course is plotted, but I&#x27;m currently somewhat short on time: in between
the end of the year stress - got papers to finish - I seem to be unable to find
the proper time to finish this . Well the holidays are up in a week and then
I&#x27;ll have time to work on this - further updates are incoming.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>Restricted Boltzmann Machines - Theory II</title>
                <pubDate>Fri, 25 Oct 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/restricted-boltzmann-machines-theory-ii.html/</link>
                <guid>https://cprohm.de/article/restricted-boltzmann-machines-theory-ii.html/</guid>
                <description>&lt;p&gt;In the &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;restricted-boltzmann-machines-theory-i.html&#x2F;&quot;&gt;last post&lt;&#x2F;a&gt; we have parametrized the model and are now left
with the task of learning it. Learning in the context of machine-learning always
implies maximizing a predefined objective. Generative models aim to maximize the
probability they assign to the input data. We will present the model a number
images where the pixels are stored in the vectors v&lt;sup&gt;(i)&lt;&#x2F;sup&gt;. We search for
the parameters of the model (here: visible biases b, hidden biases c and weight
matrix W) such that the probability the model assigns to the input images is
maximized. This probability, also called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Likelihood_function&quot;&gt;likelihood&lt;&#x2F;a&gt;, is given as
the product&lt;&#x2F;p&gt;
&lt;p&gt;$$ P(\{v\}) = \prod_i P(v^{(i)}). $$&lt;&#x2F;p&gt;
&lt;p&gt;To maximize this probability we will use gradient ascent. However when we try to
differentiate this product we end up with a sum of products, which we will not
be able to compute. Luckily there is an easy way around this problem: by taking
the logarithm of this product we turn the likelihood into the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Likelihood_function#Log-likelihood&quot;&gt;log-likelihood&lt;&#x2F;a&gt; and the products into the sum&lt;&#x2F;p&gt;
&lt;p&gt;$$ \log P(\{v\}) = \sum_i \log P(v^{(i)}). $$&lt;&#x2F;p&gt;
&lt;p&gt;As the logarithm is a monotonically increasing function, maximizing the
logarithm also maximizes its argument.&lt;&#x2F;p&gt;
&lt;p&gt;To simplify the next steps let us denote the log-likelihood by J. We can
maximize it by taking small steps along its gradients -  a procedure called
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gradient_descent&quot;&gt;gradient ascent&lt;&#x2F;a&gt;. So we can increase J by updating the weights
by&lt;&#x2F;p&gt;
&lt;p&gt;$$ W_{ij} \rightarrow W_{ij} + \epsilon \frac{\partial J}{\partial W_{ij}}. $$&lt;&#x2F;p&gt;
&lt;p&gt;Gradient ascent can be easily understood if we consider how J changes if we
perturb the weights by a small step ε ΔW&lt;sub&gt;ij&lt;&#x2F;sub&gt;. If ε is small enough we
can Taylor-expand and find that J changes as&lt;&#x2F;p&gt;
&lt;p&gt;$$
J(W + \epsilon \Delta W_{ij}) \approx
J(W) + \epsilon \sum_{ij} \frac{\partial J}{\partial W_{ij}} \Delta W_{ij}
$$&lt;&#x2F;p&gt;
&lt;p&gt;By choosing ε ΔW&lt;sub&gt;ij&lt;&#x2F;sub&gt; equal to ∂J &#x2F; ∂W this increase is always positive.
However this strictly only holds for infinitesimal small ε.&lt;&#x2F;p&gt;
&lt;p&gt;Note that you can treat the biases by including units that are always one, so
there is no need to include them in the discussion explicitly.&lt;&#x2F;p&gt;
&lt;p&gt;Inserting the &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;restricted-boltzmann-machines-theory-i.html&#x2F;&quot;&gt;joint probability&lt;&#x2F;a&gt; of the RBM into the log-likelihood
we find its derivative as the difference of the derivative of the energy
function averaged over the data and averaged over the model expectations&lt;&#x2F;p&gt;
&lt;p&gt;$$
\frac{\partial J}{\partial W_{ij}} \propto
-\langle \frac{\partial E}{\partial W_{ij}} \rangle_\mathrm{data}
+\langle \frac{\partial E}{\partial W_{ij}} \rangle_\mathrm{model}.
$$&lt;&#x2F;p&gt;
&lt;p&gt;We can understand this as follows: By following the gradient, we decrease the
energy of the data samples and increase the energy of the model expectations. As
lower energy states are more probable, this increases the probability of the
data and decreases the probability of what the model would come up with on its
own.&lt;&#x2F;p&gt;
&lt;p&gt;We can derive the gradient of the log-likelihood J by the following steps:&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{aligned}
\frac{\partial J}{\partial W_{ij}}
&amp;amp;= \sum_k \frac{\partial}{\partial W_{ij}} \log P(v^{(k)}) \\
&amp;amp;= \sum_k \frac{\partial}{\partial W_{ij}}
\left[
\log \sum_{h} \exp(-E(v^{(k)},h)) - \log Z
\right]
\end{aligned}
$$&lt;&#x2F;p&gt;
&lt;p&gt;The first term will give the expectation over the data, while the second term
will give the expectation over the model.&lt;&#x2F;p&gt;
&lt;p&gt;Concentrating on the first term:&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{aligned}
&amp;amp;\sum_k \frac{\partial}{\partial W_{ij}} \log \sum_{ { h } } \exp(-E(v^{(k)},h)) \\
&amp;amp;= \sum_k \frac{1}{\sum_{ { h } } \exp(-E(v,h))} \sum_{ { h } } \exp(-E(v^{(k)},h))
(-\frac{\partial}{\partial W_{ij}} E(v^{(k)}, h)) \\
&amp;amp;= -N_v \frac{1}{N_v} \sum_k \sum_{ { h } } P(h | v^{(k)}) \frac{\partial}{\partial W_{ij}} E(v^{(k)}, h)).
\end{aligned}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Here, N&lt;sub&gt;v&lt;&#x2F;sub&gt; is the number of visible samples. Furthermore the sum over
all data vectors can be considered the sum over all possible visible vectors
multiplied by the probability of that vector being part of the input data. If we
define the probability density of the input data as&lt;&#x2F;p&gt;
&lt;p&gt;$$
P_\mathrm{data}(v, h) = \frac{1}{N_v} \sum_k \delta(v - v^{(k)}) P(h | v^{(k)}),
$$&lt;&#x2F;p&gt;
&lt;p&gt;we can rewrite the first part of the derivative as&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{aligned}
&amp;amp;\sum_k \frac{\partial}{\partial W_{ij}} \log \sum_{ { h } } \exp(-E(v^{(k)},h)) \\
&amp;amp;= -N_v \sum_{ {v, h } } P_\mathrm{data}(v, h) \frac{\partial}{\partial W_{ij}} E(v^{(k)}, h)) \\
&amp;amp;= -N_v \langle \frac{\partial E}{\partial W_{ij}} \rangle_\mathrm{data}.
\end{aligned}
$$&lt;&#x2F;p&gt;
&lt;p&gt;The derivative of the partition functions results in&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{aligned}
&amp;amp;-\sum_k \frac{\partial}{\partial W_{ij}} \log Z \\
&amp;amp;= -N_v \frac{\partial}{\partial W_{ij}} \log \sum_{ { v, h } } exp[ -E(v, h) ] \\
&amp;amp;= N_v \log \frac{1}{\sum_{ { v, h } } exp[ -E(v, h) ]}
\sum_{ { v, h } } exp[ -E(v, h) ] \frac{\partial}{\partial W_{ij}} E(v, h) \\
&amp;amp;= N_v  \sum_{ { v, h } } P_\mathrm{model}(v, h) \frac{\partial}{\partial W_{ij}} E(v, h) \\
&amp;amp;= N_v \langle \frac{\partial E}{\partial W_{ij}} \rangle_\mathrm{model}.
\end{aligned}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Combining both terms we find:&lt;&#x2F;p&gt;
&lt;p&gt;$$
\sum_k \frac{\partial}{\partial W_{ij}} \log P(v^{(k)})
= -N_v \langle \frac{\partial E}{\partial W_{ij}} \rangle_\mathrm{data} +
N_v \langle \frac{\partial E}{\partial W_{ij}} \rangle_\mathrm{model}.
$$&lt;&#x2F;p&gt;
&lt;p&gt;All that remains is plugging in the gradient with respect to the weights of the
energy defined in the &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;restricted-boltzmann-machines-theory-i.html&#x2F;&quot;&gt;previous post&lt;&#x2F;a&gt; and we end up with&lt;&#x2F;p&gt;
&lt;p&gt;$$
\frac{\partial J}{\partial W_{ij}} \propto
-\langle v h^T \rangle_\mathrm{data}
+\langle v h^T \rangle_\mathrm{model}.
$$&lt;&#x2F;p&gt;
&lt;p&gt;Still we cannot calculate this gradient, as it involves expectations over the
model, which we cannot perform due to the infeasibility of the partition
function. Here we will try to approximate this expectation value by a finite
number of samples and often resort to using merely a single sample. To generate
the samples we will perform &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gibbs_sampling&quot;&gt;Gibbs sampling&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;restricted-boltzmann-machines-theory-i.html&#x2F;&quot;&gt;Remember&lt;&#x2F;a&gt; that we can evaluate the conditional probability of the
hidden vector given the visible vector and the converse. Gibbs sampling exploits
this fact by alternating between sampling the hidden and the visible vector. If
we repeat this process until infinity we will generate unbiased samples from the
model. In practice, as popularized by Hinton, a good approximation is start at
the data vector and perform a small number of Gibbs sampling steps. This
learning rule is called contrastive divergence.&lt;&#x2F;p&gt;
&lt;p&gt;So to summarize the learning algorithm for the Restricted Boltzmann machine can
be written (in python):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; visible&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; input_data:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	hidden&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sample_hidden_given_visible(visible)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	gradient&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; hidden&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; outer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(k):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		visible&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sample_visible_given_hidden(hidden)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		hidden&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sample_hidden_given_visible(visible)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	gradient&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; hidden&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; outer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	weights&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; gradient&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An overview of these concepts and a number of practical considerations can be
found in &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;link.springer.com&#x2F;chapter&#x2F;10.1007%2F978-3-642-35289-8_32&quot;&gt;Geoffrey Hinton&#x27;s guide&lt;&#x2F;a&gt;, which you can find as a pdf on
his &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.cs.toronto.edu&#x2F;~hinton&#x2F;&quot;&gt;home page&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>Restricted Boltzmann Machines - Theory I</title>
                <pubDate>Mon, 30 Sep 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/restricted-boltzmann-machines-theory-i.html/</link>
                <guid>https://cprohm.de/article/restricted-boltzmann-machines-theory-i.html/</guid>
                <description>&lt;p&gt;Before actually building a Restricted Boltzmann machine (RBM), let us first
discuss the math behind it.&lt;&#x2F;p&gt;
&lt;p&gt;First, a quick recap of &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;machine-learning-with-generative-models.html&#x2F;&quot;&gt;our goal&lt;&#x2F;a&gt;: We try to map the pixels of
an image (input data) to the content of this image (label). Specifically, we try
to recognize images of numbers. We tackle this problem by using a two step
approach of first building a generative model of the input data and then use the
output of this model for classification.&lt;&#x2F;p&gt;
&lt;p&gt;Like most machine learning algorithms RBMs are closely tied to basic concepts to
probability theory. Specifically RBMs are used to model an a-priori unknown
probability distribution of your input data. If we denote a sample of your input
data by the vector v, RBMS try to learn the probability P(v) of that vector.&lt;&#x2F;p&gt;
&lt;p&gt;Let us consider a visible vectors with two binary elements. For this example
there are four possible values v can take, (0,0), (1,0), (0,1), (1,1), and the
probability distribution P(v) consists four entries. Generally if the visible
vector has d elements the probability distribution has 2&lt;sup&gt;d&lt;&#x2F;sup&gt; entries.
Even for quite small inputs, as 8x8 pixel image, this is an astronomically large
number with 20 digits.&lt;&#x2F;p&gt;
&lt;p&gt;As we cannot reason directly about P(v) with its enormous number of entries, we
have to find a suitable parametrization, where the number of parameters is much
smaller. Like many probabilistic models, RBMs are based on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gibbs_measure&quot;&gt;Gibbs
distribution&lt;&#x2F;a&gt;, which assigns each visible vector v a free
energy F(v). The free energy then determines the probability by&lt;&#x2F;p&gt;
&lt;p&gt;$$P(v) = Z^{-1} \exp[-F(v)]$$&lt;&#x2F;p&gt;
&lt;p&gt;Here Z is the so called partition function, which ensure that the probability
sums to one if we sum over all possible visible vectors. So for our example of a
two element binary vector the partition sum is equal to&lt;&#x2F;p&gt;
&lt;p&gt;$$Z = \exp[-F((0,0))] + \exp[-F((1,0))] + \exp[-F((0,1))] + \exp[-F((1,1))]$$&lt;&#x2F;p&gt;
&lt;p&gt;An RBM adds additional unknowns, so called hidden units h, which are coupled to
the visible state. This coupling is again described by an energy function&lt;&#x2F;p&gt;
&lt;p&gt;$$E(v,h) = -v^T W h -v^T b - h^T c$$&lt;&#x2F;p&gt;
&lt;p&gt;Here, W is the weight matrix, b the bias of the visible units and c the bias of
the hidden units. The Gibbs distribution for E(v,h) determines the
joint-probability of a visible vector v and a hidden vector h.&lt;&#x2F;p&gt;
&lt;p&gt;So now that we have a probability P(v,h) assigned to every value of visible and
hidden vector, how do we get the distribution of visible vectors? We can compute
the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Marginal_distribution&quot;&gt;marginal distribution&lt;&#x2F;a&gt;, by summing over all possible
values of the hidden vectors:&lt;&#x2F;p&gt;
&lt;p&gt;$$P(v) = Z^{-1} \sum_{ \{ h \} } \exp [ -E(v, h) ]$$&lt;&#x2F;p&gt;
&lt;p&gt;As an example consider the case that h is a two dimensional binary vector, then
the set {h} covers the values {(0, 0), (0, 1), (1, 0), (1, 1)} and we sum up the
probabilities by setting the hidden vector to each one of these in turn.&lt;&#x2F;p&gt;
&lt;p&gt;Note, that we never specified the value of the partition function Z. The reason
is that in general we are not able to, as it involves a sum over all possible
values of the visible and hidden vectors. However, as it turns out for many
applications there are good approximations available so we do not need to
determine Z.&lt;&#x2F;p&gt;
&lt;p&gt;One particularity of the restricted Boltzmann machine is the fact that the
conditional distributions can be determined explicitly. The conditional
probability P(v|h) is the probability to find the visible vector v if the hidden
vector is equal to h. The conditional distribution P(h|v) has an equivalent
meaning.&lt;&#x2F;p&gt;
&lt;p&gt;The reason we can determine these probability distribution is that they
factorize in their argument, i.e., we can be write P(v|h) as&lt;&#x2F;p&gt;
&lt;p&gt;$$P(v|h) = \prod_i P(v_i|h).$$&lt;&#x2F;p&gt;
&lt;p&gt;The probability that the i-th visible state is equal to one is given by&lt;&#x2F;p&gt;
&lt;p&gt;$$P(v_i = 1 | h) = \frac{1}{1 + \exp[ - \sum_j (W_{ij} h_j - b_j)]}$$&lt;&#x2F;p&gt;
&lt;p&gt;So all that remains now is to optimize the parameters, i.e., the matrix W and
the vectors b and c, to maximize the probability of the input data. How this is
done will be the topic of the next post.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>Machine Learning with Generative Models</title>
                <pubDate>Sun, 25 Aug 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/machine-learning-with-generative-models.html/</link>
                <guid>https://cprohm.de/article/machine-learning-with-generative-models.html/</guid>
                <description>&lt;p&gt;After a short hiatus - holidays and finishing up a paper - I am back writing and
decided to write about my current after-work project, namely generative models
for machine learning. I&#x27;ve been interested in machine learning for a quite some
time now. However always found myself in the predicament that finding or
generating high quality training data can be quite the challenge. This applies
in particular, if you try to learn agent behavior in a complex setting.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Recipes for jmpress animations</title>
                <pubDate>Sun, 16 Jun 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/recipes-for-jmpress-animations.html/</link>
                <guid>https://cprohm.de/article/recipes-for-jmpress-animations.html/</guid>
                <description>&lt;!-- intro --&gt;
&lt;p&gt;In the &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;animations-in-jmpress.html&#x2F;&quot;&gt;last post&lt;&#x2F;a&gt;, I discussed how to use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jmpressjs&#x2F;jmpress.js&quot;&gt;jmpress&#x27;s&lt;&#x2F;a&gt;
animations. And while animations are quite flexible, there is no denying, that
this flexibility makes things a bit harder for run-off-the-mill animations. For
most of the time, I rely on a set of limited css classes for my talks, which I
want to discuss in this post.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Wrapping C++ code using boost python</title>
                <pubDate>Sat, 18 May 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/wrapping-c-code-using-boost-python.html/</link>
                <guid>https://cprohm.de/article/wrapping-c-code-using-boost-python.html/</guid>
                <description>&lt;p&gt;The saying &quot;The right tool, for the right job.&quot; is one of my most beloved rule
of thumb. This especially holds true for programming languages, certain
languages are a natural for fit for certain tasks. The fact that the simulations
I am running take forever already gives me strong motive to squeeze out the last
bit of performance. Hence the choice of C++ as the programming language.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Animations in jmpress</title>
                <pubDate>Wed, 15 May 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/animations-in-jmpress.html/</link>
                <guid>https://cprohm.de/article/animations-in-jmpress.html/</guid>
                <description>&lt;p&gt;In the &lt;a href=&quot;https:&#x2F;&#x2F;cprohm.de&#x2F;article&#x2F;simple-html5-talks.html&#x2F;&quot;&gt;first part&lt;&#x2F;a&gt; of this tutorial, I
talked about how to use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jmpressjs&#x2F;jmpress.js&quot;&gt;jmpress&lt;&#x2F;a&gt; to create simple talks using html5.
In this part I want to show you how to include animations in a slide. Animations
in talks can be very useful to guide the audience through your talk, by
highlighting the current information. Unfortunately adding animations in
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jmpressjs&#x2F;jmpress.js&quot;&gt;jmpress&lt;&#x2F;a&gt; can be hard at times.&lt;&#x2F;p&gt;
&lt;p&gt;As a reference keep the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;jmpressjs.github.io&#x2F;docs&#x2F;animation.html&quot;&gt;official documentation&lt;&#x2F;a&gt; at hand.&lt;&#x2F;p&gt;
&lt;p&gt;Animations are implement by CSS classes in jmpress and usually have three steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The animation will occur, but has not yet&lt;&#x2F;li&gt;
&lt;li&gt;It is currently running&lt;&#x2F;li&gt;
&lt;li&gt;And finally, it has already run&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Each of these steps is implemented by adding a CSS class to the element being
animated. All animations have a name, which can be chosen arbitrarily, as long
as it is a valid CSS identifier.&lt;&#x2F;p&gt;
&lt;p&gt;In the following I will walk you trough the steps of how to implement a custom
fade animations, which is also implemented in the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;jmpressjs.github.io&#x2F;jmpress.js&#x2F;examples&#x2F;animation&#x2F;&quot;&gt;jmpress
example&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Any element can be animated by adding the data-jmpress attribute. To fade out a
part of text just wrap it in a span, as in&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;html&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Hello &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; data-jmpress&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;fade&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;world&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;While presenting, the following css classes will be added to the element&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;will-fade: from the start&lt;&#x2F;li&gt;
&lt;li&gt;do-fade: once, the animation is running&lt;&#x2F;li&gt;
&lt;li&gt;has-fade: after the animation has run&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So to implement a fade effect just define the correct css classes (you may need
to add the correct browser prefixes)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;css&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;.will-fade&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;    transition-property&lt;&#x2F;span&gt;&lt;span&gt;: opacity;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;    transition-duration&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0.5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;s&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;    opacity&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;.do-fade&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;    opacity&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The will-fade class informs the browser that any change of the opacity property
should be animated and that this change should take half a second. The do-fade
class makes sure that the opacity of the fading element is reduced to zero,
while the animation is running. Note, that while the documentation says that the
class is only set while the animation is running, it is not removed after the
animation.&lt;&#x2F;p&gt;
&lt;p&gt;If there are multiple animations on each slide, the animations are run in the
order they appear in the document. For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;html&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; data-jmpress&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;fade&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;first&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; data-jmpress&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;fade&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;second&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To customize this, additional properties can be added. I found, the most
important options are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;(name) after (selector): run the animation after the animation of the element
with the given selector has run&lt;&#x2F;li&gt;
&lt;li&gt;(name) after (time): run the animation after the given time&lt;&#x2F;li&gt;
&lt;li&gt;(name) after (time) (selector): run the animation with a given delay delay
after the animation of the element given by selector has run.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are two special selectors &lt;em&gt;prev&lt;&#x2F;em&gt; and &lt;em&gt;step&lt;&#x2F;em&gt;, which denote the previous
element and the slide beginning respectively. Per default always the previous
animated element is used.&lt;&#x2F;p&gt;
&lt;p&gt;For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;html&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; data-jmpress&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;fade after #first&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;Fade after&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;first&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; data-jmpress&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;fade after step&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;this element&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; data-jmpress&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;fade after 1s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;delayed&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can find a working html version of this example here. For more
information especially about the available options for animations look at the
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;jmpressjs.github.io&#x2F;docs&#x2F;animation.html&quot;&gt;documentation&lt;&#x2F;a&gt;. In the next part I will discuss how to setup
more complex animations using jmpress.&lt;&#x2F;p&gt;
</description>
            </item>
            
        
            
            <item>
                <title>Exporting D3 graphs</title>
                <pubDate>Mon, 08 Apr 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/exporting-d3-graphs.html/</link>
                <guid>https://cprohm.de/article/exporting-d3-graphs.html/</guid>
                <description>&lt;p&gt;While playing around with &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;d3js.org&#x2F;&quot;&gt;D3&lt;&#x2F;a&gt;, I was always disappointed, that the
resulting images are stuck in the browser afterwards. However, since you use
merely use D3 to generate an embedded &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scalable_Vector_Graphics&quot;&gt;SVG&lt;&#x2F;a&gt; image, it should not be
that hard to get it out, should it?&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Simple html5 talks</title>
                <pubDate>Mon, 25 Mar 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/simple-html5-talks.html/</link>
                <guid>https://cprohm.de/article/simple-html5-talks.html/</guid>
                <description>&lt;p&gt;In this short tutorial I want to show you how to create simple html5 talks using
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jmpressjs&#x2F;jmpress.js&quot;&gt;jmpress&lt;&#x2F;a&gt;. One particularity about jmpress is, that relies exclusively
on CSS to layout your slides and some working knowledege of CSS is highly
desirable.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>HTML5 Presentations</title>
                <pubDate>Fri, 15 Mar 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/html5-presentations.html/</link>
                <guid>https://cprohm.de/article/html5-presentations.html/</guid>
                <description>&lt;p&gt;After just getting back from the DPG spring meeting, I thought I&#x27;d give a
overview of how to create (scientific) presentations using HTML5. The talk I
gave was setup using &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;github.com&#x2F;jmpress&#x2F;jmpress.git&quot;&gt;jmpress&lt;&#x2F;a&gt;, and it
worked out quite beautifully (at least from my perspective).&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Multi-particle collision dynamics</title>
                <pubDate>Mon, 28 Jan 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/multi-particle-collision-dynamics.html/</link>
                <guid>https://cprohm.de/article/multi-particle-collision-dynamics.html/</guid>
                <description>&lt;p&gt;So after spending the last two weeks parallelizing my program, I rediscovered
the ingenuity that are mesoscopic simulation techniques. Instead of simulating
the actual system at hand, you construct a simplified system, which reproduces
only a minimal set of properties of the original system.&lt;&#x2F;p&gt;</description>
            </item>
            
        
            
            <item>
                <title>Welcome</title>
                <pubDate>Sat, 19 Jan 2013 00:00:00 +0000</pubDate>
                <link>https://cprohm.de/article/welcome.html/</link>
                <guid>https://cprohm.de/article/welcome.html/</guid>
                <description>&lt;p&gt;Welcome to my blog.
Here, I will discuss general programming topics, which I&#x27;m currently interested
in, and also projects, which I&#x27;m currently pursuing.
All of this will focus on three programming languages, python, javascript and
C++.
While &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.itp.tu-berlin.de&#x2F;stark&#x2F;ag_stark&#x2F;mitglieder&#x2F;christopher_prohm&quot;&gt;my phd work&lt;&#x2F;a&gt;,
is mainly done in python and C++, I&#x27;ve recently
taking a liking to javascript for my hobbyist projects.
But more on this in later posts.&lt;&#x2F;p&gt;</description>
            </item>
            
        
    </channel>
</rss>
