<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Deb's homepage</title><link>http://www.debsankha.net</link><description>Deb's blog/home page</description><atom:link href="http://www.debsankha.net/rss.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2023 &lt;a href="mailto:d@debsankha.net"&gt;Debsankha Manik&lt;/a&gt; 
&lt;a rel="license" href="https://creativecommons.org/licenses/by-nc-sa/4.0/"&gt;
&lt;img alt="Creative Commons License BY-NC-SA"
style="border-width:0; margin-bottom:12px; margin-left:5px"
src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png"&gt;&lt;/a&gt;</copyright><lastBuildDate>Fri, 20 Jan 2023 15:47:04 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Pandas oddity</title><link>http://www.debsankha.net/posts/pandas-oddity.html</link><dc:creator>Debsankha Manik</dc:creator><description>&lt;div&gt;&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;h2 id="Table-of-Contents"&gt;Table of Contents&lt;a class="anchor-link" href="http://www.debsankha.net/posts/pandas-oddity.html#Table-of-Contents"&gt;¶&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="lev2 toc-item"&gt;&lt;a href="http://www.debsankha.net/posts/pandas-oddity.html#What's-going-on-here?" data-toc-modified-id="What's-going-on-here?-0.1"&gt;&lt;span class="toc-item-num"&gt;0.1  &lt;/span&gt;What's going on here?&lt;/a&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;h3 id="What's-going-on-here?"&gt;What's going on here?&lt;a class="anchor-link" href="http://www.debsankha.net/posts/pandas-oddity.html#What's-going-on-here?"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [91]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [104]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;nan&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;NaT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [119]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="s1"&gt;'timestamp_utc'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-10-08 03:40:00+0000'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tz&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'UTC'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
                      &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-10-08 04:40:00+0000'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tz&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'UTC'&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt; 
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [120]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_wrapper"&gt;
&lt;div class="output"&gt;


&lt;div class="output_area"&gt;

    &lt;div class="prompt output_prompt"&gt;Out[120]:&lt;/div&gt;



&lt;div class="output_html rendered_html output_subarea output_execute_result"&gt;&lt;div&gt;
&lt;style scoped&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border="1" class="dataframe"&gt;
  &lt;thead&gt;
    &lt;tr style="text-align: right;"&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;timestamp_utc&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;6&lt;/th&gt;
      &lt;td&gt;2019-10-08 03:40:00+00:00&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;7&lt;/th&gt;
      &lt;td&gt;2019-10-08 04:40:00+00:00&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [124]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="s1"&gt;'hour'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'timestamp_utc'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1 H'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_wrapper"&gt;
&lt;div class="output"&gt;


&lt;div class="output_area"&gt;

    &lt;div class="prompt output_prompt"&gt;Out[124]:&lt;/div&gt;



&lt;div class="output_html rendered_html output_subarea output_execute_result"&gt;&lt;div&gt;
&lt;style scoped&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border="1" class="dataframe"&gt;
  &lt;thead&gt;
    &lt;tr style="text-align: right;"&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;timestamp_utc&lt;/th&gt;
      &lt;th&gt;hour&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;6&lt;/th&gt;
      &lt;td&gt;2019-10-08 03:40:00+00:00&lt;/td&gt;
      &lt;td&gt;2019-10-08 03:00:00+00:00&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;7&lt;/th&gt;
      &lt;td&gt;2019-10-08 04:40:00+00:00&lt;/td&gt;
      &lt;td&gt;2019-10-08 04:00:00+00:00&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [125]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="s1"&gt;'timestamp_utc'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-10-08 03:40:00+0000'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tz&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'UTC'&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt; 
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [126]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="s1"&gt;'hour'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'timestamp_utc'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1 H'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_wrapper"&gt;
&lt;div class="output"&gt;


&lt;div class="output_area"&gt;

    &lt;div class="prompt"&gt;&lt;/div&gt;


&lt;div class="output_subarea output_text output_error"&gt;
&lt;pre&gt;
&lt;span class="ansi-red-fg"&gt;---------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="ansi-red-fg"&gt;TypeError&lt;/span&gt;                                 Traceback (most recent call last)
&lt;span class="ansi-green-fg"&gt;&amp;lt;ipython-input-126-4f1ec8ec51e9&amp;gt;&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class="ansi-green-fg"&gt;----&amp;gt; 1&lt;/span&gt;&lt;span class="ansi-red-fg"&gt; &lt;/span&gt;df&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;loc&lt;span class="ansi-blue-fg"&gt;[&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; &lt;span class="ansi-blue-fg"&gt;'hour'&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;]&lt;/span&gt; &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; df&lt;span class="ansi-blue-fg"&gt;[&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;'timestamp_utc'&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;]&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;dt&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;floor&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;freq&lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;'1 H'&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;      2&lt;/span&gt; df

&lt;span class="ansi-green-fg"&gt;~/covid-19/venv/lib/python3.6/site-packages/pandas/core/indexing.py&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;__setitem__&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;(self, key, value)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    669&lt;/span&gt;             key &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; com&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;apply_if_callable&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;key&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; self&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;obj&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    670&lt;/span&gt;         indexer &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; self&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;_get_setitem_indexer&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;key&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-fg"&gt;--&amp;gt; 671&lt;/span&gt;&lt;span class="ansi-red-fg"&gt;         &lt;/span&gt;self&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;_setitem_with_indexer&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;indexer&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; value&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    672&lt;/span&gt; 
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    673&lt;/span&gt;     &lt;span class="ansi-green-fg"&gt;def&lt;/span&gt; _validate_key&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;self&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; key&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; axis&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt; int&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;

&lt;span class="ansi-green-fg"&gt;~/covid-19/venv/lib/python3.6/site-packages/pandas/core/indexing.py&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;_setitem_with_indexer&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;(self, indexer, value)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    848&lt;/span&gt;                             indexer&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; self&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;obj&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;axes
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    849&lt;/span&gt;                         )
&lt;span class="ansi-green-fg"&gt;--&amp;gt; 850&lt;/span&gt;&lt;span class="ansi-red-fg"&gt;                         &lt;/span&gt;self&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;_setitem_with_indexer&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;new_indexer&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; value&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    851&lt;/span&gt; 
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    852&lt;/span&gt;                         &lt;span class="ansi-green-fg"&gt;return&lt;/span&gt; self&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;obj

&lt;span class="ansi-green-fg"&gt;~/covid-19/venv/lib/python3.6/site-packages/pandas/core/indexing.py&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;_setitem_with_indexer&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;(self, indexer, value)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;   1010&lt;/span&gt;                     labels&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; value&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; plane_indexer&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; lplane_indexer&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; self&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;obj
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;   1011&lt;/span&gt;                 ):
&lt;span class="ansi-green-fg"&gt;-&amp;gt; 1012&lt;/span&gt;&lt;span class="ansi-red-fg"&gt;                     &lt;/span&gt;setter&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;labels&lt;span class="ansi-blue-fg"&gt;[&lt;/span&gt;&lt;span class="ansi-cyan-fg"&gt;0&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;]&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; value&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;   1013&lt;/span&gt; 
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;   1014&lt;/span&gt;                 &lt;span class="ansi-red-fg"&gt;# per label values&lt;/span&gt;

&lt;span class="ansi-green-fg"&gt;~/covid-19/venv/lib/python3.6/site-packages/pandas/core/indexing.py&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;setter&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;(item, v)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    960&lt;/span&gt;                     s&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;_consolidate_inplace&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    961&lt;/span&gt;                     s &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; s&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;copy&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-fg"&gt;--&amp;gt; 962&lt;/span&gt;&lt;span class="ansi-red-fg"&gt;                     &lt;/span&gt;s&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;_data &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; s&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;_data&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;setitem&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;indexer&lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt;pi&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; value&lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt;v&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    963&lt;/span&gt;                     s&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;_maybe_update_cacher&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;clear&lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt;&lt;span class="ansi-green-fg"&gt;True&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    964&lt;/span&gt; 

&lt;span class="ansi-green-fg"&gt;~/covid-19/venv/lib/python3.6/site-packages/pandas/core/internals/managers.py&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;setitem&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;(self, **kwargs)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    559&lt;/span&gt; 
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    560&lt;/span&gt;     &lt;span class="ansi-green-fg"&gt;def&lt;/span&gt; setitem&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;self&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; &lt;span class="ansi-blue-fg"&gt;**&lt;/span&gt;kwargs&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;
&lt;span class="ansi-green-fg"&gt;--&amp;gt; 561&lt;/span&gt;&lt;span class="ansi-red-fg"&gt;         &lt;/span&gt;&lt;span class="ansi-green-fg"&gt;return&lt;/span&gt; self&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;apply&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;"setitem"&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; &lt;span class="ansi-blue-fg"&gt;**&lt;/span&gt;kwargs&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    562&lt;/span&gt; 
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    563&lt;/span&gt;     &lt;span class="ansi-green-fg"&gt;def&lt;/span&gt; putmask&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;self&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; &lt;span class="ansi-blue-fg"&gt;**&lt;/span&gt;kwargs&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;

&lt;span class="ansi-green-fg"&gt;~/covid-19/venv/lib/python3.6/site-packages/pandas/core/internals/managers.py&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;apply&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;(self, f, filter, **kwargs)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    440&lt;/span&gt;                 applied &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; b&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;apply&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;f&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; &lt;span class="ansi-blue-fg"&gt;**&lt;/span&gt;kwargs&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    441&lt;/span&gt;             &lt;span class="ansi-green-fg"&gt;else&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;
&lt;span class="ansi-green-fg"&gt;--&amp;gt; 442&lt;/span&gt;&lt;span class="ansi-red-fg"&gt;                 &lt;/span&gt;applied &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; getattr&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;b&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; f&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;**&lt;/span&gt;kwargs&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    443&lt;/span&gt;             result_blocks &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; _extend_blocks&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;applied&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; result_blocks&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    444&lt;/span&gt; 

&lt;span class="ansi-green-fg"&gt;~/covid-19/venv/lib/python3.6/site-packages/pandas/core/internals/blocks.py&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;setitem&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;(self, indexer, value)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    856&lt;/span&gt;                 &lt;span class="ansi-green-fg"&gt;if&lt;/span&gt; &lt;span class="ansi-green-fg"&gt;not&lt;/span&gt; is_dtype_equal&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;self&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;dtype&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; dtype&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    857&lt;/span&gt;                     b &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; self&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;astype&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;dtype&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-fg"&gt;--&amp;gt; 858&lt;/span&gt;&lt;span class="ansi-red-fg"&gt;                     &lt;/span&gt;&lt;span class="ansi-green-fg"&gt;return&lt;/span&gt; b&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;setitem&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;indexer&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; value&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    859&lt;/span&gt; 
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    860&lt;/span&gt;         &lt;span class="ansi-red-fg"&gt;# value must be storeable at this moment&lt;/span&gt;

&lt;span class="ansi-green-fg"&gt;~/covid-19/venv/lib/python3.6/site-packages/pandas/core/internals/blocks.py&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;setitem&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;(self, indexer, value)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    906&lt;/span&gt; 
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    907&lt;/span&gt;             &lt;span class="ansi-green-fg"&gt;try&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;
&lt;span class="ansi-green-fg"&gt;--&amp;gt; 908&lt;/span&gt;&lt;span class="ansi-red-fg"&gt;                 &lt;/span&gt;values &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; values&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;astype&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;arr_value&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;dtype&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    909&lt;/span&gt;             &lt;span class="ansi-green-fg"&gt;except&lt;/span&gt; ValueError&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;    910&lt;/span&gt;                 &lt;span class="ansi-green-fg"&gt;pass&lt;/span&gt;

&lt;span class="ansi-red-fg"&gt;TypeError&lt;/span&gt;: data type not understood&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [ ]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;&lt;/div&gt;</description><guid>http://www.debsankha.net/posts/pandas-oddity.html</guid><pubDate>Tue, 31 Mar 2020 20:55:06 GMT</pubDate></item><item><title>A python decorator puzzle</title><link>http://www.debsankha.net/posts/a-python-decorator-puzzle.html</link><dc:creator>Debsankha Manik</dc:creator><description>&lt;div&gt;&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [14]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;p&gt;I recently wrote an ETL job to be run in a data processing pipeline. The job fetches data from four database tables in our data lake, stores them in pandas DataFrames and outputs a single DataFrame. 
So in pseudocode:&lt;/p&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [44]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_data_x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"Fetching data X between &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;
    
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_data_y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"Fetching data Y between &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;p&gt;Since the fetching operations are the most time consuming part of the pipeline, I 
wanted to cache the fetched results. I wrote a decorator:&lt;/p&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;h2 id="What's-wrong-with-this-piece-of-code?"&gt;What's wrong with this piece of code?&lt;a class="anchor-link" href="http://www.debsankha.net/posts/a-python-decorator-puzzle.html#What's-wrong-with-this-piece-of-code?"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [45]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pickle&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cache_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'./tmp'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;cache_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;function_details&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__code__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isoformat&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="n"&gt;cache_filepath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cache_dir&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;joinpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function_details&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            
            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"Reading from cache: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cache_filepath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_filepath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'rb'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pickle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"Writing to cache: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cache_filepath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_filepath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'wb'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;pickle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapped&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;decorator&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [46]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nd"&gt;@cache_result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_data_x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"Fetching data X between &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;
    
&lt;span class="nd"&gt;@cache_result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_data_y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"Fetching data Y between &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;
    
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [47]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fetch_data_x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2020-01-01'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2020-02-02'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_wrapper"&gt;
&lt;div class="output"&gt;


&lt;div class="output_area"&gt;

    &lt;div class="prompt"&gt;&lt;/div&gt;


&lt;div class="output_subarea output_text output_error"&gt;
&lt;pre&gt;
&lt;span class="ansi-red-fg"&gt;---------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="ansi-red-fg"&gt;UnboundLocalError&lt;/span&gt;                         Traceback (most recent call last)
&lt;span class="ansi-green-fg"&gt;&amp;lt;ipython-input-47-9ccb94c9170a&amp;gt;&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class="ansi-green-fg"&gt;----&amp;gt; 1&lt;/span&gt;&lt;span class="ansi-red-fg"&gt; &lt;/span&gt;fetch_data_x&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;pd&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;Timestamp&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;'2020-01-01'&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; pd&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;Timestamp&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;'2020-02-02'&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;

&lt;span class="ansi-green-fg"&gt;&amp;lt;ipython-input-45-d206a3d6af1a&amp;gt;&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;wrapped&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;(t_start, t_end)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;      4&lt;/span&gt;     &lt;span class="ansi-green-fg"&gt;def&lt;/span&gt; decorator&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;func&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;      5&lt;/span&gt;         &lt;span class="ansi-green-fg"&gt;def&lt;/span&gt; wrapped&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;t_start&lt;span class="ansi-blue-fg"&gt;,&lt;/span&gt; t_end&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;
&lt;span class="ansi-green-fg"&gt;----&amp;gt; 6&lt;/span&gt;&lt;span class="ansi-red-fg"&gt;             &lt;/span&gt;cache_dir &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; Path&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;cache_dir&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;      7&lt;/span&gt;             function_details &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; &lt;span class="ansi-blue-fg"&gt;f"{func.__code__.co_name},{t_start.isoformat()},{t_end.isoformat}"&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;      8&lt;/span&gt;             cache_filepath &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; cache_dir&lt;span class="ansi-blue-fg"&gt;.&lt;/span&gt;joinpath&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;function_details&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;

&lt;span class="ansi-red-fg"&gt;UnboundLocalError&lt;/span&gt;: local variable 'cache_dir' referenced before assignment&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;h2 id="What-is-going-on?"&gt;What is going on?&lt;a class="anchor-link" href="http://www.debsankha.net/posts/a-python-decorator-puzzle.html#What-is-going-on?"&gt;¶&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This took me quite a while to figure out. I read through &lt;a href="https://wiki.python.org/moin/PythonDecorators"&gt;a couple&lt;/a&gt; of &lt;a href="https://www.python.org/dev/peps/pep-0318/"&gt;in-depth&lt;/a&gt; description of how to write decorators, but was none the wiser.&lt;/p&gt;
&lt;p&gt;In the end, I figured out this &lt;code&gt;UnboundLocalError&lt;/code&gt; has less to do with decorators than namespaces. In particular, we are allowed to &lt;em&gt;reference&lt;/em&gt; a variable defined in an outer scope from an inner scope, but not to  reassign it. More details follow:&lt;/p&gt;
&lt;h3 id="Referencing-variable-defind-in-outer-scope:-OK"&gt;Referencing variable defind in outer scope: OK&lt;a class="anchor-link" href="http://www.debsankha.net/posts/a-python-decorator-puzzle.html#Referencing-variable-defind-in-outer-scope:-OK"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [51]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello "&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_wrapper"&gt;
&lt;div class="output"&gt;


&lt;div class="output_area"&gt;

    &lt;div class="prompt output_prompt"&gt;Out[51]:&lt;/div&gt;




&lt;div class="output_text output_subarea output_execute_result"&gt;
&lt;pre&gt;'Hello world'&lt;/pre&gt;
&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;h3 id="Assigning-to-variable-already-defind-in-outer-scope:-also-fine.-A-new-variable-is-created,-variable-in-outer-scope-not-modified."&gt;Assigning to variable already defind in outer scope: also fine. A new variable is created, variable in outer scope not modified.&lt;a class="anchor-link" href="http://www.debsankha.net/posts/a-python-decorator-puzzle.html#Assigning-to-variable-already-defind-in-outer-scope:-also-fine.-A-new-variable-is-created,-variable-in-outer-scope-not-modified."&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [56]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello "&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hi! "&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_wrapper"&gt;
&lt;div class="output"&gt;


&lt;div class="output_area"&gt;

    &lt;div class="prompt output_prompt"&gt;Out[56]:&lt;/div&gt;




&lt;div class="output_text output_subarea output_execute_result"&gt;
&lt;pre&gt;'Hi! world'&lt;/pre&gt;
&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [55]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"foo is: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_wrapper"&gt;
&lt;div class="output"&gt;


&lt;div class="output_area"&gt;

    &lt;div class="prompt"&gt;&lt;/div&gt;


&lt;div class="output_subarea output_stream output_stdout output_text"&gt;
&lt;pre&gt;foo is: Hello 
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;h3 id="All-hell-breaks-loose-if-you-do-both:-reference-foo-and-at-the-same-time-try-to-assign-to-it:"&gt;All hell breaks loose if you do &lt;em&gt;both&lt;/em&gt;: reference &lt;code&gt;foo&lt;/code&gt; and at the same time try to assign to it:&lt;a class="anchor-link" href="http://www.debsankha.net/posts/a-python-decorator-puzzle.html#All-hell-breaks-loose-if-you-do-both:-reference-foo-and-at-the-same-time-try-to-assign-to-it:"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [57]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello "&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hi"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_wrapper"&gt;
&lt;div class="output"&gt;


&lt;div class="output_area"&gt;

    &lt;div class="prompt"&gt;&lt;/div&gt;


&lt;div class="output_subarea output_text output_error"&gt;
&lt;pre&gt;
&lt;span class="ansi-red-fg"&gt;---------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="ansi-red-fg"&gt;UnboundLocalError&lt;/span&gt;                         Traceback (most recent call last)
&lt;span class="ansi-green-fg"&gt;&amp;lt;ipython-input-57-5b276360a2fe&amp;gt;&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;      6&lt;/span&gt;     &lt;span class="ansi-green-fg"&gt;return&lt;/span&gt; foo&lt;span class="ansi-blue-fg"&gt;+&lt;/span&gt;x
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;      7&lt;/span&gt; 
&lt;span class="ansi-green-fg"&gt;----&amp;gt; 8&lt;/span&gt;&lt;span class="ansi-red-fg"&gt; &lt;/span&gt;hello&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;"world"&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;

&lt;span class="ansi-green-fg"&gt;&amp;lt;ipython-input-57-5b276360a2fe&amp;gt;&lt;/span&gt; in &lt;span class="ansi-cyan-fg"&gt;hello&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;(x)&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;      2&lt;/span&gt; 
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;      3&lt;/span&gt; &lt;span class="ansi-green-fg"&gt;def&lt;/span&gt; hello&lt;span class="ansi-blue-fg"&gt;(&lt;/span&gt;x&lt;span class="ansi-blue-fg"&gt;)&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;
&lt;span class="ansi-green-fg"&gt;----&amp;gt; 4&lt;/span&gt;&lt;span class="ansi-red-fg"&gt;     &lt;/span&gt;&lt;span class="ansi-green-fg"&gt;if&lt;/span&gt; foo &lt;span class="ansi-blue-fg"&gt;==&lt;/span&gt; &lt;span class="ansi-blue-fg"&gt;"Hello"&lt;/span&gt;&lt;span class="ansi-blue-fg"&gt;:&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;      5&lt;/span&gt;         foo &lt;span class="ansi-blue-fg"&gt;=&lt;/span&gt; &lt;span class="ansi-blue-fg"&gt;"Hi"&lt;/span&gt;
&lt;span class="ansi-green-intense-fg ansi-bold"&gt;      6&lt;/span&gt;     &lt;span class="ansi-green-fg"&gt;return&lt;/span&gt; foo&lt;span class="ansi-blue-fg"&gt;+&lt;/span&gt;x

&lt;span class="ansi-red-fg"&gt;UnboundLocalError&lt;/span&gt;: local variable 'foo' referenced before assignment&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;h2 id="Now-the-fixed-decorator"&gt;Now the fixed decorator&lt;a class="anchor-link" href="http://www.debsankha.net/posts/a-python-decorator-puzzle.html#Now-the-fixed-decorator"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [58]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cache_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'./tmp'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;cache_dir_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;function_details&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__code__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="n"&gt;cache_filepath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cache_dir_path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;joinpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function_details&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;cache_dir_path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"Reading from cache: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cache_filepath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_filepath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'rb'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pickle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"Failed to read from cache: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cache_filepath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"Writing to cache: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cache_filepath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_filepath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'wb'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;pickle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapped&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;decorator&lt;/span&gt;

&lt;span class="nd"&gt;@cache_result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_data_x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"Fetching data X between &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;
    
&lt;span class="nd"&gt;@cache_result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_data_y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"Fetching data Y between &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_end&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_end&lt;/span&gt;
    
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [49]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fetch_data_x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2020-01-02'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2020-02-02'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_wrapper"&gt;
&lt;div class="output"&gt;


&lt;div class="output_area"&gt;

    &lt;div class="prompt"&gt;&lt;/div&gt;


&lt;div class="output_subarea output_stream output_stdout output_text"&gt;
&lt;pre&gt;Reading from cache: tmp/fetch_data_x_2020-01-02T00:00:00_2020-02-02T00:00:00
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_area"&gt;

    &lt;div class="prompt output_prompt"&gt;Out[49]:&lt;/div&gt;




&lt;div class="output_text output_subarea output_execute_result"&gt;
&lt;pre&gt;(Timestamp('2020-01-02 00:00:00'), Timestamp('2020-02-02 00:00:00'))&lt;/pre&gt;
&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;p&gt;Some useful articles on the topic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/a/23558809"&gt;https://stackoverflow.com/a/23558809&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@dannymcwaves/a-python-tutorial-to-understanding-scopes-and-closures-c6a3d3ba0937"&gt;https://medium.com/@dannymcwaves/a-python-tutorial-to-understanding-scopes-and-closures-c6a3d3ba0937&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;</description><guid>http://www.debsankha.net/posts/a-python-decorator-puzzle.html</guid><pubDate>Mon, 30 Mar 2020 21:13:50 GMT</pubDate></item><item><title>Python's stdout buffering and systemd</title><link>http://www.debsankha.net/posts/pythons-stdout-buffering-and-systemd.html</link><dc:creator>Debsankha Manik</dc:creator><description>&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;h2 id="Running-a-Python-script-as-a-Systemd-service"&gt;Running a Python script as a Systemd service&lt;a class="anchor-link" href="http://www.debsankha.net/posts/pythons-stdout-buffering-and-systemd.html#Running-a-Python-script-as-a-Systemd-service"&gt;¶&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This is very simple, first we need to create a systmed "unit", in &lt;code&gt;/etc/systemd/system/foo.service&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;Unit&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="nv"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Abracadabra
&lt;span class="nv"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;network.target

&lt;span class="o"&gt;[&lt;/span&gt;Service&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;simple
&lt;span class="nv"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bob
&lt;span class="nv"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;on-failure
&lt;span class="nv"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/python3 /home/bob/test_daemon.py
&lt;span class="o"&gt;[&lt;/span&gt;Install&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="nv"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multi-user.target
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, we can enable and start the service with&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; foo.service
systemctl start foo
&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="What-happens-to-the-stdout-and-stderr?"&gt;What happens to the stdout and stderr?&lt;a class="anchor-link" href="http://www.debsankha.net/posts/pythons-stdout-buffering-and-systemd.html#What-happens-to-the-stdout-and-stderr?"&gt;¶&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;They can be checked by calling &lt;code&gt;journalctl -u foo&lt;/code&gt;. Assuming &lt;code&gt;test_daemon.py&lt;/code&gt; was:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sleep&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Started abracadabra"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;curtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;%X&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hi! Current time is: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;curtime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;we should see&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ sudo journalctl -u foo
Okt &lt;span class="m"&gt;09&lt;/span&gt; &lt;span class="m"&gt;21&lt;/span&gt;:07:18 etna python3&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;13499&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: Started abracadabra
Okt &lt;span class="m"&gt;09&lt;/span&gt; &lt;span class="m"&gt;21&lt;/span&gt;:07:18 etna python3&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;13499&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: Hi! Current &lt;span class="nb"&gt;time&lt;/span&gt; is:  &lt;span class="m"&gt;21&lt;/span&gt;:07:18
Okt &lt;span class="m"&gt;09&lt;/span&gt; &lt;span class="m"&gt;21&lt;/span&gt;:07:20 etna python3&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;13499&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: Hi! Current &lt;span class="nb"&gt;time&lt;/span&gt; is:  &lt;span class="m"&gt;21&lt;/span&gt;:07:20
Okt &lt;span class="m"&gt;09&lt;/span&gt; &lt;span class="m"&gt;21&lt;/span&gt;:07:22 etna python3&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;13499&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: Hi! Current &lt;span class="nb"&gt;time&lt;/span&gt; is:  &lt;span class="m"&gt;21&lt;/span&gt;:07:22
Okt &lt;span class="m"&gt;09&lt;/span&gt; &lt;span class="m"&gt;21&lt;/span&gt;:07:24 etna python3&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;13499&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: Hi! Current &lt;span class="nb"&gt;time&lt;/span&gt; is:  &lt;span class="m"&gt;21&lt;/span&gt;:07:24
Okt &lt;span class="m"&gt;09&lt;/span&gt; &lt;span class="m"&gt;21&lt;/span&gt;:07:26 etna python3&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;13499&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: Hi! Current &lt;span class="nb"&gt;time&lt;/span&gt; is:  &lt;span class="m"&gt;21&lt;/span&gt;:07:26
Okt &lt;span class="m"&gt;09&lt;/span&gt; &lt;span class="m"&gt;21&lt;/span&gt;:07:28 etna python3&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;13499&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: Hi! Current &lt;span class="nb"&gt;time&lt;/span&gt; is:  &lt;span class="m"&gt;21&lt;/span&gt;:07:28
Okt &lt;span class="m"&gt;09&lt;/span&gt; &lt;span class="m"&gt;21&lt;/span&gt;:07:30 etna python3&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;13499&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: Hi! Current &lt;span class="nb"&gt;time&lt;/span&gt; is:  &lt;span class="m"&gt;21&lt;/span&gt;:07:30
&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="Redirecting-stdout/stderr-to-a-file"&gt;Redirecting stdout/stderr to a file&lt;a class="anchor-link" href="http://www.debsankha.net/posts/pythons-stdout-buffering-and-systemd.html#Redirecting-stdout/stderr-to-a-file"&gt;¶&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;We can ask Systemd to do this by adding these lines in &lt;code&gt;/etc/systemd/system/foo.service&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;Service&lt;span class="o"&gt;]&lt;/span&gt;
---snip---
&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/python3 /home/bob/test_daemon.py
&lt;span class="nv"&gt;StandardOutput&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;file:/var/log/foo/stdout
&lt;span class="nv"&gt;StandardError&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;file:/var/log/foo/stderr
---snip---
&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="But-nothing-gets-written-to-/var/log/foo/stdout!"&gt;But nothing gets written to &lt;code&gt;/var/log/foo/stdout&lt;/code&gt;!&lt;a class="anchor-link" href="http://www.debsankha.net/posts/pythons-stdout-buffering-and-systemd.html#But-nothing-gets-written-to-/var/log/foo/stdout!"&gt;¶&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;This is because python &lt;a href="https://unix.stackexchange.com/questions/182537/write-python-stdout-to-file-immediately"&gt;buffers stdout&lt;/a&gt; if it is not a console. If we really want to see the stdout of our daemon as soon as they are printed, we need to disable this buffering. This can be achieved by starting python with &lt;code&gt;-u&lt;/code&gt; flag. So, the systemd unit file changes to:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;Unit&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="nv"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Abracadabra
&lt;span class="nv"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;network.target

&lt;span class="o"&gt;[&lt;/span&gt;Service&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;simple
&lt;span class="nv"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bob
&lt;span class="nv"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;on-failure
&lt;span class="nv"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/python3 /home/bob/test_daemon.py
&lt;span class="nv"&gt;StandardOutput&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;file:/var/log/foo/stdout
&lt;span class="nv"&gt;StandardError&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;file:/var/log/foo/stderr
&lt;span class="o"&gt;[&lt;/span&gt;Install&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="nv"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multi-user.target
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That's it! Now &lt;code&gt;/var/log/foo/stdout&lt;/code&gt; should be populated with whatever &lt;code&gt;test_daemon.py&lt;/code&gt; prints.&lt;/p&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description><guid>http://www.debsankha.net/posts/pythons-stdout-buffering-and-systemd.html</guid><pubDate>Wed, 09 Oct 2019 18:57:06 GMT</pubDate></item><item><title>Logging in Python</title><link>http://www.debsankha.net/posts/logging-in-python.html</link><dc:creator>Debsankha Manik</dc:creator><description>&lt;div&gt;&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;h2 id="Logging-in-Python"&gt;Logging in Python&lt;a class="anchor-link" href="http://www.debsankha.net/posts/logging-in-python.html#Logging-in-Python"&gt;¶&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Python has a very powerful &lt;a href="https://docs.python.org/3.7/library/logging.html"&gt;logging system&lt;/a&gt;. Adding logging to a Python program is as simple as:&lt;/p&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [1]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt; 
&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'__name__'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;function_that_logs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"I was called with x=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, y=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;p&gt;However, calling &lt;code&gt;function_that_logs&lt;/code&gt; won't print the logged message anywhere yet:&lt;/p&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [4]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;function_that_logs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;p&gt;This is because unless explicitly enabled, python ignores logging calls. Otherwise calling codes would be inundated with logging messages from various libraries. 
There are a few steps to do before our logged message gets anywhere.&lt;/p&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [5]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Set the logger level. Anything logged with level lower than DEBUG will be ignored. &lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Now add a handler to our logger. StreamHandler prints to stderr&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# Now the handler's level must be set too.&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Add the handler to the logger&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [7]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;function_that_logs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_wrapper"&gt;
&lt;div class="output"&gt;


&lt;div class="output_area"&gt;

    &lt;div class="prompt"&gt;&lt;/div&gt;


&lt;div class="output_subarea output_stream output_stderr output_text"&gt;
&lt;pre&gt;I was called with x=12, y=13
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;p&gt;Finally, our logged message appears. A &lt;code&gt;logger&lt;/code&gt; can have multiple &lt;code&gt;handler&lt;/code&gt;s in Python: &lt;code&gt;logging&lt;/code&gt; module contains many kinds of &lt;a href="https://docs.python.org/3.7/library/logging.handlers.html#module-logging.handlers"&gt;handlers&lt;/a&gt;, e.g. &lt;code&gt;HTTPHandler&lt;/code&gt; (sends logs to a web server), &lt;code&gt;SMTPHandler&lt;/code&gt; (sends the log via email) etc.&lt;/p&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;h2 id="Custom-formatters"&gt;Custom formatters&lt;a class="anchor-link" href="http://www.debsankha.net/posts/logging-in-python.html#Custom-formatters"&gt;¶&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We might sometimes want some additional information to be logged alongwith the message, for example the time the log was created. This can be achieved by setting the &lt;code&gt;formatter&lt;/code&gt; of our log handler:&lt;/p&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [31]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;%(asctime)s&lt;/span&gt;&lt;span class="s1"&gt; - &lt;/span&gt;&lt;span class="si"&gt;%(name)s&lt;/span&gt;&lt;span class="s1"&gt; - &lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s1"&gt; - &lt;/span&gt;&lt;span class="si"&gt;%(funcName)s&lt;/span&gt;&lt;span class="s1"&gt; - &lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;p&gt;Where do the properties like &lt;code&gt;asctime&lt;/code&gt; or &lt;code&gt;funcName&lt;/code&gt; come from? They are all attributes of the &lt;a href="https://docs.python.org/3.7/library/logging.html#logrecord-attributes"&gt;Logrecord&lt;/a&gt; objects. On each logging call, such a &lt;code&gt;LogRecord&lt;/code&gt; object is created, and they contain a lot of information including the calling code's  module name, filepath, line number etc.&lt;/p&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [12]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"Hello"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [13]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CustomFormatter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [14]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;function_that_logs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class="output_wrapper"&gt;
&lt;div class="output"&gt;


&lt;div class="output_area"&gt;

    &lt;div class="prompt"&gt;&lt;/div&gt;


&lt;div class="output_subarea output_stream output_stderr output_text"&gt;
&lt;pre&gt;I was called with x=12, y=13
Hello
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [ ]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;&lt;/div&gt;</description><guid>http://www.debsankha.net/posts/logging-in-python.html</guid><pubDate>Mon, 30 Sep 2019 19:05:53 GMT</pubDate></item><item><title>Creating this website</title><link>http://www.debsankha.net/posts/creating-this-website.html</link><dc:creator>Debsankha Manik</dc:creator><description>&lt;div&gt;&lt;p&gt;I wanted a personal homepage/blog. I very often jot down my thoughts using 
&lt;a href="https://jupyter.org/"&gt;Jupyter&lt;/a&gt; notebooks or MarkDown documents, so I looked 
for a tool that can create an website out of documents in these two formats. 
Since I &lt;em&gt;love&lt;/em&gt; &lt;a href="https://docs.gitlab.com/ee/ci/pipelines.html"&gt;CI/CD pipelines&lt;/a&gt;,
and totally wanted my future site to be automatically deployed to &lt;a href="https://docs.gitlab.com/ee/user/project/pages/"&gt;GitLab pages&lt;/a&gt;
on each commit, I decided to use a static site generator (SSG). There are quite a few
good SSG's, e.g. &lt;a href="https://docs.getpelican.com/en/stable/"&gt;Pelican&lt;/a&gt;,
&lt;a href="https://jekyllrb.com/"&gt;Jekyll&lt;/a&gt;, &lt;a href="https://gohugo.io/"&gt;Hugo&lt;/a&gt;, to name a few.&lt;/p&gt;
&lt;p&gt;I settled on &lt;a href="https://www.getnikola.com/handbook.html#post-list"&gt;Nikola&lt;/a&gt; because
I liked its documentations, out of the box support for Jupyter nokebooks and
ease of configuring via a python file.&lt;/p&gt;
&lt;p&gt;I roughly followed the guide by &lt;a href="http://www.jaakkoluttinen.fi/blog/how-to-blog-with-jupyter-ipython-notebook-and-nikola/"&gt;Jaakko Luttinen&lt;/a&gt;.
The steps I took were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install nikola in a virtualenv.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;nikola init&lt;/code&gt; to initialize a website.&lt;/li&gt;
&lt;li&gt;Made jupyter notebooks the default format for posts in &lt;code&gt;conf.py&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Enable MathJax rendering of $...$ delimited text.&lt;/li&gt;
&lt;li&gt;Choose a theme by playing around with &lt;code&gt;nikola subtheme&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add CC-BY-SA license.&lt;/li&gt;
&lt;li&gt;Configure &lt;code&gt;GitLab CI&lt;/code&gt; so that on each commit, a fresh copy of the site gets deployed to GitLab pages.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;</description><guid>http://www.debsankha.net/posts/creating-this-website.html</guid><pubDate>Tue, 17 Sep 2019 19:32:37 GMT</pubDate></item><item><title>Hello World</title><link>http://www.debsankha.net/posts/hello-world.html</link><dc:creator>Debsankha Manik</dc:creator><description>&lt;div&gt;&lt;div class="cell border-box-sizing text_cell rendered"&gt;&lt;div class="prompt input_prompt"&gt;
&lt;/div&gt;&lt;div class="inner_cell"&gt;
&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;
&lt;h2 id="Header"&gt;Header&lt;a class="anchor-link" href="http://www.debsankha.net/posts/hello-world.html#Header"&gt;¶&lt;/a&gt;&lt;/h2&gt;&lt;h3 id="Moar-header"&gt;Moar header&lt;a class="anchor-link" href="http://www.debsankha.net/posts/hello-world.html#Moar-header"&gt;¶&lt;/a&gt;&lt;/h3&gt;&lt;h4 id="Equation-$E=mc%5E4$"&gt;Equation $E=mc^4$&lt;a class="anchor-link" href="http://www.debsankha.net/posts/hello-world.html#Equation-%24E=mc%5E4%24"&gt;¶&lt;/a&gt;&lt;/h4&gt;$$
a = b+c
$$
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="cell border-box-sizing code_cell rendered"&gt;
&lt;div class="input"&gt;
&lt;div class="prompt input_prompt"&gt;In [ ]:&lt;/div&gt;
&lt;div class="inner_cell"&gt;
    &lt;div class="input_area"&gt;
&lt;div class=" highlight hl-ipython3"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;&lt;/div&gt;</description><category>test</category><guid>http://www.debsankha.net/posts/hello-world.html</guid><pubDate>Sun, 15 Sep 2019 15:02:21 GMT</pubDate></item></channel></rss>