<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Planetpython on Janusworx</title><link>https://janusworx.com/tags/planetpython/</link><description>Recent content in Planetpython on Janusworx</description><generator>Hugo -- gohugo.io</generator><language>en</language><managingEditor>feedback@janusworx.com (Mario Jason Braganza)</managingEditor><webMaster>feedback@janusworx.com (Mario Jason Braganza)</webMaster><copyright>© 2026, Mario Jason Braganza</copyright><lastBuildDate>Thu, 14 Sep 2023 17:38:03 +0530</lastBuildDate><atom:link href="https://janusworx.com/tags/planetpython/index.xml" rel="self" type="application/rss+xml"/><item><title>derb; Script to Create podcast RSS feeds</title><link>https://janusworx.com/work/derb/</link><pubDate>Thu, 14 Sep 2023 17:38:03 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/derb/</guid><description>&lt;p&gt;I wrote a tiny script that creates an RSS feed for all the audio files it finds in a folder.&lt;br&gt;
I call it &lt;a href="https://github.com/jasonbraganza/derb" target="_blank" rel="noreferrer"&gt;derb&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My mother gets devotional songs and sermons on cds, which I rip to MP3 files and then dump on her phone for her.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;br&gt;
She listens to them all the time, and now three of her friends want to do the same too.&lt;br&gt;
I thought of just sticking them in my self hosted &lt;a href="https://jellyfin.org/" target="_blank" rel="noreferrer"&gt;Jellyfin&lt;/a&gt; instance,&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; but then I realised, all of them have erratic, slow internet. So the idea of self hosting a podcast feed really appealed to me.&lt;/p&gt;
&lt;p&gt;So I quickly used &lt;a href="https://github.com/lkiesow/python-feedgen" target="_blank" rel="noreferrer"&gt;Feedgenerator&lt;/a&gt; in conjunction with &lt;a href="https://github.com/devsnd/tinytag" target="_blank" rel="noreferrer"&gt;Tinytag&lt;/a&gt;, to whip up a script that’d help me do just that.
&lt;a href="https://github.com/jasonbraganza/derb" target="_blank" rel="noreferrer"&gt;The code’s up on Github&lt;/a&gt;, if you want to go install and play with it yourselves.&lt;/p&gt;
&lt;p&gt;Here’s a quick walk through &lt;code&gt;derb.py&lt;/code&gt;.&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h3 class="relative group"&gt;Setting up house
 &lt;div id="setting-up-house" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#setting-up-house" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;We set up a place to accept a path containing the files. The feed will ultimately be placed as a &lt;code&gt;feed.xml&lt;/code&gt; in the same folder as well
We then walk through the folder (after a really basic sanity check) and gather all the files into a list.&lt;br&gt;
The &lt;code&gt;base_url&lt;/code&gt; is where the feeds (along with the audio) will be served from.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://ab.janusworx.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;book_folder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Paste path to audiobook folder here: &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;book_out_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book_folder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;file_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;walk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book_folder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Do a basic check on the validity of the path we get, &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# before we build the audio file list.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;all_files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_list&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&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;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;IndexError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&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;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;---&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ERROR!: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Have you typed in the right path?&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;---&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Quitting script!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;each_file&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;all_files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;each_file&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;each_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;each_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;.mp3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.m4a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.m4b&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;audio_files&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;each_file&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audio_files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;hr style='margin-left: auto; margin-right: auto; margin-bottom: 40px; margin-top: 50px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238); height: 1px;'/&gt;


&lt;h3 class="relative group"&gt;Creating a feed
 &lt;div id="creating-a-feed" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#creating-a-feed" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;We now go about the business of setting up the feed proper.&lt;br&gt;
To begin with, we grab the first file we can get our grubby paws on, and create a TinyTag object that’ll give us a lot of metadata. (If there isn’t any, we quit.)&lt;br&gt;
Oh, and by the way, how do I know what data I’d need to create a feed? I just cribbed everything from the &lt;a href="https://github.com/lkiesow/python-feedgen" target="_blank" rel="noreferrer"&gt;Feedgenerator’s excellent documentation&lt;/a&gt;. I also looked at the widely linked to, &lt;a href="https://cyber.harvard.edu/rss/rss.html" target="_blank" rel="noreferrer"&gt;RSS&lt;/a&gt; reference page for clarification if I got confused.&lt;/p&gt;
&lt;p&gt;We then, instantiate create a feedgenerator object along with the podcast extension.&lt;br&gt;
Following which, we supply the feed a title, an id&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;, feed author details, a language, podcast category and description.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Setup a feed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;## Grab feed metadata from the first audio file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;feed_metadata_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TinyTag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&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;book_folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;audio_files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;## Grab title from metadata file.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;## At the same time, break out if there isn’t any.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;feed_metadata_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;---&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Stopping feed creation.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;Setup&lt;/span&gt; &lt;span class="n"&gt;audio&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="n"&gt;editor&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;feed_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;feed_metadata_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;album&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;## Creating feed instance&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_book_feed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FeedGenerator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_book_feed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_extension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;podcast&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;## Setting up more stuff on the feed proper&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_book_feed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_book_feed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feed_title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_book_feed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Jason Braganza&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;email&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;feedback@janusworx.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_book_feed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;book_out_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;self&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_book_feed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;en&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_book_feed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;podcast&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;itunes_category&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Private&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_book_feed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feed_title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;hr style='margin-left: auto; margin-right: auto; margin-bottom: 40px; margin-top: 50px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238); height: 1px;'/&gt;


&lt;h3 class="relative group"&gt;Adding episodes and writing out the file
 &lt;div id="adding-episodes-and-writing-out-the-file" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#adding-episodes-and-writing-out-the-file" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;After which it’s then a matter of looping through that audio file list we created and adding them as entries to the feed object we created.&lt;br&gt;
Once again we grab the metadata from each file, using &lt;a href="https://github.com/devsnd/tinytag" target="_blank" rel="noreferrer"&gt;Tinytag&lt;/a&gt;, and then set each feed entry’s details (title, id and enclosure).&lt;br&gt;
I’ve hardcoded the mime types, since I know I only have two basic type of audio files. If you don’t know what kind of audio, you might be serving, the &lt;a href="https://pypi.org/project/mimetypes-magic/" target="_blank" rel="noreferrer"&gt;&lt;code&gt;mimetypes-magic&lt;/code&gt;&lt;/a&gt; package should help.&lt;br&gt;
Finally we write it all out to a file.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Loop the file list and create entries in the feed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;each_file&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;audio_files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;each_file_metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TinyTag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&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;book_folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;each_file&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;episode_file_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;each_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;episode_suffix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;episode_file_path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;episode_mime_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;audio/mpeg&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;episode_suffix&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.mp3&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;audio/x-m4a&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;episode_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;each_file_metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;episode_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;each_file_metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filesize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;episode_link&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;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;book_out_path&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;each_file&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;audio_episode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;audio_book_feed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_entry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;audio_episode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;episode_title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;audio_episode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;episode_link&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;audio_episode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enclosure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;episode_link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;episode_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;episode_mime_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Write the rss feed to the same folder as the source audio files&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;audio_book_feed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rss_file&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;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;book_folder&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/feed.xml&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;hr style='margin-left: auto; margin-right: auto; margin-bottom: 40px; margin-top: 50px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238); height: 1px;'/&gt;


&lt;h3 class="relative group"&gt;Serving
 &lt;div id="serving" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#serving" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;Once done, I moved it all to my trusty Pi, which runs barebones Nginx with a single bare page, protected by basic auth.&lt;br&gt;

&lt;figure&gt;
 &lt;img class="my-0 rounded-md" src="https://janusworx.com/images/2023/private-web-page.png" alt="" /&gt;
 
 
 &lt;/figure&gt;
I decided not to publish the feeds publicly.&lt;br&gt;
Rather I’m going to just set it up in their podcast players, when I meet them, or pass it over to their kids over Signal.&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;br&gt;
It’s already worked with three of them, so everyone’s happy and here’s me hoping, fingers crossed, it’ll be easy to support in the long run.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update (2023-09-15):&lt;/strong&gt;&lt;/em&gt; &lt;em&gt;&lt;a href="https://www.humblebundle.com/books/sci-fi-classic-audiobooks-feat-hell-divers-books" target="_blank" rel="noreferrer"&gt;Guess I’m using it for myself too, now&lt;/a&gt; 😂&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;hr style='margin-left: auto; margin-right: auto; margin-bottom: 40px; margin-top: 50px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238); height: 1px;'/&gt;

Feedback on this post? Mail me at &lt;a href="mailto:&amp;amp;#102;&amp;amp;%23101;&amp;amp;%23101;&amp;amp;%23100;&amp;amp;%2398;&amp;amp;%2397;&amp;amp;%2399;&amp;amp;%23107;&amp;amp;%2364;&amp;amp;%23106;&amp;amp;%2397;&amp;amp;%23110;&amp;amp;%23117;&amp;amp;%23115;&amp;amp;%23119;&amp;amp;%23111;&amp;amp;%23114;&amp;amp;%23120;&amp;amp;%2346;&amp;amp;%2399;&amp;amp;%23111;&amp;amp;%23109;" &gt;feedback@janusworx.com&lt;/a&gt;
&lt;br&gt;

&lt;br&gt;

P.S. Subscribe to my &lt;a href="https://janusworx.com/subscribe/" target="_blank" rel="noreferrer"&gt;mailing list!&lt;/a&gt;&lt;br&gt;
Forward these posts and letters to your friends and get them to subscribe!&lt;br&gt;
P.P.S. Feed my &lt;a href="https://www.amazon.in/hz/wishlist/ls/2QAUKHHAMOOVS?ref_=wl_share" target="_blank" rel="noreferrer"&gt;insatiable reading habit.&lt;/a&gt;&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Yes, while it’s slowly moving to Youtube, that world still mostly depends on CDs and USB sticks.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;the audio files, not my mother’s friends.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Large parts are elided. Please look at Github for the actual file.&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;normally, the site it’ll be served from&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;Why should I be the only one doing family tech support?&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>TIL: The Difference Between a CLI Tool and a Freeze Tool</title><link>https://janusworx.com/work/til-the-difference-between-a-cli-tool-and-a-freeze-tool/</link><pubDate>Wed, 01 Mar 2023 11:35:47 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/til-the-difference-between-a-cli-tool-and-a-freeze-tool/</guid><description>&lt;p&gt;I keep writing these tiny utilities for myself in Python and while I &lt;em&gt;love&lt;/em&gt; writing in Python, I definitely don’t enjoy the little war dance I have to do everytime I want to run it on a new machine. Keeping track of virtual environments, and then installing packages in them, quickly gets tiresome. I want to just run the program once I’m done with it. Like a C program. Or Rust. Or Go.&lt;/p&gt;
&lt;p&gt;I could go learn one of those languages. Sure. That’s an option.&lt;br&gt;
And I see no problem doing it for other needs (like if I’m working with a group that uses said language) or for my career’s sake or just for being a polyglot.&lt;/p&gt;
&lt;p&gt;But when I write for myself, I’d rather stick to Python.&lt;br&gt;
Its mental model fits my brain. I find writing Python joyful.&lt;/p&gt;
&lt;p&gt;So what’s a boy to do?&lt;br&gt;
Since I was writing CLI applications, I went and looked for how to write Python CLIs and I found &lt;code&gt;argparse&lt;/code&gt; and &lt;a href="https://typer.tiangolo.com/" target="_blank" rel="noreferrer"&gt;Typer&lt;/a&gt; and &lt;a href="https://click.palletsprojects.com/en/8.1.x/" target="_blank" rel="noreferrer"&gt;Click&lt;/a&gt; and I was confused. They didn’t seem to give me my executable. They had all sorts of other powerful features, but the one I wanted.&lt;br&gt;
And I went looking some more. And the penny dropped.&lt;/p&gt;
&lt;p&gt;What I wanted, wasn’t a way to build a CLI, (although that is what I was writing).&lt;br&gt;
What I wanted, was a way to bundle my environment into an executable.&lt;br&gt;
What I wanted, I learned, was a way to &lt;em&gt;&lt;a href="https://docs.python-guide.org/shipping/freezing/" target="_blank" rel="noreferrer"&gt;freeze my code&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;More searching led to &lt;a href="https://nuitka.net/pages/overview.html" target="_blank" rel="noreferrer"&gt;Nuitka&lt;/a&gt;, &lt;a href="https://github.com/indygreg/PyOxidizer" target="_blank" rel="noreferrer"&gt;PyOxidizer&lt;/a&gt;, &lt;a href="https://pyinstaller.org/en/stable/" target="_blank" rel="noreferrer"&gt;PyInstaller&lt;/a&gt; and their ilk.&lt;br&gt;
I went with Nuitka, because that is what I found first and what I found was &lt;em&gt;dead simple&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python -m nuitka --static-libpython&lt;span class="o"&gt;=&lt;/span&gt;no mastodon-to-moi.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;and &lt;em&gt;boom!&lt;/em&gt;&lt;br&gt;
I got myself an executable &lt;code&gt;mastodon-to-moi.bin&lt;/code&gt;!&lt;br&gt;
And then I got greedy and did a &lt;code&gt;mastodon-to-moi.bin --help&lt;/code&gt; and figured, &lt;em&gt;that’s&lt;/em&gt; where the cli/tui frameworks like Typer and Textualize, come in handy. To scaffold and help these interfaces.&lt;/p&gt;
&lt;p&gt;But when I ran it on my laptop, which has nothing other than system Python, it hiccoughed. I tried Pyinstaller next, and that too, did not do the trick. It choked on a loop, that worked when I ran it as with Python normally. PyOxidizer scared me off.&lt;/p&gt;
&lt;p&gt;This needs looking further looking into, but atleast I know what I need to do now&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Afterthought:&lt;/strong&gt;&lt;/em&gt; The one con I do see, is losing platform independence. My binaries will be Linux on Intel only.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; I could just take my Python source anywhere, set up my environment and &lt;em&gt;go&lt;/em&gt;. Well, I still have that option if I need it and in the meanwhile, having binaries affords me a lot of convenience.&lt;/p&gt;
&lt;p&gt;&lt;hr style='margin-left: auto; margin-right: auto; margin-bottom: 40px; margin-top: 50px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238); height: 1px;'/&gt;

Feedback on this post? Mail me at &lt;a href="mailto:&amp;amp;#102;&amp;amp;%23101;&amp;amp;%23101;&amp;amp;%23100;&amp;amp;%2398;&amp;amp;%2397;&amp;amp;%2399;&amp;amp;%23107;&amp;amp;%2364;&amp;amp;%23106;&amp;amp;%2397;&amp;amp;%23110;&amp;amp;%23117;&amp;amp;%23115;&amp;amp;%23119;&amp;amp;%23111;&amp;amp;%23114;&amp;amp;%23120;&amp;amp;%2346;&amp;amp;%2399;&amp;amp;%23111;&amp;amp;%23109;" &gt;feedback@janusworx.com&lt;/a&gt;
&lt;br&gt;

&lt;br&gt;

P.S. Subscribe to my &lt;a href="https://janusworx.com/subscribe/" target="_blank" rel="noreferrer"&gt;mailing list!&lt;/a&gt;&lt;br&gt;
Forward these posts and letters to your friends and get them to subscribe!&lt;br&gt;
P.P.S. Feed my &lt;a href="https://www.amazon.in/hz/wishlist/ls/2QAUKHHAMOOVS?ref_=wl_share" target="_blank" rel="noreferrer"&gt;insatiable reading habit.&lt;/a&gt;&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;until I learn to cross compile that is.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>Updated Poemfeed</title><link>https://janusworx.com/personal/updated-poemfeed/</link><pubDate>Fri, 27 May 2022 18:52:00 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/personal/updated-poemfeed/</guid><description>&lt;p&gt;&lt;em&gt;Update: fixed Github link&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://janusworx.com/blog/a-hundred-days-of-code-day-029/" target="_blank" rel="noreferrer"&gt;little script&lt;/a&gt; I wrote in 2020, to get me my daily poetry fix, died a couple of months ago.&lt;br&gt;
Life got in the way of me, figuring out what was wrong.&lt;/p&gt;
&lt;p&gt;I finally got around to it today.&lt;br&gt;
A little bit of peeking under the hood revealed that Cloudflare did not like me using the Python Requests library to check the Poetry Foundation page.&lt;br&gt;
Or maybe it just did not like the useragent string that Requests gave it.&lt;br&gt;
I was in no mood to go down that rabbit hole, so I just went looking for modern alternatives to Requests.&lt;br&gt;
Found &lt;a href="https://www.python-httpx.org/" target="_blank" rel="noreferrer"&gt;HTTPX.&lt;/a&gt;&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; and switched over to it.&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;br&gt;
And then while I was at it, replaced PyRSS2Gen with &lt;a href="https://feedgen.kiesow.be/" target="_blank" rel="noreferrer"&gt;FeedGenerator.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And tada!
Poemfeed lives again!&lt;br&gt;
Find the updated code, &lt;a href="https://github.com/jasonbraganza/poemfeed" target="_blank" rel="noreferrer"&gt;over on Github.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Writing code today, made me realise, how far I have come since I wrote that code.&lt;br&gt;
I figured out the issue, I knew just how I wanted it to work, I went out, researched the code, and then wrote and iterated over the code and got it working in a matter of hours.&lt;br&gt;
&lt;a href="https://github.com/kushaldas/" target="_blank" rel="noreferrer"&gt;Kushal&lt;/a&gt; was right.&lt;br&gt;
Writing lots of shitty code, over and over and over again is the best way to get fluent.&lt;br&gt;
Here’s to more contributing and lots more of writing code!&lt;/p&gt;
&lt;hr style='margin-left: auto; margin-right: auto; margin-bottom: 40px; margin-top: 50px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238); height: 1px;'/&gt;

&lt;p&gt;P.S. Subscribe to my &lt;a href="https://janusworx.com/subscribe/" target="_blank" rel="noreferrer"&gt;mailing list!&lt;/a&gt;&lt;br&gt;
Forward these posts and letters to your friends and get them to subscribe!&lt;br&gt;
P.P.S. Feed my &lt;a href="https://www.amazon.in/hz/wishlist/ls/2QAUKHHAMOOVS?ref_=wl_share" target="_blank" rel="noreferrer"&gt;insatiable reading habit.&lt;/a&gt;&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;which delightfully, has a Requests compatible API&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;and to be sure, changed the userstring, so that my script presented itself as Firefox&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>Starting up #CNC2021.</title><link>https://janusworx.com/personal/starting-up-cnc2021/</link><pubDate>Tue, 20 Apr 2021 19:06:06 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/personal/starting-up-cnc2021/</guid><description>&lt;p&gt;Enough learning.&lt;br&gt;
I now have to drill what I’ve learnt over the past few weeks and months by writing lots of code.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;
&lt;p&gt;Been noodling around with what that might look like in my head.
Here’s what I got.&lt;br&gt;
After tentatively coding up stuff in a couple of domains and after a short chat with a friend, I realise I love writing code for the web.&lt;br&gt;
I love reading.&lt;br&gt;
I love to write on my blog.&lt;br&gt;
I love that with just a few keypresses, my words can be read by anyone on the web, no gatekeeper required.&lt;br&gt;
I would love to write code to enable this for more people.&lt;br&gt;
I would love to play and tinker and push at the boundaries of this domain.
This intersection of all this is web development.&lt;br&gt;
Ergo, I want to become a web developer.&lt;/p&gt;
&lt;p&gt;So while I have learnt and watched and written a bit of code and understand how programming works, what I need now, if I want this to be my second career, is fluency and a portfolio.&lt;/p&gt;
&lt;p&gt;To that end,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I need to do all sorts of basic exercises in the languages I am learning (Python/HTML/CSS/JavaScript)&lt;/li&gt;
&lt;li&gt;I need to find and contribute to open source projects, to get a feel of how it is to work with folks and to understand how this whole world functions&lt;/li&gt;
&lt;li&gt;I need to write toy projects for myself.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Learning by my ownsome was a tremendously hard, extremely lonely task.&lt;br&gt;
I don’t want to repeat that mistake again.&lt;br&gt;
So, to start with the “doing”, I’ve signed up at Code Newbie for their &lt;a href="https://community.codenewbie.org/codenewbie/announcing-cnc2021-codenewbie-challenge-2021-1jbh" target="_blank" rel="noreferrer"&gt;#CNC2021&lt;/a&gt; challenge.&lt;br&gt;
Lasts 5 weeks, and I’m already a couple of days behind, but never mind that.&lt;br&gt;
I also stretched a bit and signed up for the Code More challenge.&lt;/p&gt;
&lt;p&gt;As to what’s involved, I have no clue, yet.&lt;br&gt;
Will wait up for their emails and then do the work and write all about it here.&lt;/p&gt;</description></item><item><title>I Can’t Do This Yet … Updated</title><link>https://janusworx.com/personal/i-cant-do-this-yet-updated/</link><pubDate>Sat, 17 Apr 2021 14:33:15 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/personal/i-cant-do-this-yet-updated/</guid><description>&lt;p&gt;Updated version of the post. I seem to have somehow, mangled the old one.&lt;br&gt;
I’ll just blame it on the gremlins in the cloud.&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 
&lt;p&gt;I’ve been “soft” looking for a job, since the end of last year when I learnt the basics of Python.&lt;br&gt;
&lt;small&gt;&lt;em&gt;(Want me to come work with you as a junior developer? Here’s &lt;a href="https://janusworx.com/files/mjb-resume-i.pdf" target="_blank" rel="noreferrer"&gt;my resume!&lt;/a&gt;)&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;And I’ve had rejection after rejection after rejection.&lt;br&gt;
I apparently am good.&lt;br&gt;
I have skills.&lt;br&gt;
I could be an asset for companies.&lt;br&gt;
But I am not “quite” what folks are looking for, not quite right for them.&lt;br&gt;
I am not quite what it is, folks are looking for, to take chance on.&lt;br&gt;
I am a square peg …&lt;/p&gt;
&lt;p&gt;And while I understand this in my head, my heart does not get it at times.&lt;br&gt;
And that’s when &lt;a href="https://seths.blog/2021/02/a-simple-missing-word/" target="_blank" rel="noreferrer"&gt;Seth&lt;/a&gt;, as usual comes to the rescue.&lt;br&gt;
With a word, that I am increasingly using to mentally toughen myself and give me courage.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Yet …&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;From &lt;a href="https://seths.blog/2017/06/a-professional-stumbler/" target="_blank" rel="noreferrer"&gt;A Professional Stumbler&lt;/a&gt; …&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Leo&amp;rsquo;s working hard to do something he&amp;rsquo;s never done before. He&amp;rsquo;s just turned one, and he doesn&amp;rsquo;t know how to walk &lt;em&gt;&lt;strong&gt;(yet).&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;There are no really useful books or videos on how to walk. It&amp;rsquo;s something he has to figure out on his own. But instead of waiting on the couch until the day he&amp;rsquo;s ready to proudly strut across the room, he&amp;rsquo;s there, on the floor, every day, trying it out.&lt;/p&gt;
&lt;p&gt;He&amp;rsquo;s already discovered a hundred ways that don&amp;rsquo;t work, and stumbled countless times.&lt;/p&gt;
&lt;p&gt;But he persists.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t know about you, but this is precisely the way I learned how to walk as well.&lt;/p&gt;
&lt;p&gt;In fact, it&amp;rsquo;s the way I learned how to do just about everything important. By doing it.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;From &lt;a href="https://seths.blog/2021/02/a-simple-missing-word/" target="_blank" rel="noreferrer"&gt;A Simple Missing Word&lt;/a&gt; …&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;“Yet”.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You can append it after any sentence related to your journey of achievement and contribution.&lt;/p&gt;
&lt;p&gt;“I haven’t finished the project”&lt;br&gt;
“I haven’t learned how to juggle”&lt;br&gt;
“I haven’t made the sale”&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;YET.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And along the way, “Yet” turns “can’t” into “haven’t.”&lt;/p&gt;
&lt;p&gt;Yet isn’t the result of brazen persistence. It’s what we earn with learning, insight and generosity.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;From &lt;a href="https://seths.blog/2020/02/so-far-not-yet/" target="_blank" rel="noreferrer"&gt;So Far / Not Yet&lt;/a&gt; …&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;What to do in the face of failure? What happens when you’ve done your best and it still doesn’t get the review, close the sale or win the race?&lt;/p&gt;
&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;… The growth mindset, is to realize that while you did your best, it’s not your best forever, it’s just what you’ve done so far. And that while you haven’t created what you set out to create, the key word, the one you have to remind yourself of daily, is &lt;em&gt;&lt;strong&gt;yet.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;From &lt;a href="https://seths.blog/2015/07/you-have-no-credibility-yet/" target="_blank" rel="noreferrer"&gt;You Have No Credibility (yet)&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Your belief, even your proof, is insufficient for you to get the attention, the trust and the action you seek. &lt;br&gt;
Attention is not yours to take whenever you need it. And trust is not something you can insist on.&lt;br&gt;
The bad news is that you are not entitled to attention and trust. It is not allocated on the basis of some sort of clearly defined scale of worthiness.&lt;br&gt;
The good news is that you can earn it. You can invest in the community, you can patiently lead and contribute and demonstrate that the attention you are asking be spent on you is worthwhile.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;So yes, I might not be up to par, might not match up to what they look for, might not be skilled enough … &lt;em&gt;&lt;strong&gt;yet.&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
I’ll get there, soon enough!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://seths.blog/2021/04/youre-not-that-good/" target="_blank" rel="noreferrer"&gt;&lt;h2 id="update"&gt;“You’re not that good”&lt;/h2&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And of course, Seth has to read my little blog and riff off my post :P&lt;br&gt;
I kid. He doesn’t even know I exist. But talk about happy serendipity!&lt;br&gt;
You’re not that good, spells my journey up above in beautiful detail.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The first is that when we begin, we’re not that good. This is a fact. The breakthrough for anyone on this journey is adding the word **&lt;em&gt;“yet.”&lt;/em&gt;
**&lt;/p&gt;
&lt;p&gt;It doesn’t pay to pretend that we’ve figured it out before we have. It’s counterproductive to adopt a brittle attitude in the face of criticism. In fact, during this stage, “you’re not that good,” is precisely what we need to hear, because it might be followed with insight on how to get better.&lt;/p&gt;
&lt;p&gt;The second is that once we start to build skills and offer something of value, some people are going to persist in believing that we’re not that good. Fine. They’ve told us something about themselves and what they want and need. This is a clue to offer our leadership and contribution to someone else, someone who gets what we’re doing and wants it. The smallest viable audience isn’t a compromise, it’s a path forward. Find the folks who are enrolled and open and eager. Serve them instead.&lt;br&gt;
The danger is that when you hear rejection during this stage, you might come to believe that you’ve accomplished nothing, as opposed to realizing that you might simply be talking to the wrong people.&lt;/p&gt;
&lt;p&gt;And the third comes full circle. Because it’s possible that in fact, we’re not that good yet, and there aren’t enough people who want what we’ve got. We’re simply not good enough for this part of the market. So we embrace that truth and begin at the beginning. We’re not good enough yet. We haven’t practiced enough, found enough empathy, understood the genre well enough and figured out how to contribute. Yet. At least for this audience.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;And then we get better.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>A Love Letter to Books</title><link>https://janusworx.com/personal/a-love-letter-to-books/</link><pubDate>Thu, 08 Apr 2021 18:38:32 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/personal/a-love-letter-to-books/</guid><description>&lt;blockquote&gt;&lt;p&gt;Despite financial troubles there’s a sense in which my childhood was immensely privileged — a pauper in the material world, I was a sultan in the world of ideas.&lt;/p&gt;
&lt;p&gt;— &lt;a href="https://lithub.com/the-joy-and-privilege-of-growing-up-in-an-indie-bookstore/" target="_blank" rel="noreferrer"&gt;Erik Hoel&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;I started by wanting to share that quote and link on my microblog and then my thoughts turned into a blog post sized comment.&lt;br&gt;
I decided to post it here too, then.&lt;/p&gt;
&lt;hr style="margin-left: auto; margin-right: auto;margin-bottom: 40px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238); height: 1px;" /&gt;
&lt;!-- TEASER_END --&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="low"
 alt="Bookshelf"
 src="https://janusworx.com/images/2021/bookshelf.jpeg"
 &gt;&lt;/figure&gt;
&lt;hr style="margin-left: auto; margin-right: auto;margin-bottom: 40px; margin-top: 40px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238); height: 1px;" /&gt;
&lt;p&gt;That quote describes my life to a T, even now.&lt;/p&gt;
&lt;p&gt;I might be financially down in the dumps, but when it comes to books, my friends and kinfolk, have always somehow found a way to keep me happy and occupied.&lt;/p&gt;
&lt;p&gt;The school librarian knew I used the library for what it actually was, a repository of magic and wisdom, and not what most folks used it for, a sick bay.&lt;br&gt;
Which meant at least once a month, I would tell my teachers I was sick, go to the library and read books for an hour and after a year, the librarian would turn a blind eye to my presence too.&lt;br&gt;
I was lost in Verne and Poe and Dickens.&lt;/p&gt;
&lt;p&gt;The roadside vendor at the railway station, who I would buy books second hand from, would always keep the keep the newest ones for me.&lt;br&gt;
If I couldn’t pay, he’d lend them to me on the condition, that I return it in day or two&lt;br&gt;
This is where I got to read epic fiction. Tolkien’s worlds and McCullough’s Rome, all entranced me.&lt;/p&gt;
&lt;p&gt;As a young hardware engineer making calls all over the city, I got to know the nooks and crannies of Bombay and more importantly I learnt where I could find the books that I wanted to read.&lt;br&gt;
The Strand, and the roadside vendors at Fountain and Matunga and other nooks and cranies across the expanse of my tiny (in area) city became intimate friends.&lt;br&gt;
Crazy animé, Golden age Marvel, “Banned” books, Old scifi and fantasy authors like Asimov and Niven/Pournelle and and newfangled ones like Gaiman and GRRM and the ones who would merge story telling and philosophy like PKD or Anthony DeMello and Carroll.&lt;/p&gt;
&lt;p&gt;Friends, family, bosses, coworkers have all been indulgent too.&lt;br&gt;
I own the Ultimate Sandman, and the Complete Calvin and Hobbes, and the Complete Asterix, and a Niven novel that Asimov signed, and lots of Gibran, and lots of Anthony DeMello, and lots and lots and lots of hardbacks thanks to their generosity.&lt;/p&gt;
&lt;p&gt;In a life, that has been constantly buffeted by storms, books have been my solace.&lt;/p&gt;
&lt;p&gt;I may not not have graduated college, but books have been my education.&lt;br&gt;
Books have gotten me over breakups.&lt;br&gt;
Books have taught me how to save money and make it grow.&lt;br&gt;
Books have made me a better human by passing on the wisdom of the ancients to me.&lt;br&gt;
Books made me healthier by teaching me how to lose weight sustainably.&lt;br&gt;
Books gave me a leg up in life.&lt;br&gt;
Books are helping me reinvent my work life as I change careers to programming.&lt;/p&gt;
&lt;p&gt;Books give me a leg up in life.&lt;br&gt;
With books I have been truly privileged and truly blessed!&lt;/p&gt;</description></item><item><title>Thoughts on Setting Up a Blog</title><link>https://janusworx.com/personal/thoughts-on-setting-up-a-blog/</link><pubDate>Fri, 26 Mar 2021 05:45:00 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/personal/thoughts-on-setting-up-a-blog/</guid><description>&lt;p&gt;&lt;small&gt;&lt;em&gt;This post was first sent to my newsletter on March 19th, 2021.&lt;br&gt;
[You really ought to subscribe][1] :)&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;I blame Mahe for this post.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;Hey, Jason!&lt;br&gt;
Can you please write an article on how to build a website like yours, where I can post my blogs?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Check out her blogs, &lt;a href="https://maheiram.medium.com/" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt; and &lt;a href="https://renderingsofmyheart.wordpress.com/" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 
&lt;p&gt;This one is squarely aimed at all the young ones, who are convinced that they need to be writing.&lt;br&gt;
&lt;a href="https://summertraining.readthedocs.io/en/latest/blogging.html" target="_blank" rel="noreferrer"&gt;&lt;em&gt;(Maybe, it was me who convinced you, in the first place.)&lt;/em&gt;&lt;/a&gt;&lt;br&gt;
You are young (or like me, forever young) and broke (also like me).&lt;br&gt;
You need a place for your thoughts to call home.&lt;br&gt;
You need a place to &lt;em&gt;write&lt;/em&gt;, and grow and focus more on what you want to say about life and what you study or what you work at, or the portfolio/showcase of thoughts you will slowly build.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;What you use to write, does not matter at this stage!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So, what now?&lt;/p&gt;
&lt;h2 id='intent'&gt;&lt;a href='#intent'&gt;Intent (aka, what do you want out of your blog?)&lt;/a&gt;&lt;/h2&gt; 
I have learnt the hard way, that the only way I can write better posts, is by writing [*lots* of crappy ones][crap]. 
I started a static website in the early oughts, then had a blogger blog, then a tumblr blog, then a self hosted wordpress blog, and then a self hosted ghost blog and now this self hosted [nikola blog][nb]. 
I sweated over the spacing. 
I fretted over which blog engine was best and most performant. 
I wondered about which ones protected privacy best. 
I had flame wars over which language was the best one to create a blog in, what sites were the best hosts, what frameworks would work better and how static blogs were so much faster than dynamic blogs but dynamic blogs offered so much power and flexibility. (all while I did not know how to write a single line of code.) 
I designed my blogs the way I wanted them, I bought premium themes, I bought fancy text editors and then figured out how I would write and where I would share them. I was all set. 
&lt;p&gt;And then? … zip, nada, nothing.&lt;br&gt;
The blogs just languished.&lt;/p&gt;
&lt;p&gt;This current incarnation of the blog is the only one that I have stuck with and written &lt;a href="https://janusworx.com/archive.html" target="_blank" rel="noreferrer"&gt;lots&lt;/a&gt; on.&lt;br&gt;
Every one of those previous attempts just withered on the vine.&lt;br&gt;
And not for lack of good intentions.&lt;br&gt;
I was always going to write that perfect post.&lt;br&gt;
I was waiting for more data, so that the post would be complete.&lt;br&gt;
I was researching for depth, because this subject was not just a post. It was a whole series.&lt;br&gt;
I never got around to actually writing though.&lt;br&gt;
It was lack of focus. &lt;a href="https://janusworx.com/blog/on-intention/" target="_blank" rel="noreferrer"&gt;Lack of intent&lt;/a&gt;.&lt;br&gt;
Think about why you are starting the blog and what do you want on there?&lt;br&gt;
And that will give you direction about what to write.&lt;br&gt;
You might realise that you don’t want to write, and just play with technology.&lt;br&gt;
That is fair too. At least you’re being intentional about it.&lt;/p&gt;
&lt;h2 id='write'&gt;&lt;a href='#write'&gt;Begin Writing!&lt;/a&gt;&lt;/h2&gt;
If you have never written before, my advice to you is 
&lt;ul&gt;
&lt;li&gt;to do precisely 1 hour of research, into all the free, hosted blog engines that are out there. Off the top of my head, &lt;a href="https://write.as/start" target="_blank" rel="noreferrer"&gt;Write.as&lt;/a&gt;, &lt;a href="https://www.netlify.com/" target="_blank" rel="noreferrer"&gt;Netlify&lt;/a&gt;, &lt;a href="https://www.tumblr.com/register" target="_blank" rel="noreferrer"&gt;Tumblr&lt;/a&gt;, &lt;a href="https://wordpress.com/start/" target="_blank" rel="noreferrer"&gt;Wordpress&lt;/a&gt;, and &lt;a href="https://medium.com/m/signin" target="_blank" rel="noreferrer"&gt;Medium&lt;/a&gt; come to mind.&lt;/li&gt;
&lt;li&gt;make dummy blogs and explore all their features over the next day or two (at most). Figure out what interface you are most comfortable with.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Begin Writing.&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I cannot stress this enough.&lt;br&gt;
You will never write perfect posts.&lt;br&gt;
How do I know?&lt;br&gt;
Because I tried so hard, for so many years.&lt;br&gt;
And failed.&lt;/p&gt;
&lt;p&gt;What you can do, is show up on the first day.&lt;br&gt;
Publicly commit to writing everyday.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;br&gt;
And write.&lt;br&gt;
Everyday.&lt;br&gt;
Good.&lt;br&gt;
Bad.&lt;br&gt;
Ugly.&lt;br&gt;
Whatever.&lt;br&gt;
Just put words on the page.&lt;/p&gt;
&lt;p&gt;The only two things that’d probably matter are,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;That you show up on the time you committed to&lt;/li&gt;
&lt;li&gt;And if your blog needs a general direction in the long run, you kinda sorta write your posts in that general direction.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Even that is a pretty distant second though.&lt;br&gt;
First, master showing up daily.&lt;br&gt;
Build that discipline.&lt;/p&gt;
&lt;h2 id='tools'&gt;&lt;a href='#tools'&gt;Tools of the trade&lt;/a&gt;&lt;/h2&gt; 
Caveat, don’t even *think* about reading this section, if you have not written close to a hundred posts on a regular schedule first. 
You need that muscle built strong. 
The rest as they say, is window dressing. 
Once you have written a couple of hundred posts, you get a pretty good handle on what it is that you are writing and what it is, that the blog needs to do to serve that purpose. 
I can tell you why I did, what I did with my blog. 
It might help you build yours? I don’t really know. 
But honestly, once you get on with writing, you will figure out most of this stuff or know someone who does, or understand that maintaining the status quo is good enough, until you can afford to pay for a hosted vendor, who does this all for you. 
&lt;p&gt;I used Wordpress for a long time and loved it.&lt;br&gt;
Then I thought I wanted to control it all, and so I hosted Wordpress on my own site.&lt;br&gt;
Then I actually understood, what a headache maintaining it all really is.&lt;br&gt;
Then I looked for something simpler.&lt;br&gt;
I backed the &lt;a href="https://www.kickstarter.com/projects/johnonolan/ghost-just-a-blogging-platform" target="_blank" rel="noreferrer"&gt;Ghost kickstarter&lt;/a&gt; and as soon as they released it, I began using it.&lt;br&gt;
It served my needs really well, until they decided to go in a different direction and abandon what I loved most about it. Writing in markdown. (I had written enough, to realise that any blog engine that I would use, needed to support Markdown.)&lt;/p&gt;
&lt;p&gt;And by then, like I said, I had written enough to know what I wanted out of a blog.&lt;br&gt;
I was writing for myself, so I did not want comments.&lt;br&gt;
That eliminating comments also got rid of moderating people and spam was just a bonus.&lt;br&gt;
If I wanted, I could actually go spread my message seperately. (the fediverse, email newsletters, social media networks and all that jazz.) But that is an intentional step. Separate from my act of writing.&lt;br&gt;
I mostly wrote words. So I needed something that would have pretty text.&lt;br&gt;
And since it was mostly just text, I could get by with a bunch of Markdown files rendered into static html files.&lt;br&gt;
I did not want to upgrade and patch and maintain a blog engine some place.&lt;br&gt;
I wanted something I could either host on my own server or just on some site somewhere else.&lt;br&gt;
This would be easier once again if it was just a bunch of files that needed to be placed somewhere.&lt;br&gt;
I wanted the ability to write from anywhere.&lt;br&gt;
And finally I wanted a measure of control over where all this was.&lt;/p&gt;
&lt;p&gt;All these considerations led me to realise …&lt;br&gt;
A static blog, with a pretty looking theme would address both my bunch of files requirement and my show words well requirement.&lt;br&gt;
There were tons of fonts that I could use. So I chose one that was &lt;a href="https://practicaltypography.com/charter.html" target="_blank" rel="noreferrer"&gt;free to use and I could host myself&lt;/a&gt;.&lt;br&gt;
Not just hosting fonts, right now I can afford to host the site myself, so I have a Linode that hosts this blog.&lt;br&gt;
The static blog can just as easily be hosted on some free place like github.io if life takes a turn for the worse.&lt;br&gt;
I was learning Python, so using a static site generator that supports markdown and was built in Python seemed logical. So I picked &lt;a href="https://getnikola.com/" target="_blank" rel="noreferrer"&gt;Nikola&lt;/a&gt;.&lt;br&gt;
(Did not really matter in the long run. I have used Go based Hugo, and Ruby based Jekyll too and all of them work essentially the same way. Even the theme I use on the blog, &lt;a href="https://themes.getnikola.com/v7/lanyon/" target="_blank" rel="noreferrer"&gt;Lanyon&lt;/a&gt;, is originally a &lt;a href="https://lanyon.getpoole.com/" target="_blank" rel="noreferrer"&gt;Jekyll theme&lt;/a&gt;, and can be found in &lt;a href="https://themes.gohugo.io/lanyon/" target="_blank" rel="noreferrer"&gt;Hugo&lt;/a&gt; as well).&lt;br&gt;
So I learnt how to install it on my desktop, and customise it to use the fonts I wanted in the weights I wanted.&lt;br&gt;
Then I learnt how to automatically deploy it via ssh to my site.
Most static site engines offer to automatically deploy to github.io or are available as hosted services on Netlify. Here’s &lt;a href="https://youtu.be/7Yg6HbwdRro" target="_blank" rel="noreferrer"&gt;Nikola on Github/Netlify&lt;/a&gt;.&lt;br&gt;
And finally, I’ve always wanted everything to be under my name, ergo the domain which I saved up for and bought.&lt;br&gt;
It’s not essential to your writing, but probably essential to your identity in the long run, so that might be something to consider too.&lt;/p&gt;
&lt;p&gt;So there we are.&lt;br&gt;
One more post done :)&lt;br&gt;
If you have questions, mail me! (jason at this domain)&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;small&gt;or to a schedule that you are comfortable with and publicly commit to.&lt;/small&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>Consolidating Websites</title><link>https://janusworx.com/work/consolidating-websites/</link><pubDate>Fri, 15 Jan 2021 09:00:00 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/consolidating-websites/</guid><description>&lt;small&gt;
*Update: 15/01/2021. 
It’s done. 
I moved everything and it all seems to be working. 
If something is broken, let me know, on [the fediverse][cbj], or mailing me at jason at this domain. 
To my tech posse, no there is no forwarding of old links happening. The site is too small and I have no time. Nobody is going to miss this. 
And to that one little friend, who noticed that the site was dead and actually cried, I love you.* 
&lt;/small&gt; 
&lt;!-- TEASER_END --&gt; 
&lt;hr style="margin-left: auto; margin-right: auto;margin-bottom: 40px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238); height: 1px;" /&gt; 
&lt;p&gt;Happy New Year and welcome to the first newsletter of the year :)&lt;/p&gt;
&lt;p&gt;I’m starting the year with a bit of spring cleaning.&lt;br&gt;
I decided to stop publishing to mjbraganza.com&lt;br&gt;
Yes, the book review and the photo website is now gone.&lt;br&gt;
I had started it to give my family and friends the option where they did not have to see me work rants and struggles.&lt;/p&gt;
&lt;p&gt;A few years of doing this have taught me that they don’t mind it anyway. They don’t check it on their own anyway. The newsletter is where the magic happens for family &amp;amp; friends.&lt;/p&gt;
&lt;p&gt;Which left me the unwanted, detested task of having to run two websites, maintain two sets of data and run two newsletter like things.&lt;br&gt;
I also have goals (my health, my family, my professional life) that I need to focus on, which leave me very little time to do these (even though I enjoy it immensely).&lt;br&gt;
So, I’ve decided to stop doing it.&lt;br&gt;
Like &lt;a href="https://www.calnewport.com/blog/2020/04/03/on-productivity-part-3/" target="_blank" rel="noreferrer"&gt;Cal Newport says&lt;/a&gt;,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do less&lt;/li&gt;
&lt;li&gt;Do Better&lt;/li&gt;
&lt;li&gt;Know why&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com" target="_blank" rel="noreferrer"&gt;janusworx.com&lt;/a&gt; is where home is, for the forseeable future.&lt;br&gt;
If you are looking for the old stuff, I will be bringing it over here, slowly as time and energy allow.&lt;br&gt;
&lt;br&gt;
And once again, I wish you and yours a very Happy New Year!&lt;/p&gt;</description></item><item><title>My Plan for the New Year</title><link>https://janusworx.com/personal/my-plan-for-the-new-year/</link><pubDate>Fri, 01 Jan 2021 12:15:12 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/personal/my-plan-for-the-new-year/</guid><description>&lt;p&gt;My plan for the new year …&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 
&lt;blockquote&gt;&lt;p&gt;A final thought from Atomic Habits as we start the new year:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“Improvements are only temporary until they become part of who you are.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The goal is not to read a book, the goal is to become a reader.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The goal is not to run a marathon, the goal is to become a runner.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The goal is not to learn an instrument, the goal is to become a musician.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;This year, focus on the identity you want to build.”&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;— &lt;a href="https://jamesclear.com/3-2-1/december-31-2020?rh_ref=e1cbd323" target="_blank" rel="noreferrer"&gt;James Clear&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Day of Updates</title><link>https://janusworx.com/work/a-day-of-updates/</link><pubDate>Mon, 16 Nov 2020 18:08:36 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-day-of-updates/</guid><description>&lt;p&gt;Could not focus much on programming today.&lt;br&gt;
So decided on &lt;em&gt;doing&lt;/em&gt; things with Python programs.&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h3 class="relative group"&gt;Nikola Upgrade
 &lt;div id="nikola-upgrade" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#nikola-upgrade" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;I use &lt;a href="https://www.getnikola.com/" target="_blank" rel="noreferrer"&gt;Nikola&lt;/a&gt; to generate both my websites.&lt;br&gt;
It is an extremely easy to use, no fuss static site generator, which is easy on my server’s resources.&lt;br&gt;
&lt;a href="https://github.com/getnikola/nikola/releases/tag/v8.1.2" target="_blank" rel="noreferrer"&gt;Version 8.1.2&lt;/a&gt; was released a few hours ago and I hopped on and installed it.&lt;br&gt;
I follow a slightly unconventional upgrade path, because I was terrified of breaking my server in the early days, when I was still learning about how to go about installing things on servers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I have &lt;a href="https://docs.conda.io/en/latest/miniconda.html" target="_blank" rel="noreferrer"&gt;Miniconda&lt;/a&gt; installed.&lt;/li&gt;
&lt;li&gt;I use that to generate a conda environment, which I then installed Nikola into.&lt;/li&gt;
&lt;li&gt;When a new release drops, I create a &lt;em&gt;new&lt;/em&gt; conda environment, install the new release in there and run them against my source folders (after backing them up).&lt;/li&gt;
&lt;li&gt;This lets me revert very quickly to the old data and the older version of Nikola, in case I do something boneheaded and screw things up.&lt;/li&gt;
&lt;li&gt;If all works fine for a month, I delete the older conda environment along with the old Nikola release.&lt;/li&gt;
&lt;li&gt;I have been doing this for quite a while now, and while it may be overkill, it gives me peace of mind.&lt;/li&gt;
&lt;li&gt;As usual, Nikola upgraded with no issues at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;Pleroma Bot
 &lt;div id="pleroma-bot" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#pleroma-bot" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;I always wanted to understand what bots do.&lt;br&gt;
Now I realise they are athromorphic programs that (with the right permissions and the right credentials) look like actual users of a service, doing sets of activities they are programmed to do.&lt;br&gt;
Like your banking app has set of solutions to common queries that it shows you, before it hands off to an actual human, if those solutions don’t fit your needs.&lt;br&gt;
They feel like supercharged scripts to me.&lt;br&gt;
So I decided to see if I could install one.&lt;br&gt;
Since I am learning Python, I love reading the low volume &lt;a href="https://twitter.com/python_tip" target="_blank" rel="noreferrer"&gt;Daily Python Tip&lt;/a&gt; Twitter account.&lt;br&gt;
It has surprising, handy, funny, interesting tips and tricks about the Python language and the massive ecosystem around it.&lt;br&gt;
&lt;em&gt;But,&lt;/em&gt; I have weaned myself off Twitter for my own sanity.&lt;br&gt;
I only use it sparingly once a day.&lt;br&gt;
And going back to that noise and tumult no longer interests me.&lt;br&gt;
I saw &lt;a href="https://mastodon.social/@newsbot" target="_blank" rel="noreferrer"&gt;a bot&lt;/a&gt; that mirrored tech news accounts to Mastodon and wondered if a bot could get Daily Python Tip to me on my Pleroma timeline.&lt;br&gt;
A quick search led me to &lt;a href="https://github.com/robertoszek/pleroma-twitter-info-grabber" target="_blank" rel="noreferrer"&gt;Pleroma Bot&lt;/a&gt;.&lt;br&gt;
A couple of struggling hours later, (creating a twitter developer account, creating a pleroma account for the bot, figuring out how to get bearer tokens for said accounts) and tada, I got the &lt;a href="https://cb.janusworx.com/@ptjwbot" target="_blank" rel="noreferrer"&gt;bot to come alive!&lt;/a&gt;&lt;br&gt;
It checks the Twitter account once a day, and mirrors the tweets to the bot account.&lt;br&gt;
You’re most welcome to follow it for a Python tip, daily.&lt;br&gt;
The next thing to do, is to see if I can get a bot to post a tagged pleroma status to my twitter account.&lt;br&gt;
But that is something for another day …&lt;br&gt;
&lt;em&gt;Update, 2020/11/17: figured out how to use the bot to mirror multiple accounts. It now mirrors, &lt;a href="https://twitter.com/python_tip" target="_blank" rel="noreferrer"&gt;Daily Python Tip&lt;/a&gt;, &lt;a href="https://twitter.com/regextip" target="_blank" rel="noreferrer"&gt;RegexTip&lt;/a&gt;, and &lt;a href="https://twitter.com/compscifact" target="_blank" rel="noreferrer"&gt;CompSciFact&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Git the Branch</title><link>https://janusworx.com/work/git-the-branch/</link><pubDate>Fri, 13 Nov 2020 18:55:00 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/git-the-branch/</guid><description>&lt;p&gt;I started playing with a way to control &lt;a href="https://janusworx.com/blog/starting-work-on-git-the-branch/" target="_blank" rel="noreferrer"&gt;Git via Python&lt;/a&gt;.&lt;br&gt;
Kushal had asked me to write a program, that would show me the local git branches.&lt;br&gt;
So here it is!&lt;br&gt;
I call it &lt;em&gt;&lt;strong&gt;Git the Branch&lt;/strong&gt;&lt;/em&gt;. (painfully, punny, I know :))&lt;/p&gt;
&lt;p&gt;And now I realise why he asked me to do this.&lt;br&gt;
The program itself is trivial.&lt;br&gt;
Here’s the code on my &lt;a href="https://cr.janusworx.com/jason/git-the-branch" target="_blank" rel="noreferrer"&gt;code repo&lt;/a&gt;, &lt;a href="https://gitlab.com/jasonbraganza/git-the-branch" target="_blank" rel="noreferrer"&gt;Gitlab&lt;/a&gt;, and &lt;a href="https://github.com/jasonbraganza/git-the-branch" target="_blank" rel="noreferrer"&gt;Github&lt;/a&gt;.&lt;br&gt;
It just consists of me using &lt;a href="https://gitpython.readthedocs.io/en/stable/" target="_blank" rel="noreferrer"&gt;GitPython&lt;/a&gt; to access the current folder via a GitPython &lt;code&gt;Repo&lt;/code&gt; object.&lt;br&gt;
And then querying it for its branches.&lt;/p&gt;
&lt;p&gt;The important work was done &lt;em&gt;yesterday&lt;/em&gt;, when I pored over the documentation and figured out how GitPython actually works.&lt;br&gt;
And I realised that is what Kushal wanted me to do.&lt;br&gt;
Read something and figure out how I could adapt it to my situation.&lt;/p&gt;
&lt;p&gt;The other thing I realised, was licensing.&lt;br&gt;
I want my programs to be used, played with and adapted.&lt;br&gt;
So it makes sense for me, to make it as easy to use as possible.&lt;br&gt;
This is why I have decided, that until circumstances dictate otherwise, I shall use the &lt;a href="https://choosealicense.com/licenses/mit/" target="_blank" rel="noreferrer"&gt;MIT License&lt;/a&gt;.&lt;br&gt;
This led me to check if I could then actually license my software as such, if the software that I depend on (in this case GitPython) have different licenses.&lt;br&gt;
My arbitrary and random research suggests that I can do so.&lt;br&gt;
If I learn otherwise, I shall think about what to do next.&lt;br&gt;
If you have anything to suggest, please let me know, by mailing me at jason at this domain.&lt;/p&gt;
&lt;p&gt;One other (painful) thing, that I realised is that I cannot focus at all when I am writing code.&lt;br&gt;
This post has come out in a blur of focussed writing.&lt;br&gt;
My academic studies are also something that I can focus for hours on.&lt;br&gt;
Apparently that focus does not translate to programming.&lt;br&gt;
I need to build up this skill for this domain seperately.&lt;br&gt;
Hopefully, this will come with showing up daily.&lt;/p&gt;
&lt;p&gt;This was fun to do.&lt;br&gt;
Here’s to writing my way to fluency.&lt;/p&gt;
&lt;p&gt;P.S. Subscribe to my &lt;a href="https://janusworx.com/subscribe/" &gt;mailing list&lt;/a&gt;!&lt;br&gt;
P.P.S. Feed my &lt;a href="https://www.amazon.in/hz/wishlist/ls/2QAUKHHAMOOVS?ref_=wl_share" target="_blank" rel="noreferrer"&gt;insatiable reading habit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;P.P.P.S. &lt;em&gt;Update, 7pm the same day,&lt;/em&gt; The answer to focus, lies in &lt;a href="https://seths.blog/2020/11/the-incoming/" target="_blank" rel="noreferrer"&gt;this serendipitous Seth post&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;A third might be, just for an hour, to turn it off.&lt;br&gt;
All of it.&lt;br&gt;
To sit alone and create the new thing, the thing worth seeking out, the thing that will cause a positive change.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;I love it when the universe speaks to me :)&lt;/p&gt;</description></item><item><title>Poem Feed</title><link>https://janusworx.com/personal/poem-feed/</link><pubDate>Fri, 13 Nov 2020 17:00:00 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/personal/poem-feed/</guid><description>&lt;p&gt;&lt;em&gt;Update, 2020/11/13: This has been working beautifully! I love the poems as they show up in my feed.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is a tiny little niche thing, I built all for my ownsome.&lt;br&gt;
It all &lt;a href="https://janusworx.com/blog/a-hundred-days-of-code-day-029/" target="_blank" rel="noreferrer"&gt;started&lt;/a&gt;, when I got hooked on reading the daily poem, on the Poetry Foundation page.&lt;/p&gt;
&lt;p&gt;Learning Python as I am, I wondered if there was a way to have it come to my RSS reader.&lt;br&gt;
And so &lt;a href="https://cr.janusworx.com/jason/poemfeed/src/branch/main/poemfeed.py" target="_blank" rel="noreferrer"&gt;Poemfeed&lt;/a&gt; is a tiny little utility that does just that for me.&lt;/p&gt;
&lt;p&gt;It looks up Poetry Foundation’s, &lt;a href="https://www.poetryfoundation.org/poems/poem-of-the-day" target="_blank" rel="noreferrer"&gt;Poem of the Day&lt;/a&gt; for a new poem.&lt;br&gt;
If there is one, it follows the link to the complete poem, and then gets the link to &lt;em&gt;that&lt;/em&gt; page and writes that into an simple RSS entry in an xml file.&lt;/p&gt;
&lt;p&gt;I then wrote a simple cron job that executes the python script twice a day, and if an xml file is generated, it moves it to a place that my RSS reader can access.&lt;br&gt;
Et voilà, a brand new poem everyday! (or as often as they publish :))&lt;/p&gt;
&lt;p&gt;The code’s here, on &lt;a href="https://cr.janusworx.com/jason/poemfeed/src/branch/main/poemfeed.py" target="_blank" rel="noreferrer"&gt;my repo&lt;/a&gt;, on &lt;a href="https://gitlab.com/jasonbraganza/poemfeed/-/blob/main/poemfeed.py" target="_blank" rel="noreferrer"&gt;Gitlab&lt;/a&gt; and on &lt;a href="https://github.com/jasonbraganza/poemfeed/blob/main/poemfeed.py" target="_blank" rel="noreferrer"&gt;Github&lt;/a&gt;, if you want to have a look see.&lt;/p&gt;</description></item><item><title>Starting Work on Git-the-Branch</title><link>https://janusworx.com/work/starting-work-on-git-the-branch/</link><pubDate>Thu, 12 Nov 2020 15:16:12 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/starting-work-on-git-the-branch/</guid><description>
&lt;h3 class="relative group"&gt;The Itch
 &lt;div id="the-itch" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-itch" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;Aiming to write a tool using this which will show all the git branches in the current directory and the last commit date on those branches (and only the local branches :))&lt;/p&gt;

&lt;h3 class="relative group"&gt;What I did today
 &lt;div id="what-i-did-today" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#what-i-did-today" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;I had to carry my phone in to the service centre, so I did not quite have as much focussed time as yesterday, with all the coordinating and carrying, but I learned a few new things&lt;/p&gt;
&lt;p&gt;&lt;a href="https://kushaldas.in/" target="_blank" rel="noreferrer"&gt;Kushal&lt;/a&gt; hinted that I could use &lt;a href="https://gitpython.readthedocs.io/en/stable/index.html" target="_blank" rel="noreferrer"&gt;GitPython&lt;/a&gt; to do what I want.&lt;br&gt;
So I spent a little while reading there.&lt;br&gt;
And then decided to test it out.&lt;/p&gt;
&lt;p&gt;And then immediately went yak shaving, because I wanted to solve the problem of how to quickly type iterate in Visual Studio Code.&lt;br&gt;
I learnt &lt;a href="https://janusworx.com/tags/pythonoop/" &gt;lots of Python&lt;/a&gt; using &lt;a href="https://store.lerner.co.il/" target="_blank" rel="noreferrer"&gt;Reuven Lerner&lt;/a&gt;’s courses and I used a lot of &lt;a href="https://jupyter.org/" target="_blank" rel="noreferrer"&gt;Jupyter Notebooks&lt;/a&gt; then.&lt;br&gt;
And I love them.&lt;br&gt;
The trick now, is to figure out how to use them in Visual Studio Code.&lt;br&gt;
To my delight, the Python extension in VS Code has support for notebooks. And all works well for the most part.&lt;br&gt;
The only thing that tripped me up was that when I tried importing a module in the notebook after activating my virtual environment, the Jupyter server hiccoughed and threw up some error about not finding the module (which I knew was &lt;em&gt;definitely&lt;/em&gt; installed) and then something about it not being in the PYTHONPATH (which I had no clue of which places, it was looking in.)&lt;br&gt;
A little snooping and I realised that the extension loads the server with a default kernel in someplace. And I need to tell it about my environment. Once I told it to use the kernel from my venv, all was fine.&lt;br&gt;
VS Code went and installed a ton of things and found what was already there and everything was hunky dory.&lt;br&gt;
A &lt;code&gt;from git import Repo&lt;/code&gt; worked just fine.&lt;/p&gt;
&lt;p&gt;I felt good about this piece of dawdling, because I know this is something I am going to do every day and better I spend &lt;em&gt;some&lt;/em&gt; time figuring it out, right at the start.&lt;/p&gt;
&lt;p&gt;I learnt that I could use the ! mark as a prefix in Jupyter to run shell commands! A &lt;code&gt;!ls&lt;/code&gt; will show me the contents of my folder :)&lt;/p&gt;
&lt;p&gt;I skimmed the GitPython documentation.&lt;br&gt;
I kind of got what I want.&lt;br&gt;
This will require lots more work, which I shall have to put in.&lt;br&gt;
But even a cursory glance, showed me that GitPython was an &lt;em&gt;exhaustive&lt;/em&gt; wrapper, that would let you do practically anything you would want to do with Git.&lt;/p&gt;
&lt;p&gt;More tomorrow …&lt;/p&gt;</description></item><item><title>A Good First Day</title><link>https://janusworx.com/work/a-good-first-day/</link><pubDate>Wed, 11 Nov 2020 19:05:10 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-good-first-day/</guid><description>&lt;p&gt;Was a really good day to ease back into Python today.&lt;br&gt;
I got my VS Code up and running.&lt;br&gt;
I got a personal [Gitea instance][crjw] up, to host my code, from where I will syndicate it to Github and Gitlab.&lt;br&gt;
And finally I got a &lt;a href="https://janusworx.com/programming-projects/" target="_blank" rel="noreferrer"&gt;projects page&lt;/a&gt; up, to slowly fill up with projects.&lt;/p&gt;
&lt;p&gt;I also managed to improve an old program I wrote for myself, but I’ll write about that in the next post.&lt;br&gt;
All in all, a day well spent. A journey well begun.&lt;/p&gt;</description></item><item><title>Getting Back on the Horse</title><link>https://janusworx.com/personal/getting-back-on-the-horse/</link><pubDate>Wed, 11 Nov 2020 09:49:28 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/personal/getting-back-on-the-horse/</guid><description>&lt;p&gt;Ok, one more time.&lt;br&gt;
I know there have been &lt;a href="https://janusworx.com/blog/a-hundred-days-of-code-day-000-begin-again/" target="_blank" rel="noreferrer"&gt;lots of one more times&lt;/a&gt; before, but I am going to keep at this until I get proficient enough at this to land a job :)&lt;br&gt;
And while I may not be brainy enough, the one thing I &lt;em&gt;can&lt;/em&gt; do is be persistent enough to show up.&lt;/p&gt;
&lt;p&gt;This time, I will focus on building tiny projects.&lt;br&gt;
I realise my life is too chaotic for &lt;a href="https://janusworx.com/tags/100daysofcode/" &gt;#100DaysofCode&lt;/a&gt;.&lt;br&gt;
But I can do this, one tiny thing at a time.&lt;/p&gt;
&lt;p&gt;Wish me luck!&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 026 - Refactoring</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-026-refactoring/</link><pubDate>Mon, 03 Aug 2020 13:00:03 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-026-refactoring/</guid><description>&lt;p&gt;Worked only an hour today.&lt;br&gt;
Trying to change the little &lt;a href="https://janusworx.com/blog/a-hundred-days-of-code-day-023-day-24-tiny-utility-to-do-comparative-dns-lookups/" target="_blank" rel="noreferrer"&gt;lookup program&lt;/a&gt;, I made the other day, into something a little better.&lt;/p&gt;
&lt;p&gt;Not quite a good day.&lt;br&gt;
Calling it quits early.&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 025 - Comprehension Exercises</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-025-comprehension-exercises/</link><pubDate>Mon, 03 Aug 2020 12:57:20 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-025-comprehension-exercises/</guid><description>&lt;p&gt;Working on Comprehension exercises today.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Reflections and Experience
 &lt;div id="reflections-and-experience" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#reflections-and-experience" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;!-- TEASER_END --&gt; 
&lt;ul&gt;
&lt;li&gt;I really need feedback, when it comes to programming. I cannot face a blank page. I always seem to start with printing something out to screen and then my brain kind of kicks into gear. Everything after that is just type, print, is this what I expected, if not then fix, type, print …&lt;/li&gt;
&lt;li&gt;Exercise 3.1 and I think, I am &lt;em&gt;finally&lt;/em&gt; getting good handle on comprehensions.
&lt;ul&gt;
&lt;li&gt;from something that would take me at least 10 lines of code to just expressing it concisely in 1!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I can read Python messages and take a gander at what I need to do next.
&lt;ul&gt;
&lt;li&gt;I see a &lt;code&gt;'_io.TextIOWrapper' object&lt;/code&gt; and know I can iterate over it.&lt;/li&gt;
&lt;li&gt;I see &lt;code&gt;AttributeError: '_io.TextIOWrapper' object has no attribute 'strip'&lt;/code&gt; and realise that it cannot be stripped into parts. I need another way to skin that cat.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;And then I took it too far (just like this sentence), and nested a comprehension in another one, in where, I had to learn how to put in a conditional in the form of a ternary operator, in Exercise 3.2 (the commented for loop is much simpler!), but that was &lt;em&gt;very good&lt;/em&gt; practice. Really stretched me!&lt;/li&gt;
&lt;li&gt;I caught myself getting distracted a lot. I needed to set a 30 min timer and I spent about 15, looking for where the timer app in my Mint Desktop was, instead of just setting the darned timer on the phone.&lt;/li&gt;
&lt;li&gt;Took an hour to figure out the comprehension for 3.2 and about 20 minutes to do it for Exercise 3.3. Practice helps!&lt;/li&gt;
&lt;li&gt;Watching the solutions, and I realise, I got them right in principle, but that I need to be more aware of what happens to an object in memory, so that I can simplify code. I was able to remove one level of comprehension, which I used just to get the end of a string.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>A Hundred Days of Code, Day 023, Day 24 - Tiny Utility to do comparative DNS Lookups</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-023-day-24-tiny-utility-to-do-comparative-dns-lookups/</link><pubDate>Sat, 01 Aug 2020 15:33:22 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-023-day-24-tiny-utility-to-do-comparative-dns-lookups/</guid><description>
&lt;h2 class="relative group"&gt;Problem - Compare domain lookups, against DoH Servers
 &lt;div id="problem---compare-domain-lookups-against-doh-servers" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#problem---compare-domain-lookups-against-doh-servers" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Take a list of domains (one per line) from a text file as input, find the IP address for the domain using the standard system level DNS, and then check against DoH answers from both cloudflare and google. and say if all answers match properly or not.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- TEASER_END --&gt;

&lt;h2 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;What do I need to do? (checklist)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Get a list of popular websites, (probably Alexa)&lt;/li&gt;
&lt;li&gt;figure out a way to read them in&lt;/li&gt;
&lt;li&gt;loop through each line, and look up its ip
&lt;ul&gt;
&lt;li&gt;with the local dns (use the sockets module)&lt;/li&gt;
&lt;li&gt;with Google’s &lt;a href="https://developers.google.com/speed/public-dns/docs/doh/json" target="_blank" rel="noreferrer"&gt;DoH json endpoint&lt;/a&gt; (use the requests module)&lt;/li&gt;
&lt;li&gt;with Cloudflare’s &lt;a href="https://developers.cloudflare.com/1.1.1.1/dns-over-https/json-format/" target="_blank" rel="noreferrer"&gt;DoH json endpoint&lt;/a&gt; (ditto like Google)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Compare all the values.&lt;/li&gt;
&lt;li&gt;Print if they match or not.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;Experience
 &lt;div id="experience" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#experience" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;I should commit my work often. This took me two days, because I lost all of yesterday’s progress in a computer hiccough.&lt;/li&gt;
&lt;li&gt;The program runs well. It intentionally limits itself to only the first result in the Google and Cloudflare lookups.&lt;/li&gt;
&lt;li&gt;I should learn to focus more on what is at hand and not overthink the program.&lt;/li&gt;
&lt;li&gt;I should be learning to build primitive little, handy dandy tools, not giant cathedrals.&lt;/li&gt;
&lt;li&gt;I spent two hours fiddling with a way to create &lt;em&gt;another&lt;/em&gt; program that would process files for me. (and abandoned it)&lt;/li&gt;
&lt;li&gt;I need to read the documentation across sites &lt;em&gt;very carefully&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;They are written with experienced programmers in mind, and not beginners like me.&lt;/li&gt;
&lt;li&gt;For e.g. When I was trying to look up domain names with Cloudflare, I blindly copied the example and then wondered why it was not giving me the appropriate replies. I then realised I was missing a seperate parameter, &lt;code&gt;&amp;amp;ct=application/dns-json&lt;/code&gt; which was quite clearly listed above, but not in the example below. (which in truth &lt;em&gt;was&lt;/em&gt; listed, but as part of the command at the command line and I, like a dumbass, just copied the requisite code to adapt to my Python program. &lt;em&gt;Lesson: Cargo cult with extreme caution&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Which leads back to the fact, that I should stick to what is assigned, because just doing that much at this stage is taking me a long time. Improvements and features can wait until I am much more fluent.&lt;/li&gt;
&lt;li&gt;I realise I am trusting autocomplete too much, and I should at least &lt;em&gt;look&lt;/em&gt; at what I am completing. I spent 40 minutes, wondering why my comparisons were not working, when in fact, I was using the wrong variables.&lt;/li&gt;
&lt;li&gt;Lost loads of time with typos.&lt;/li&gt;
&lt;li&gt;Be more intentional. More slow.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;Code.
 &lt;div id="code" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#code" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Put your sitenames into a file called dumpsites.txt
Run check-ip.py&lt;/p&gt;
&lt;p&gt;&lt;a href="https://gitlab.com/jasonbraganza/programming-practice/-/tree/master/check-ip" target="_blank" rel="noreferrer"&gt;Gitlab&lt;/a&gt; / &lt;a href="https://github.com/jasonbraganza/programming-practice/tree/master/check-ip" target="_blank" rel="noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 022 - Getting into the Groove</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-022-getting-into-the-groove/</link><pubDate>Thu, 30 Jul 2020 12:03:45 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-022-getting-into-the-groove/</guid><description>&lt;p&gt;Did the same time as yesterday.&lt;br&gt;
Only about an hour.&lt;br&gt;
Was much more prodcutive though.&lt;/p&gt;
&lt;p&gt;Getting the hang of how to sit and program and work through things I do not know.&lt;br&gt;
Gaining a bit of experience with the workflow now.&lt;br&gt;
I have the basics in hand. I know what I want to look up.&lt;br&gt;
So check problem, work a bit, look up, try, fail, repeat, gain incremental success, work some more.&lt;br&gt;
Love the feedback loop too.&lt;br&gt;
With other stuff I try, I have to wait days, weeks, months.&lt;br&gt;
Here, it’s immediate.&lt;/p&gt;
&lt;p&gt;Beginning to love the work, as I get more familiar with it.&lt;br&gt;
Tomorrow is another day :)&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 021 - Swing and a miss</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-021-swing-and-a-miss/</link><pubDate>Wed, 29 Jul 2020 18:06:35 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-021-swing-and-a-miss/</guid><description>&lt;p&gt;Only did about an hour of distracted work and exercises today.&lt;br&gt;
I’ll still count it though.&lt;/p&gt;
&lt;p&gt;Tomorrow is another day :)&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 020 - Setting up an Editor for Python Development</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-020-setting-up-an-editor-for-python-development/</link><pubDate>Tue, 28 Jul 2020 17:29:08 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-020-setting-up-an-editor-for-python-development/</guid><description>&lt;p&gt;Had given myself a day, to see if I could get a good Python development environment using Elpy and Emacs.&lt;br&gt;
It &lt;em&gt;does&lt;/em&gt; work.&lt;br&gt;
Just not well enough for me.&lt;br&gt;
At the end of the day today, I was happy I learnt so much about Emacs.&lt;br&gt;
But that is not my focus right now. Python is.&lt;br&gt;
Emacs knowledge can come slowly and organically.&lt;/p&gt;
&lt;p&gt;So I have kept Emacs as my regular editor for nearly everything text.&lt;br&gt;
And switched to the community edition of Pycharm for all my Python projects.&lt;/p&gt;
&lt;p&gt;I am also grateful to all of you, who gave me problems to practice on.&lt;br&gt;
These will help me grow.&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 019 - Future Exercise Addendum</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-019-future-exercise-addendum/</link><pubDate>Mon, 27 Jul 2020 16:23:14 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-019-future-exercise-addendum/</guid><description>&lt;p&gt;Ok, think I have the problem of writing code, licked.&lt;br&gt;
Will start with one problem from all the &lt;a href="http://store.lerner.co.il/" target="_blank" rel="noreferrer"&gt;Lerner Courses&lt;/a&gt;, that I still have to do.&lt;br&gt;
And another problem, I ask my friends to give me.&lt;/p&gt;
&lt;p&gt;This should prove for a promising start.&lt;br&gt;
If you, dear reader, have problems in Python that you’d like me, a budding Python programmer to solve, please mail them to me at jason at this domain.&lt;br&gt;
It’ll add to my pool of problems and give me plenty to practice.&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 019 - Python Iterators and Generators, Done!</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-019-python-iterators-and-generators-done/</link><pubDate>Mon, 27 Jul 2020 11:55:48 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-019-python-iterators-and-generators-done/</guid><description>&lt;p&gt;Starting up with the last of the &lt;a href="https://store.lerner.co.il/iterators-and-generators/" target="_blank" rel="noreferrer"&gt;Lerner courses&lt;/a&gt;, I got.&lt;br&gt;
Iterators and Generators.&lt;br&gt;
Hopefully I get done with this and use the same intensity with actually writing code.&lt;br&gt;
What shape will that take and how will I write about it? I have no clue&lt;br&gt;
For now, notes follow.&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h2 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;** Part 1, Iterators **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If we run the &lt;code&gt;iter&lt;/code&gt; function on something and it comes back with an iterator object, then it’s iterable; I can iterate on it.&lt;/li&gt;
&lt;li&gt;Behind scenes in a &lt;code&gt;for&lt;/code&gt; loop, Python does something similar. It asks if the object that has to be looped over is iterable with &lt;code&gt;iter&lt;/code&gt;. And then keeps doing &lt;code&gt;next&lt;/code&gt; with it to get the next result/item, until it comes across a &lt;code&gt;StopIteration&lt;/code&gt; which lets it know, that the values are exhausted and it can stop looping.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;for&lt;/code&gt; loop is a very thin shell, that asks the appropriate questions of the iterator. But it is always the iterator that determines, what exactly is returned.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;iterable vs iterator&lt;/strong&gt;&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;iterable&lt;/em&gt; means that it can be put into a “for” loop in Python
&lt;ul&gt;
&lt;li&gt;things like strings, lists, dictionaries, sets, files and objects (that I will soon create) that implement that iterator protocol.&lt;/li&gt;
&lt;li&gt;it responds positively to the &lt;code&gt;iter&lt;/code&gt; function’s question, Are you iterable? It returns an iterator object instead of raising errors (TypeErrors in this case)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;an &lt;em&gt;iterator&lt;/em&gt; is the object returned by the &lt;em&gt;iterable&lt;/em&gt;, the thing on which the &lt;code&gt;next&lt;/code&gt; function is run.
&lt;ul&gt;
&lt;li&gt;it could be the original object (the iterable) itself.&lt;/li&gt;
&lt;li&gt;it could also be a seperate object returned by the iterable.&lt;/li&gt;
&lt;li&gt;when the iterator object is exhausted, it returns &lt;code&gt;StopIteration&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;these are what give us the values.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;How do I make my objects iterable?
&lt;ul&gt;
&lt;li&gt;By implementing the iterator protocol
&lt;ul&gt;
&lt;li&gt;the object must respond to iter, by returning an iterator object&lt;/li&gt;
&lt;li&gt;it should respond to the next function with values&lt;/li&gt;
&lt;li&gt;it should raise a &lt;code&gt;StopIteration&lt;/code&gt; error, when it’s done.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Best to create a helper class, pass the data to it and return that as the iterator instance.
&lt;ul&gt;
&lt;li&gt;helps with state, since I can then use the same object and iterate over it multiple times independantly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;** Part 2, Generators **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating a whole class just to implement an iterator, might be overkill&lt;/li&gt;
&lt;li&gt;Generators are a solution, that might come in handy.&lt;/li&gt;
&lt;li&gt;They are like functions; functions that implement the iterator protocol.&lt;/li&gt;
&lt;li&gt;instead of using &lt;code&gt;return&lt;/code&gt;, we use &lt;code&gt;yield&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;this lets us return multiple items.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I can use them to chunk large items, buffer uncertain stuff, and wrap complex stuff.&lt;/li&gt;
&lt;li&gt;Rule of thumb,
&lt;ul&gt;
&lt;li&gt;if I already have a class, just added functionality to it using an iterator class.&lt;/li&gt;
&lt;li&gt;but if I need something standalone, just use a generator function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;** Part 3, Coroutines **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Little helper functions.
&lt;ul&gt;
&lt;li&gt;With such a function, I assign the &lt;code&gt;yield&lt;/code&gt; statment to a variable.&lt;/li&gt;
&lt;li&gt;This makes the function sit and wait for me to &lt;code&gt;send&lt;/code&gt; it something.&lt;/li&gt;
&lt;li&gt;Once it receives data, it ingests it, processes it and poops out, yields an answer :)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x = yield x&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Instead of sending data back to a coroutine with &lt;code&gt;send&lt;/code&gt;, I could send it an exception using &lt;code&gt;throw&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;I use &lt;code&gt;close&lt;/code&gt; to close the generator and break out (trap &lt;code&gt;GeneratorExit&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;I can just say &lt;code&gt;yield from some_generator&lt;/code&gt; if I am calling another generator from my generator.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;** Part 4, Generator Comprehensions **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create one just using () &lt;code&gt;genvar = (x*x for x in range(-5,5))&lt;/code&gt; will make genvar a generator object.&lt;/li&gt;
&lt;li&gt;The general idea, I am getting, behind the idea of generators and iterators is that we use them on really large objects, so that we don’t run out of memory.
&lt;ul&gt;
&lt;li&gt;for e.g. joining a list of 3 elements is easy-peasy. A list of 3 billion elements less so, and ergo, generators and iterators.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;the ultimate idea being, just like an oil pipeline. We ought not to store it in tanks (lists, dictionaries etc.) We ought to strive as much as possible that it flows from upstream, right through to our taps in a single unbroken stream. Just pass the oil along, using various t-junctions and pipes and motors and stuff. Keep it flowing. Minimise storage.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;it also spreads wait times across well, time. So I never have to wait for something to gather up and collect and then display. the generator comes back instantly and when it has to get a values, I just have to wait for that &lt;em&gt;one&lt;/em&gt; value.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;** Part 5, itertools **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;itertools is a collection of generators/iterators, that’ll let me add the iterator protocol to existing classes and functions. Looking through these feels like looking at specialty carpentry tools, like &lt;a href="https://www.youtube.com/watch?v=ZNd7I4OiOf8" target="_blank" rel="noreferrer"&gt;this biscuit joiner&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;lets me take advantage of other smarter folks’ work and optimisations
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;itertools.chain&lt;/code&gt; crawls elements across iterables&lt;/li&gt;
&lt;li&gt;&lt;code&gt;itertools.count&lt;/code&gt; counts upwards from a number given, in steps if we want.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;itertools.cycle&lt;/code&gt; cycles through a range of options&lt;/li&gt;
&lt;li&gt;&lt;code&gt;itertools.repeat&lt;/code&gt; repeats a value for the number of times, we tell it&lt;/li&gt;
&lt;li&gt;&lt;code&gt;itertools.filterfalse&lt;/code&gt; takes a iterable and a function, applies the function to the iterable and if the function returns false, only then is the element from the iterable, passed through. (the inverse in which only true elements are returned is a built-in in Python, aptly called &lt;code&gt;filter&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;itertools.takewhile&lt;/code&gt; and &lt;code&gt;itertools.dropwhile&lt;/code&gt; are opposites of each other
&lt;ul&gt;
&lt;li&gt;takewhile takes a function and a sequence, applies the function to the sequence (starts a &lt;code&gt;while&lt;/code&gt; loop) and then immediately stops if it hits false&lt;/li&gt;
&lt;li&gt;dropwhile inverts that. it starts a &lt;code&gt;while&lt;/code&gt; loop when it hits it’s first false and then keeps going from there.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;itertools.compress&lt;/code&gt; takes two iterables of equal length, (or if they are unequal, it’ll stop when it reaches the end of the shorter one) and then if the element second iterable rings true, it returns the element in the first one.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;itertools.accumulate&lt;/code&gt; adds the first element to the second element, then adds that the third element and so on. (if i want to use some other function of add, I can do that too)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;itertools.tee&lt;/code&gt; lets me create multiple instances of a generator, each with it’s own state (memory intensive.)&lt;/li&gt;
&lt;li&gt;permutations and combinations
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;itertools.product&lt;/code&gt; takes an element from one iterable, runs it across all the elements of the second (or third and fourth) and returns a cartesian product, an x,y (or x,y,z) coordinate tuple.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;itertools.permutations&lt;/code&gt; does permutations across two iterables. returns tuples.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;itertools.combinations&lt;/code&gt; does combinations.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;itertools.combinations_with_replacements&lt;/code&gt; does combinations allowing each element to repeat. (a combination might not allow (10, 10, 10) for example; this helps with that)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;more-itertools is an external package that gives me more complex itertools. (&lt;code&gt;pip install more-itertools&lt;/code&gt;) need to look at them later.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;Learning / Feedback/ Experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Reuven tells stories “Deep in the recesses of Python …”&lt;/li&gt;
&lt;li&gt;Reuven’s talking Python interpreter, “Hey Object, are you iterable?”&lt;/li&gt;
&lt;li&gt;I am slowly anticipating the problems in Reuven’s code as he keeps iterating on them.
&lt;ul&gt;
&lt;li&gt;‘Will this work?’, asks Reuven.&lt;br&gt;
&lt;em&gt;‘NO!’&lt;/em&gt;, I yell back at the screen. ‘This function does not do anything, will return None and cause an error!’&lt;br&gt;
I am learning! This is fun! :)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Been going, “Ooooh! So that’s how they do it!” lots of times in this class.&lt;/li&gt;
&lt;li&gt;Ok, have now dropped from a 30,000 foot view of Python to a 10,000 foot view. Will hit ground level, starting tomorrow, when I start doing exercises.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/python-iterators-generators/" &gt;Read all about my Python Iterators &amp;amp; Generators journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 018 - Python Comprehensions, Done!</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-018-python-comprehensions-done/</link><pubDate>Sun, 26 Jul 2020 19:00:00 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-018-python-comprehensions-done/</guid><description>&lt;p&gt;Continuing my comprehensions journey.&lt;br&gt;
Hopefully it makes more sense this time around&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h2 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;** Set Comprehensions **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If I want a set of uniques from a group, I could use a set.
&lt;ul&gt;
&lt;li&gt;Or like Reuven likes to joke, a set is a dictionary with no values; an immoral dictionary 😂&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Create it with a &lt;code&gt;somesetcomp = set('somecondition' for a something in somethingbig)&lt;/code&gt; or in a simpler manner, &lt;code&gt;somesetcomp = {'somecondition' for something in somethingbig}&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Protip, better to start with a list comprehension, be done with figuring out stuff and then just switch the brackets at the end. Fewer issues that way.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;** Dictionary Comprehensions **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create it like so &lt;code&gt;somedictcomp = {somekey:somevalue for something in somethingbig}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;It creates only one dictionary, not a set&lt;/li&gt;
&lt;li&gt;It &lt;em&gt;has&lt;/em&gt; to have a key and a value variable, seperated by a colon. If it is just a single variable, I’ll end up with a set comprehension.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;** Nested Comprehensions **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Running a comprehension on the elements of a parent comphrehension is a nested comprehension.
&lt;ul&gt;
&lt;li&gt;For e.g. if I had a list of lists and I needed to pull out each element from each list I would
&lt;ul&gt;
&lt;li&gt;create a comprehension that would get each list from my giant list of lists&lt;/li&gt;
&lt;li&gt;and then run a comprehension on those lists to get each element out.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;big_list = [[10, 20], [30, 40], [50, 60], [70, 80]]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;elemental_list = [each_element for each_list in big_list for each_element in each_list]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pretty handy when needed. I can go as many levels deep as needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;** Why Comprehensions? **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A comprehension is needed or rather the better tool for the job, when I have one sequence and I want to turn it into another sequence. Creating new things from old things&lt;/li&gt;
&lt;li&gt;If I am interested in the side effects, the actions, umm, like printing to the screen for example, that is when I’d use &lt;code&gt;for&lt;/code&gt; loops.&lt;/li&gt;
&lt;li&gt;It gets increasingly obvious, the more I use it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythoncomprehensions/" &gt;Read all about my Python Comprehensions journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 017 - Python, Advanced Objects, Done!</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-017-python-advanced-objects-done/</link><pubDate>Sat, 25 Jul 2020 18:10:46 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-017-python-advanced-objects-done/</guid><description>&lt;p&gt;And we are done with objects!&lt;br&gt;
&lt;a href="https://store.lerner.co.il/advanced-python-objects/" target="_blank" rel="noreferrer"&gt;This course&lt;/a&gt; finally gave me what I was looking for all these months.&lt;br&gt;
The ability to think of and reason about Python, so that I can then think of and reason about, how to build my own programs.&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h2 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Abstract base classes
&lt;ul&gt;
&lt;li&gt;Sounds all high and mighty, but does something pretty logical and simple&lt;/li&gt;
&lt;li&gt;Helps me test if my object is of a generic (of sorts) type. I don’t want to test if 5 is an integer or a float or any of the other various county types in Python. I just want to see if it’s a number, of some sort. The abstract base class &lt;code&gt;numbers&lt;/code&gt; helps me do that.&lt;/li&gt;
&lt;li&gt;There are such classes for strings and files, I hear.&lt;/li&gt;
&lt;li&gt;Will go into learning more about them in detail later, as I actually write more Python. But at least I know &lt;em&gt;what&lt;/em&gt; they are now.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;** Part 3, Context Managers**&lt;/p&gt;
&lt;p&gt;Again, Context Managers, sound like something really complex, but they are just a matter of writing and doing things in a certain manner.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It’s something like a &lt;a href="https://mjbraganza.com/atomic-habits/" target="_blank" rel="noreferrer"&gt;Tiny Habit stack loop&lt;/a&gt;, I learnt in the Atomic Habits book, as I was building up new habits.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;When&lt;/em&gt; I do this,&lt;/li&gt;
&lt;li&gt;&lt;em&gt;then&lt;/em&gt; I will do this immediately &lt;em&gt;after&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;and when I am done, I will do &lt;em&gt;that.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Context Managers have a similar paradigm.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;With this object &lt;em&gt;(as this variable, optionally)&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;I will run the &lt;code&gt;__enter__&lt;/code&gt; method&lt;/li&gt;
&lt;li&gt;&lt;em&gt;then after,&lt;/em&gt; I will do stuff&lt;/li&gt;
&lt;li&gt;and when I am done, I will run the &lt;code&gt;__exit__&lt;/code&gt; method&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I can add the context manager protocol to my objects too, by impletementing the &lt;code&gt;__enter__&lt;/code&gt; and &lt;code&gt;__exit__&lt;/code&gt; methods in my classes&lt;/li&gt;
&lt;li&gt;They are used in a particular context, where you want to turn something on and then turn something off, before and after that context, thus &lt;em&gt;Context Manager&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;I can set something up in my &lt;code&gt;__enter__&lt;/code&gt; method and then tear it down in my &lt;code&gt;__exit__&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;This could be, for example, a network connection, a file, a redefinition of some sort, etc.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;__enter__&lt;/code&gt; method must return self if all has to work well.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;__exit__&lt;/code&gt; block, takes four arguments, one for &lt;code&gt;self&lt;/code&gt;, one for an error class, one for the object, and one for the address in memory, the traceback. I can use them to catch errors in the main body of my with block, and then decide what the appropriate way to deal with them is.&lt;/li&gt;
&lt;li&gt;A good example is using redirecting the &lt;code&gt;print&lt;/code&gt; function’s output to a file, using a context manager. (The print function can write to a file, when I specify it as an output device like so &lt;code&gt;print (&amp;quot;Hello there&amp;quot;, file=f)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;While I might be able to catch errors in the body of the context manager, I cannot if something happens during &lt;code&gt;__enter__&lt;/code&gt;. just something to be aware of.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Contextlib is a library of context managers, Python already provides us.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;import contextlib&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;contextlib.redirect_stdout/err&lt;/code&gt; will redirect stuff from the default output (the screen) to whereever else you want it to.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;** Part 4, Properties and Descriptors **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;&lt;strong&gt;property&lt;/strong&gt;&lt;/em&gt; is an attribute, that acts like getters/setters in other languages. It uses methods to set other attributes in the class (within the bounds we set). For e.g. a &lt;code&gt;.temp&lt;/code&gt; property that will let you set temperatures, but only in the range you specify. not below 18C and not above 25C.&lt;/li&gt;
&lt;li&gt;set by putting &lt;code&gt;@property&lt;/code&gt; atop a getter function (let’s say &lt;code&gt;temp&lt;/code&gt;) and then defining the setter properties in an identically named &lt;code&gt;temp&lt;/code&gt; function again but decorated with &lt;code&gt;@function_name.setter&lt;/code&gt;; in our case &lt;code&gt;@temp.setter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;the whole actual way to do it is like a contortionist twisting into a pretzel shape. Getting fluent with this will take time and practice.&lt;/li&gt;
&lt;li&gt;it basically (to my mind) is like me giving someone something, and that someone goes and magician like, does something marvellous with that something, instead of just storing it in their pocket. it looks like assigning data to an attribute, but behind the scenes there are methods, just waiting to weave spells on said data.&lt;/li&gt;
&lt;li&gt;When I take a property out of a class and abstact it, so that it can be used by many classes, it’s called a &lt;em&gt;&lt;strong&gt;descriptor.&lt;/strong&gt;&lt;/em&gt; (kinda like abstracting functions out of program files and into modules)&lt;/li&gt;
&lt;li&gt;To kinda formally state, a descriptor is a class whose instances are supposed to be class attributes in other classes.
&lt;ul&gt;
&lt;li&gt;To fit the descriptor protocol, a descriptor class needs to implement…
&lt;ul&gt;
&lt;li&gt;a &lt;code&gt;__get__(self, host_instance, host_class)&lt;/code&gt; method with a corresponding &lt;code&gt;__set__(self, host_instance, new_value_to_set)&lt;/code&gt; method&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;These are class specific. As in, the descriptor is shared amongst all the instances it is used in.&lt;/li&gt;
&lt;li&gt;To get instance specific descriptors, you set the value that you are changing to be assigned as a dictionary using the host instance as the key and the value, as the value. (More contorting!) and then return the value of the &lt;code&gt;[host_instance]&lt;/code&gt; value.&lt;/li&gt;
&lt;li&gt;Definitely tons of practice needed with this.&lt;/li&gt;
&lt;li&gt;Not used much, in day to day work, but used heavily behind the scenes by Python itself for its object system. The methods, Python classes have, are plain old functions, with descriptors (in conjunction with weak referenced elements) applied to them.&lt;/li&gt;
&lt;li&gt;The more I dive into all of this, the more Python feels less magical and more like the work of thousands of hard working atomic elements. And I think, I like this better. That everything complex, is actually lots of simple pieces, working together in concert.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;** Part 5, Advanced Topics **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The only thing I can write here, is that Reuven goes deep into hijacking how Python creates classes and then using them for our own customised ends. How to create my own custom &lt;code&gt;__new__&lt;/code&gt; method, my own custom &lt;code&gt;__init__&lt;/code&gt; method, my own custom &lt;code&gt;type&lt;/code&gt; of object, create my own class with a metaclass…&lt;/li&gt;
&lt;li&gt;Never going to use this, unless I am writing the next Django or something, and even then I doubt, these would be needed 😂&lt;/li&gt;
&lt;li&gt;But this was so much fun to learn!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythonoop/" &gt;Read all about my Python Objects journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 016 - Python, Advanced Objects.</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-016-python-advanced-objects/</link><pubDate>Fri, 24 Jul 2020 20:34:43 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-016-python-advanced-objects/</guid><description>&lt;p&gt;Started up with Python Objects today.&lt;br&gt;
This seems like a long, hard one.&lt;br&gt;
Here’s hoping I learn lots.&lt;br&gt;
Knowing Reuven, &lt;a href="https://store.lerner.co.il/advanced-python-objects/" target="_blank" rel="noreferrer"&gt;I know I will.&lt;/a&gt;&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h2 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Part 1, Advanced Methods.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This section focuses on the dunder methods in Python.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;By default objects are not &lt;code&gt;equal&lt;/code&gt; to other objects even they they are from the same class, with the same attributes and methods.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We could implement our own &lt;code&gt;equals&lt;/code&gt; method though.&lt;/li&gt;
&lt;li&gt;The point being, we need to be &lt;em&gt;intentional&lt;/em&gt; and methodical, when we design and implement our classses&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Static methods are plain old functions that I write in my class for use by &lt;em&gt;both&lt;/em&gt; the class and the instance. Could be used to clean up input or similar such utility functions. I create them by putting a &lt;code&gt;@staticmethod&lt;/code&gt; decorator atop my method.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Class methods are those that are meant for use by only the class. I can call them from my instances, but they act on the class. I create them by using the &lt;code&gt;@classmethod&lt;/code&gt; atop my method. For clarity, the first variable is now written as &lt;code&gt;cls&lt;/code&gt; instead of &lt;code&gt;self&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Part 2, Inheritance.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MRO, Method Resolution Order. I can do an &lt;code&gt;classname.__mro__&lt;/code&gt; to see how Python goes about looking for methods upwards, specially if I’m inheriting from multiple objects. Running help on an object also lists the MRO of its methods.&lt;/li&gt;
&lt;li&gt;Best to explicity inherit from all parent classes, when inheriting from multiple classes.&lt;/li&gt;
&lt;li&gt;We can use the &lt;code&gt;classname.__bases__&lt;/code&gt; to check for the classes parents.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;mixin&lt;/code&gt; is a class, we can inherit from (probably in addition to and before our parent class), that just adds functionality to our class. Does nothing sematically / organizationally to our objects or classes.
&lt;ul&gt;
&lt;li&gt;The mixin &lt;em&gt;must come first.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Adding an &lt;code&gt;__&lt;/code&gt; before an attribute, signifies that it is not to be touched. A little security by obscurity too. Nothing’s stopping me from actually going and changing things up. It’s just a notifier to people with common sense that such stuff ought not to be tampered with.
&lt;ul&gt;
&lt;li&gt;The main reason though is to prevent conflict between attribute names.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;Learning / Feedback/ Experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;This course feels like the O’Reilly cookbooks in video form.&lt;/li&gt;
&lt;li&gt;The first section takes all the operators, I take for granted in Python and then shows me how to implement them with my own classes
&lt;ul&gt;
&lt;li&gt;how do I get &lt;code&gt;len&lt;/code&gt; to work on my object? or how do I implement the &lt;code&gt;==&lt;/code&gt; operator in my classes? etc. etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Starting with the last one and this one, have given up on exercises and just taking notes for now. As soon as I finish the run, I will be then going on an exercise binge with these pending exercises as well as Reuven’s &lt;a href="https://www.manning.com/books/python-workout" target="_blank" rel="noreferrer"&gt;Python Workout&lt;/a&gt;.
&lt;ul&gt;
&lt;li&gt;The execption being, if I run into a topic that is &lt;em&gt;really&lt;/em&gt; confusing, then I will attempt the exercises to drill the idea immediately into my head.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Obligatory Reuven plug, since I started up a new course :)
&lt;ul&gt;
&lt;li&gt;Reuven is an awesome teacher.&lt;/li&gt;
&lt;li&gt;He takes the time, to explain stuff in &lt;em&gt;painstaking detail&lt;/em&gt;, leaving nothing as an “exercise to the reader”.&lt;/li&gt;
&lt;li&gt;All of these courses, so far have been worth every single penny I spent on them.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythonoop/" &gt;Read all about my Python Objects journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 015 - Python, Advanced Functions, Done!</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-015-python-advanced-functions-done/</link><pubDate>Fri, 24 Jul 2020 11:32:03 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-015-python-advanced-functions-done/</guid><description>&lt;p&gt;Delving deeper into Python functions and learning more about them, using &lt;a href="https://store.lerner.co.il/advanced-python-functions/" target="_blank" rel="noreferrer"&gt;Reuven Lerner’s Advanced Python Functions Course&lt;/a&gt;&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h2 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;co_*&lt;/code&gt; series of attributes &lt;em&gt;inside&lt;/em&gt; the &lt;code&gt;__code__&lt;/code&gt; attribute inside most functions gives a wealth of information about a function.
&lt;ul&gt;
&lt;li&gt;For example, looking up the argcount attribute for some function hello, with &lt;code&gt;hello.__code__.co_argcount&lt;/code&gt; will give us the number of arguments &lt;code&gt;hello&lt;/code&gt; takes.&lt;/li&gt;
&lt;li&gt;And doing a &lt;code&gt;hello.__code__.co_varnames&lt;/code&gt; will give us a tuple of all the local variables in a function&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hello.__code__.co_code&lt;/code&gt; contains the compiled bytecode for the function.
&lt;ul&gt;
&lt;li&gt;Importing the disassembler &lt;code&gt;import dis&lt;/code&gt; and running it on the bytecode, &lt;code&gt;dis.dis(hello)&lt;/code&gt; will show us what’s in there.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hello.__code__.co_flags&lt;/code&gt; keeps a track of whether the function has * arguments or not via a binary switch. (It holds many parameters, one of which is the on/off switch for *args)
&lt;ul&gt;
&lt;li&gt;if said switch is set, the function checks for such arguments at runtime and turns them into a tuple to process.&lt;/li&gt;
&lt;li&gt;they are set for *args via the &lt;code&gt;hello.__code__co_argcount&lt;/code&gt; switch (0/1) and for keyword arguments with the &lt;code&gt;hello.__code__.co_kwonlyargcount&lt;/code&gt; switch.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;__defaults__&lt;/code&gt; attribute keeps all the functions default variable values. If I don’t supply a value to some parameter, the function will look in here, to see if a default value exists. &lt;code&gt;hello.__defaults__&lt;/code&gt; could hold a last name default, for example, if I want my hello function to work even if no last name was supplied, and it actually expected a full name.
&lt;ul&gt;
&lt;li&gt;do &lt;em&gt;&lt;strong&gt;not&lt;/strong&gt;&lt;/em&gt; use mutable defaults. an empty list or dictionary for example.&lt;/li&gt;
&lt;li&gt;set the default to &lt;code&gt;None&lt;/code&gt; first in such case and then create the list when the function runs at runtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The last thing I learnt about were nested functions.
&lt;ul&gt;
&lt;li&gt;I can nest them two/three/as many levels deep as I wish. Practically, most folks do two or three.&lt;/li&gt;
&lt;li&gt;When an inner function takes the variables of its enclosure and does something with it and returns stuff…? those kinds of functions are called closures.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;Learning / Feedback/ Experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The course so far is Reuven making simple functions and then breaking them down and explaining functionality in &lt;em&gt;painstaking detail&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Reuven is an awesome teacher! I would gush about him every post, but then it would get too much 😂. So once per course is good&lt;/li&gt;
&lt;li&gt;I kept looking at the disassembled code and wondering, what language it was. I still don’t know. My ‘educated’ guess is that it is a level of standard pseudo-assembly code for some phantom standardised processor. Once I had that mental model in mind though, all of it started making a lot more sense. This brought memories of Z80 assembly, I learnt in the mid 90s&lt;/li&gt;
&lt;li&gt;This was fun to do! Onwards to Advanced Objects!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythonfunctions/" &gt;Read all about my Python Functions journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 013, Day 14 - Python, Advanced Data Structures, Done!</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-013-day-14-python-advanced-data-structures-done/</link><pubDate>Wed, 22 Jul 2020 17:48:09 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-013-day-14-python-advanced-data-structures-done/</guid><description>&lt;p&gt;Notes and experiences for yesterday and today.&lt;br&gt;
I ‘wasted’ a lot of time, again, struggling with exercises yesterday and ended up being too zombied to even write the summary post.&lt;br&gt;
Have been much smarter about it today.&lt;br&gt;
Stopped after about 30 mins and copied and tried to understand the solution.&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h3 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;List of Dictionaries&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Just more convenient than a list of lists, not particularly faster&lt;/li&gt;
&lt;li&gt;Make it more flexible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Dictionary of dictionaries&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Think beforehand of what your keys are going to be.&lt;/li&gt;
&lt;li&gt;Looking in them, faster than lists&lt;/li&gt;
&lt;li&gt;The tradeoff is more memory usage&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Dictionary of Lists&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Works when you need disparate elements to work with later. Those can be stored as dictionary values, in a list form.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Part 3&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Decimals&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To have something sane between integers and crazy floats.&lt;/li&gt;
&lt;li&gt;I import the Decimal class and then create objects, like so&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;decimal&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Decimal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0.1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0.2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;I create them from &lt;em&gt;strings&lt;/em&gt; not floats, just like I would &lt;code&gt;int&lt;/code&gt; strings.&lt;/li&gt;
&lt;li&gt;It has various methods I can call on the Decimal object.
&lt;ul&gt;
&lt;li&gt;Stuff like &lt;code&gt;getcontext&lt;/code&gt; with has a method to set the precision of units after the decimal point.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Helpful if you need precision at a certain level.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Named Tuples&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A very handy way of calling values in a tuple by sensible names, just like dictionaries&lt;/li&gt;
&lt;li&gt;Very handy instead of heavyweight dictionaries.&lt;/li&gt;
&lt;li&gt;Create them like so&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;collections&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;namedtuple&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;namedtuple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Person&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;first&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;last&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;age&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;me&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Jason&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Braganza&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Doing a &lt;code&gt;me.first&lt;/code&gt; will get me &lt;code&gt;Jason&lt;/code&gt;, just like a dictionary.&lt;/li&gt;
&lt;li&gt;I can still refer to the tuples with the numeric indices.&lt;/li&gt;
&lt;li&gt;I can do a &lt;code&gt;._replace&lt;/code&gt; to replace values, if I want to. &lt;code&gt;me._replace(first ='Mario')&lt;/code&gt;. It just returns a new object with the same name, which I can choose to catch in a &lt;em&gt;new&lt;/em&gt; variable.&lt;/li&gt;
&lt;li&gt;Better for readability.&lt;/li&gt;
&lt;li&gt;Basic uses. The moment I want to twiddle with it too much, I know I should just make my own classes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;defaultdict&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A variation/improvement on the normal dictionary.&lt;/li&gt;
&lt;li&gt;We want a dictionary, with default values.&lt;/li&gt;
&lt;li&gt;When I check for the presence of a key, if it does not exist it’ll get created with a default value.&lt;/li&gt;
&lt;li&gt;We give it a function or a class, that will run, be called everytime a key does not exist.&lt;/li&gt;
&lt;li&gt;So I could pass it basic primitives, like a list with no entries and it will return an empty list for a value everytime, there is not one. Or saying int, in which case it will create a key with 0 for a value&lt;/li&gt;
&lt;li&gt;Create them like so&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;collections&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;defaultdict&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;defaultdict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;So now when I do &lt;code&gt;d['a']&lt;/code&gt;, it well check for key &lt;code&gt;a&lt;/code&gt;. If it does not exist, it will create it, and give it a value of 0 by running the int function with no arguments.&lt;/li&gt;
&lt;li&gt;I can use any function or callable, as long as it has no arguments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;OrderedDict&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No need to use it anymore&lt;/li&gt;
&lt;li&gt;But handy in case I am looking at old code.&lt;/li&gt;
&lt;li&gt;Regular dictionaries order stuff chronolgically as of Python 3.7.&lt;/li&gt;
&lt;li&gt;Which is what ordered dictionaries used to do.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Counter&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;from collections import Counter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;if I pass an Counter dictionary an iterable, it will create a dictionary with the occurrence of each element.&lt;/li&gt;
&lt;li&gt;if I go &lt;code&gt;c = Counter[10, 10, 20, 50, 60, 60, 80, 80, 80, 90']&lt;/code&gt;, then I get a dictionary like &lt;code&gt;Counter({10: 2, 20: 1, 50: 1, 60: 2, 80: 3, 90: 1})&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I can also do a most common method to get the most frequently used elements. &lt;code&gt;c.most_common()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Enums&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;from enum import Enum&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create ’em like&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ColorEnum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Red&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Blue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Green&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Matches symbolic labels / names to numeric values.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;a = ColorEnum.Red&lt;/code&gt; and &lt;code&gt;b=ColorEnum.Red&lt;/code&gt; then they would both be equal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;Learning / Feedback/ Experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Reuven keeps harping on the fact, that I need to &lt;em&gt;think&lt;/em&gt; things through.
&lt;ul&gt;
&lt;li&gt;Is this how you want to build things?&lt;/li&gt;
&lt;li&gt;What are the ramifications?&lt;/li&gt;
&lt;li&gt;What if you want to change up things or if things are expected to grow exponentially in the future?&lt;/li&gt;
&lt;li&gt;Think! Be itentional. Design accordingly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Caught myself frequently initalising a total in a loop and then wondering why I would not get the actual total :)&lt;/li&gt;
&lt;li&gt;Now my approach, kinda matches what Reuven does. Which means, I am beginning to write some sane code :)&lt;/li&gt;
&lt;li&gt;Finished with this course. And on to the next one. Planning, building in margin and working at it a little bit everyday helping a lot!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/python-advanced-python-data-structures/" &gt;Read all about my Python advanced data structures journey here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 012 - Python, Advanced Data Structures continued</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-012-python-advanced-data-structures-continued/</link><pubDate>Mon, 20 Jul 2020 16:21:04 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-012-python-advanced-data-structures-continued/</guid><description>&lt;p&gt;Ok! Had a nice refreshing break, yesterday being Sunday.&lt;br&gt;
Back to work today!&lt;br&gt;
If today’s notes, feel a little light, that’s because I was struggling with exercises.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;h2 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Part 2&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A lightweight solution to classes, if I am just combining all sorts of data structures is the built-in &lt;code&gt;collections&lt;/code&gt;. Some of them could be
&lt;ul&gt;
&lt;li&gt;List of Lists&lt;/li&gt;
&lt;li&gt;List of Tuples&lt;/li&gt;
&lt;li&gt;List of Dictionaries&lt;/li&gt;
&lt;li&gt;Dictionary of Dictionaries&lt;/li&gt;
&lt;li&gt;Dictionary of Lists&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Mostly use them to solve tricky issues. If I find myself using lots of functions, just to deal with these structures, I am better off using classes.
&lt;ul&gt;
&lt;li&gt;These structures also lend themselves to being converted into classes.&lt;/li&gt;
&lt;li&gt;Sometimes it’s just a matter of adding a few methods, et voilà, I have a class!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Lists of lists&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As simple to create as &lt;code&gt;l = [[1,3,2],[4,5,6],[7,8,9]]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;If I do a &lt;code&gt;l[0]&lt;/code&gt;, I’ll get the first element, the list &lt;code&gt;[1,3,2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;To get at the elements inside &lt;em&gt;that&lt;/em&gt; list, I can go &lt;code&gt;l[0][2]&lt;/code&gt; which will give me the number, 3.&lt;/li&gt;
&lt;li&gt;Behind the scenes, &lt;code&gt;l.__getitem__(0).__getitem__(2)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;We can either work with them with indices like up above, or iterate over them, with for loops or comprehensions&lt;/li&gt;
&lt;li&gt;Better to use lists of tuples, if I am dealing with mixed types, specially those that are not apt to change, like records of some sort. Something like a list of details about movies.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;Learning / Feedback/ Experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Learning to think atomically. Learning to break down each exercise into pieces and then learning to organise them in a manner, that I can solve it, step by step.
&lt;ul&gt;
&lt;li&gt;What hints do Reuven’s results show?&lt;/li&gt;
&lt;li&gt;What should I compare first? What will be the aftermath? and so on.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Gave up an exercise after two hours of trying.
&lt;ul&gt;
&lt;li&gt;After peeking at the solution I realised that it was not because of something I forgot or did not practice, but once again, because of something I did not know.&lt;/li&gt;
&lt;li&gt;in this case that there are set operators to use between two iterator objects.instead of crazily stepping through everything like I did below, I could’ve just created a union list run through them.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Just goes to show, there is lots for me to learn. And that there is a lot of tacit knowledge out there. And this I will only be able to figure out by writing lots of code!&lt;/li&gt;
&lt;li&gt;Also (note to self), time your self and be ok with giving up and looking at the solution. I seem to keep thinking that I am wrong or am missing something. Never the fact, that it might be something that I do not know.
&lt;ul&gt;
&lt;li&gt;I am now strictly going to give myself 30 minutes per exercise and then move on.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lots of mistakes as usual.
&lt;ul&gt;
&lt;li&gt;Wrong indentation, giving weird results.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/python-advanced-python-data-structures/" &gt;Read all about my Python advanced data structures journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 011 - Python, Advanced Data Structures</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-011-python-advanced-data-structures/</link><pubDate>Sat, 18 Jul 2020 19:14:17 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-011-python-advanced-data-structures/</guid><description>&lt;p&gt;Started with a new &lt;a href="https://store.lerner.co.il/advanced-python-data-structures/" target="_blank" rel="noreferrer"&gt;Reuven Lerner Course, on Advanced Data Structures.&lt;/a&gt;.&lt;br&gt;
Aiming to comfortably finish this in a week.&lt;br&gt;
Notes and experiences, follow.&lt;br&gt;
The course is three parts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Part 1 - Deep dive into the common data structures&lt;/li&gt;
&lt;li&gt;Part 2 - Combining Data Structures. Lists of lists, Dicts of lists, Tuples of Lists and so forth. How far can I go without classes? Or how can I enhance my classes with this approach?&lt;/li&gt;
&lt;li&gt;Part 3 - Complex data structures, that come with the Python Standard Library. The Collections module, Weak references etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h3 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Part 1&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;id&lt;/code&gt; of a variable shows me where the object in refers to, is located in memory.&lt;br&gt;
If &lt;code&gt;x=5&lt;/code&gt; then the &lt;code&gt;id(x)&lt;/code&gt; will point to where it’s object, here the number 5, is located in memory.&lt;/li&gt;
&lt;li&gt;When I assign a variable to another, what I actually do is assign the new variable to the same objects address. That is all. When I do &lt;code&gt;x = y&lt;/code&gt;, then y will point to 5 too, independent of x. If I set x to something else later, y is not going to follow x. Instead it steadfastly points to 5.&lt;/li&gt;
&lt;li&gt;A simple way to say this is &lt;code&gt;x is y&lt;/code&gt;, where I am &lt;em&gt;not&lt;/em&gt; checking for equality, but rather testing the fact, that both of them point to the same location in memory, or not.&lt;/li&gt;
&lt;li&gt;I can use &lt;code&gt;sys.getsizeof()&lt;/code&gt; to find the size of an object in memory. (how much memory it uses), but it’s a tricky beast. For e.g. when it shows me the size of a list, it shows me the size of the list object. Not the size of the elements it contains. To get that, I need to go check the size of its elements one by one.&lt;/li&gt;
&lt;li&gt;A singleton object (not many in Python) is an object that every time you create a new instance of, from the parent class, it always points back to the same instance. &lt;code&gt;None&lt;/code&gt; is an example in Python.&lt;/li&gt;
&lt;li&gt;Better to create a list using square brackets, rather than assigning them via a string. &lt;code&gt;x = ['a','b','c','d']&lt;/code&gt; works better than going &lt;code&gt;x = list('abcd')&lt;/code&gt;. This obviously matters upon what you are doing and if that is possible to do or not.&lt;/li&gt;
&lt;li&gt;I can tuple-unpack-split a string in various ways. If I go, &lt;code&gt;a, b, *c = s.split[]&lt;/code&gt; it will get the first split item in a, the next one in b, and the rest will be a list in c. But if I want the first and last elements for example and don’t care about the stuff in the middle, I can also go, &lt;code&gt;a, *b, c = s.split()&lt;/code&gt;. I need to play with this. Just realised I could’ve solved a lot of exercises I did in the past, more elegantly if I knew this then.&lt;/li&gt;
&lt;li&gt;If I access an element in a sequence via its index, I will get the element back along with the &lt;em&gt;elements type&lt;/em&gt;, but if I slice a sequence to get just one element back, I get a single element of the &lt;em&gt;sequence’s type&lt;/em&gt;. Very nifty!
&lt;ul&gt;
&lt;li&gt;For example if I access &lt;code&gt;s[0]&lt;/code&gt; in the list &lt;code&gt;['jason', 'braganza']&lt;/code&gt;, then I will get a string &lt;code&gt;jason&lt;/code&gt; back.&lt;/li&gt;
&lt;li&gt;But if I slice and get just the first element with a &lt;code&gt;s[:1]&lt;/code&gt; (get upto, but not including 1), I get a single element &lt;em&gt;list&lt;/em&gt;, &lt;code&gt;['jason']&lt;/code&gt; back.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If I look up a key &lt;code&gt;z&lt;/code&gt; in a dictionary &lt;code&gt;d&lt;/code&gt; with a &lt;code&gt;d[z]&lt;/code&gt; and it does not exist, then I get a &lt;code&gt;KeyError&lt;/code&gt;. If I want to check keys without noise, I use the &lt;code&gt;get&lt;/code&gt; method on a dictionary. If the key exists, the value is returned. If not &lt;code&gt;None&lt;/code&gt; comes back.
&lt;ul&gt;
&lt;li&gt;I can set keys similarly with the &lt;code&gt;setdefault&lt;/code&gt; key if I want to set keys safely. If I just do &lt;code&gt;d[z] = 100&lt;/code&gt; and z already existed, its value would have gotten trampled and set to 1000. But if I do the samething with a &lt;code&gt;d.setdefault(z, 100)&lt;/code&gt; then it sets it to 100 &lt;em&gt;only&lt;/em&gt; if the key does not exist. If it does, it just returns the old existing value. No harm, no foul.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If I have two dictionaries and I want the contents of one in the other, then I use the update method. For e.g., I have dictionary a and dictionary b, so I do &lt;code&gt;a.update(b)&lt;/code&gt; and everything from b flows into a.
&lt;ul&gt;
&lt;li&gt;If there is overlap in the keys, then the values get trampled and overwritten.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I normally cannot add dictionaries, lists, or other sets &lt;em&gt;to&lt;/em&gt; my sets (no &lt;em&gt;unhashable&lt;/em&gt; types allowed), I can freeze a set with &lt;code&gt;frozenset&lt;/code&gt;, which makes it hashable and then add it to my set.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h3 class="relative group"&gt;Learning / Feedback/ Experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Reuven makes Python sound like a cute animated bear. ‘Python notices and says “Oh, you’re using 256. I’ve aleady got that. Don’t create a new object for that!”’ I wish my interpreter was as helpful 😂&lt;/li&gt;
&lt;li&gt;This course is a lot less structured than the basic courses. It approaches you from the point of view, that you know stuff, you can read and write Python, you have a modicum of intelligence, so here’s a really juicy grab bag of interesting stuff about all the basics you learnt earlier.
&lt;ul&gt;
&lt;li&gt;It’s best to always use f-strings, but if you need to eke performance, can you figure out, what kind of strings are the best? (spoiler, benchmark it)&lt;/li&gt;
&lt;li&gt;While Python lists are expandable, the C structures underyling it are fixed. How does Python let you have flexible, expandable lists then?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;And so on and so forth. So far, this has been &lt;em&gt;fascinating.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/python-advanced-python-data-structures/" &gt;Read all about my Python advanced data structures journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 010 - Python Functions, Basics Done!</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-010-python-functions-basics-done/</link><pubDate>Fri, 17 Jul 2020 19:36:18 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-010-python-functions-basics-done/</guid><description>&lt;p&gt;Today was hard!&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h3 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;‘*args’&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;way to get multiple arguments without having to assign placeholders for them&lt;/li&gt;
&lt;li&gt;it scoops up all the arguments and gives it to the function in a &lt;em&gt;tuple&lt;/em&gt;. I could then loop over it with &lt;em&gt;for&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;I just put * in front of one of my placholders et voilà, &lt;code&gt;def example_func(*catch_everything)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I can define placeholders to catch specific arguments, but those need to be &lt;em&gt;before&lt;/em&gt; my ‘*args’.&lt;/li&gt;
&lt;li&gt;Edge Case: I could have my arguments in a list/tuple already. I can just add the structure with a * in front of it and Python will unpack it for me. If I have a list, &lt;code&gt;catch_me_if_you_can=[1,2,4]&lt;/code&gt; then I can pass the &lt;em&gt;elements&lt;/em&gt; individually, as arguments with a &lt;code&gt;def example_func(*[catch_me_if_you_can])&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Another kinda frequent edge case: ‘*args’ catches everything that is unassigned. so if i have something with a default value, it will get trampled by the data from my args. Best thing to do is to set the default &lt;em&gt;after&lt;/em&gt; the ‘*args’ like so, &lt;code&gt;example_func(a, *args, b=10)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Keyword Arguments&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Normally in the form of &lt;code&gt;name = value&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Kinda like addressing lists vs dictionaries. Where instead of an index, I can now call an argument with a name.&lt;/li&gt;
&lt;li&gt;So I can go &lt;code&gt;def name(FirstName='', LastName='')&lt;/code&gt; and then put in stuff in whatever order I want to like &lt;code&gt;name(LastName='Brontë', FirstName='Emily'&lt;/code&gt;. Pretty handy!&lt;/li&gt;
&lt;li&gt;Try not to mix and match positional and keyword arguments. Python looks for positional arguments first, &lt;em&gt;then&lt;/em&gt; keyword arguments. So if you have them, then the positional arguments &lt;em&gt;have to come first!&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;‘**kwargs’&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;these scoop up keywords arguments into a &lt;em&gt;dictionary&lt;/em&gt;. I can do everything with this, just like any other dictionary&lt;/li&gt;
&lt;li&gt;I just put * in front of one of my placholders et voilà encore, &lt;code&gt;def example_func(**catch_everything)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Combining Arguments&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Arguments in decreasing order. Stick to the order as far as possible.
&lt;ul&gt;
&lt;li&gt;mandatory parameters (no defaults)&lt;/li&gt;
&lt;li&gt;optional parameters (with defaults)&lt;/li&gt;
&lt;li&gt;*args&lt;/li&gt;
&lt;li&gt;**kwargs (with and without defaults)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use them for different kinds of input&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Variable scopes&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Just because I have indentation, with an if or an else or a for, does &lt;em&gt;not&lt;/em&gt; mean that I change a variable’s scope. Variables within those indented blocks could still be global, or the scope of the thing above&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;slight&lt;/em&gt; exception is the variable within comprehensions. Variables inside them, have their own private scope&lt;/li&gt;
&lt;li&gt;The scope changes, mainly, when we define functions. Generally …
&lt;ul&gt;
&lt;li&gt;If I am &lt;em&gt;in&lt;/em&gt; a function, I’m in a local scope&lt;/li&gt;
&lt;li&gt;If I am out of it, I’m in a global scope&lt;/li&gt;
&lt;li&gt;with some exceptions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;So always think, am I in a function body … or not? (excepting comprehensions)&lt;/li&gt;
&lt;li&gt;When Python looks for variable values it looks in the LEGB sequence. (left to right).
&lt;ul&gt;
&lt;li&gt;Local (starts here if I’m in a function)&lt;/li&gt;
&lt;li&gt;Enclosing&lt;/li&gt;
&lt;li&gt;Global (starts here if I’m &lt;em&gt;not&lt;/em&gt; in a function, rather in the main body of the program)&lt;/li&gt;
&lt;li&gt;Built-in&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;globals&lt;/code&gt; function will have all the global variables for the program. It’s a dict with variable names as keys and the variable assignments as values&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;locals&lt;/code&gt; function will have all the local variables for a function in the program, when it runs. It’s also a dict with variable names as keys and the variable assignments as values or I could also look at the &lt;code&gt;function_name.code.co_varnames&lt;/code&gt; to peek at the local stuff
&lt;ul&gt;
&lt;li&gt;Parameters to a function are also local variables.&lt;/li&gt;
&lt;li&gt;I should define my local variables, before I use them in a function, or I get an &lt;code&gt;UnboundLocalError&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If I want to use and modify a global variable in a function, I should declare it at the beginning of my function. For example, if I have a global variable x, and I want to use it in a function, then I say &lt;code&gt;global x&lt;/code&gt; in the beginning of the function.&lt;/li&gt;
&lt;li&gt;I &lt;em&gt;can&lt;/em&gt; mutate elements of global variable, if they are mutable structures. As in, I cannot change list A to another set of entries, but I can append to list A, or delete items from list A. As long as you are not &lt;em&gt;assigning&lt;/em&gt; to a variable, rather using object methods, you should be ok.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The built-ins scope, houses many things that are needed by Python, but are not reserved keywords. Stuff like &lt;code&gt;list&lt;/code&gt;. I can use it to create lists, but it’s not reserved. I can redefine it if I want to (or more commonly redefine it by mistake)
&lt;ul&gt;
&lt;li&gt;This feels like one of the few places, Python allows me to shoot myself in the foot.&lt;/li&gt;
&lt;li&gt;Do a &lt;code&gt;dir(__builtins__)&lt;/code&gt; and review the names every now and then, and &lt;em&gt;don’t&lt;/em&gt; use them in your code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Kinda Advanced Stuff&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;While I said, they were verbs, functions can alse be nouns. I can just pass them as objects to other functions or elsewhere.&lt;/li&gt;
&lt;li&gt;I can pass a function as an argument as in the case of &lt;code&gt;sorted(someIterableofPositiveNegativeNumbers, key=abs)&lt;/code&gt; where I am passing the &lt;code&gt;abs&lt;/code&gt; function as a keyword to the &lt;code&gt;sorted&lt;/code&gt; function, which then uses &lt;code&gt;abs&lt;/code&gt; to get the absolute values of the numbers first and then sorts them according to those values.&lt;/li&gt;
&lt;li&gt;I can collect arguments for the inner functions I call with &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt; and then pass to them again with &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;I can also take some data as an argument along with a function and apply that function to that data. Like I did above. The main function I create acts like some glue program. This process of applying function to data, is called mapping and the functions I create to do this are map functions. Python has a built in &lt;code&gt;map&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;I can create functions, plop them into a dictionary and then call them as needed in my actual function, by accessing the dictionary keys and supplying arguements. This approach is called a dispatch table&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;Learning / Feedback/ Experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Getting used to the way, Python behaves. And beginning to love its consistency for the most part.&lt;/li&gt;
&lt;li&gt;I write slow, step by step code. while it works, Reuven’s solutions are short and make me go, oh why did I not think of that? Maybe optimised thinking will come with time?&lt;/li&gt;
&lt;li&gt;I have to use Python tutor a &lt;em&gt;lot&lt;/em&gt; to get what is actually happening.&lt;/li&gt;
&lt;li&gt;I’ve learnt to just dive in blind when begining to write programs. The more I think about stuff, the more I feel, like I can’t do this. So I just start. And build it line by line, error by error. And more often than not, it solves it self. Optimised solutions present themselves &lt;em&gt;after&lt;/em&gt; I have the rough and ready solution done. “Aah! I could’ve written it &lt;em&gt;this&lt;/em&gt; way”&lt;/li&gt;
&lt;li&gt;And I am done with the introduction to functions! Hurrah! This course stretched me a bit, and showed me I still have a ways to go.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythonfunctions/" &gt;Read all about my Python functions journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 009 - Python Functions, Basics</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-009-python-functions-basics/</link><pubDate>Thu, 16 Jul 2020 16:12:47 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-009-python-functions-basics/</guid><description>&lt;p&gt;Started up with learning about Python function basics, today. Notes follow. Using the &lt;a href="https://store.lerner.co.il/python-functions/" target="_blank" rel="noreferrer"&gt;Lerner pool of wisdom, as usual&lt;/a&gt;.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;
&lt;p&gt;&lt;strong&gt;Why do we need functions?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DRY &lt;em&gt;(Don’t Repeat Yourself)&lt;/em&gt;, because we can take stuff that is repeatable, assign it a nickname and just call that nickname over and over, instead of tediously writing all that stuff over and over and over&lt;/li&gt;
&lt;li&gt;If want to modify something, I can just call it (by the nickname) and then add my little spice to it. Like I have the recipe to an omlette written down somewhere, I can then just add a little note with secret ingredients at the bottom of that recipe to create a better or a different omlette.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Functions are objects.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We can think of them as verbs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Parentheses in Python (at the end of functions) basically mean, I want to execute, this here thing, on the left&lt;/p&gt;
&lt;p&gt;I can run help on a function to get some information about it.&lt;br&gt;
&lt;code&gt;help(str.upper)&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We don’t tack parentheses on the function, when I am lookif for its help, because I don’t want to run the darned thing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Creating/Defining a function&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We define a function using the &lt;code&gt;def&lt;/code&gt; keyword. It’s followed by the name you want to call it by, followed by parantheses terminated by a colon
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;def hello():&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;This is actually a two step thing, even though I’ve always thought of it as one.
&lt;ul&gt;
&lt;li&gt;first, I create a function object.&lt;/li&gt;
&lt;li&gt;then, I assign it a name.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Functions in Python (unlike other languages), have the same name space as the rest of our Python program. I cannot have a function called x and also a variable called x&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Returning results&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Similar to math functions, even Python functions return values after running them&lt;/li&gt;
&lt;li&gt;The default is &lt;code&gt;None&lt;/code&gt;, unless you actually, explicity tell the function to return something&lt;/li&gt;
&lt;li&gt;If you want to catch the results of what you are doing with the function, remember to return it.&lt;/li&gt;
&lt;li&gt;A function can return whatever you want. statements, values, other functions etc.&lt;/li&gt;
&lt;li&gt;Which is good and all, but remember to do this with intent. I ought to think about what I want to return and document it well&lt;/li&gt;
&lt;li&gt;If I am returning multiple values of varying types, it comes back as a tuple. Not as different objects. I need to unpack them and assign them to multiple values explicity&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Documenting Functions&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The help function needs something to read and tell the user about what our functions do. Ergo …&lt;/li&gt;
&lt;li&gt;Use docstrings (Documentation Strings) to do it.
&lt;ul&gt;
&lt;li&gt;What are docstrings? If the first line in a function is a string, then that string is seen by the help system as a docstring and used for documentation.&lt;/li&gt;
&lt;li&gt;Use triple quotes around the string. I can have multiple lines in there&lt;/li&gt;
&lt;li&gt;The convention is to document what a function receives (the input), what it returns (the output) and what it modifies.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;This is it! The docstring! This will help me figure out what the hello function does!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;		or more seriously
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;		expects: No arguments
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;		modifies: Nothing
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;		returns: A friendly greeting
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;		&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Hello, hello :)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;br&gt; 
**Arguments** 
&lt;p&gt;Functions need stuff to work with.&lt;br&gt;
We supply them using arguments.&lt;br&gt;
Just a fancy name for the data we pass along to the function.&lt;br&gt;
E.g. If a function returns a fancy format of our name, there must be some mechanism to pass our name across to the function. Arguments are how we do it. We don’t actually argue with the programe :P&lt;/p&gt;
&lt;p&gt;A function can take any number of arguments. We just put them between the parentheses, seperated by commas&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Positional Arguments&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;def hello(first, second):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(f&amp;#39;Hello, {first} and {last}&amp;#39;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;In the code above, I can call the function with &lt;code&gt;hello('Tyche','Hestia')&lt;/code&gt; and it will assign Tyche to first and Hestia to second, because I typed them in that order.&lt;/li&gt;
&lt;li&gt;These are called positional arguments&lt;/li&gt;
&lt;li&gt;When I define a number of arguments, I need to pass &lt;em&gt;all&lt;/em&gt; the arguments along. I can’t make space for two and pass only one or none.&lt;/li&gt;
&lt;li&gt;I can supply defaults, so that if the user does not supply all the arguments, the default is used in its place&lt;/li&gt;
&lt;li&gt;If some arguments cannot have defaults and are a must, they must come &lt;em&gt;before&lt;/em&gt; the ones that are optional and can have defaults.&lt;/li&gt;
&lt;li&gt;How does Python know, how many to expect?
&lt;ul&gt;
&lt;li&gt;When Python defines the function, it records the definition and makes a note of what it needs to run the function properly
&lt;ul&gt;
&lt;li&gt;If I look at the guts of the &lt;code&gt;hello&lt;/code&gt; function with a &lt;code&gt;hello.__code__.co_argcount&lt;/code&gt; it’ll tell me, it has recorded two.&lt;/li&gt;
&lt;li&gt;If I supply defaults, they are recorded in a &lt;em&gt;seperate&lt;/em&gt; place called &lt;code&gt;hello.__defaults__&lt;/code&gt; and it supplies the requisite information, so the &lt;code&gt;argcount&lt;/code&gt; always stays at the required number of arguments&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A little dazed today, so calling it quits early.&lt;/p&gt;

&lt;h3 class="relative group"&gt;Learning / Feedback/ Experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;I keep looking for elegant, one statement like solution to problems and get frustrated. Reuven then shows up with a brutally efficient solution that has four if statements. I should remember to be more workmanlike, before I turn craftsman&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythonfunctions/" &gt;Read all about my Python functions journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 008 - Python Basics, Lists, Tuples, Dictionaries, Sets and Done!</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-008-python-basics-lists-tuples-dictionaries-sets-and-done/</link><pubDate>Wed, 15 Jul 2020 19:32:58 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-008-python-basics-lists-tuples-dictionaries-sets-and-done/</guid><description>&lt;p&gt;This was an amazing run! Learnt lots.&lt;br&gt;
Done with the basics course.&lt;br&gt;
Woohoo!&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h3 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;With lists&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Not pythonic to mix types&lt;/li&gt;
&lt;li&gt;can iterate, slice and dice, search, get lengths, transmute them (for e.g. reverse items in them) just like strings&lt;/li&gt;
&lt;li&gt;can have lists of lists!&lt;/li&gt;
&lt;li&gt;lists are mutable, unlike strings. can change items/elements of a list
&lt;ul&gt;
&lt;li&gt;If i create a list from another list, the new list items reference the old list items&lt;/li&gt;
&lt;li&gt;if i want to &lt;em&gt;copy&lt;/em&gt; elements from a list rather than reference them, I’ll go &lt;code&gt;newlist = oldlist[:]&lt;/code&gt; which will copy the elements from the old list into the new one, rather than create references to the old ones&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realise that there is a difference between changing the values of a variable and between changing elements of a list.
&lt;ul&gt;
&lt;li&gt;When I do &lt;code&gt;x = 2&lt;/code&gt; and &lt;code&gt;y = x&lt;/code&gt; and then change x to be &lt;code&gt;x = 3&lt;/code&gt;, remember that the value of y does not become 3. y continues to point to the original location in memory which holds 2. What I did was to break x’s connection to that value and assign to another value in another location&lt;/li&gt;
&lt;li&gt;On the other hand, when I do &lt;code&gt;x = ['jane', 'jill', 'mary']&lt;/code&gt; and then create a copy with &lt;code&gt;y = x&lt;/code&gt; and then change &lt;code&gt;x[0]='edith'&lt;/code&gt;, what I do in this case is change the &lt;em&gt;actual element.&lt;/em&gt; The references to that object in momory stay unchanged. Which is why &lt;code&gt;y[0]&lt;/code&gt;, which holds references to the same object, will also reflect the change to edith.&lt;/li&gt;
&lt;li&gt;Finally if I go, &lt;code&gt;x = ['athena', 'diana', 'aphrodite']&lt;/code&gt;, now we’re back to the assignment. x will point to this new list while y points to the old one.&lt;/li&gt;
&lt;li&gt;This distinction between changes in assignment vs changes to content is very important, when dealing with mutable/changeable data types like lists&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Append something to a list with .append - &lt;code&gt;list.append(something, something else)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Heuristic, when a method on a mutable data type, changes data, in returns &lt;code&gt;None&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;So I should just go &lt;code&gt;mylist.append('blah')&lt;/code&gt; and stuff will be done&lt;/li&gt;
&lt;li&gt;If go &lt;code&gt;mylist = mylist.append('blah')&lt;/code&gt; (which I am &lt;em&gt;very&lt;/em&gt; apt to do) the method will change the list, then return &lt;code&gt;None&lt;/code&gt; and &lt;em&gt;that &lt;code&gt;None&lt;/code&gt; will get assigned to mylist&lt;/em&gt;, In effect, erasing the list and causing unnecessary heartache. So, be careful, very careful. Not careless, like Bond, James Bond.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;+=&lt;/code&gt; or &lt;code&gt;.extend&lt;/code&gt; takes an iterable on the right. picks each element. and then assigns them singly to the list on the left.
&lt;ul&gt;
&lt;li&gt;Append can take only one item.
&lt;ul&gt;
&lt;li&gt;If I want to add &lt;code&gt;xyz&lt;/code&gt; as separate entries to mylist that has &lt;code&gt;['a','b','c']&lt;/code&gt;, append will just take it as a big lump and make &lt;code&gt;['a','b','c','xyz']&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Instead I do a +=
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mylist += 'xyz'&lt;/code&gt; or &lt;code&gt;mylist.extend('xyz')&lt;/code&gt;will give me &lt;code&gt;['a','b','c','x','y','z']&lt;/code&gt;, which is what I wanted in the first place&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;it will only work if there are iterables on the right. (strings, lists, dictionaries etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;insert&lt;/code&gt; method will let you insert something at a location in the list.
&lt;ul&gt;
&lt;li&gt;Give it what you want, tell it where you want, and boom!&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mylist.insert('d', 3)&lt;/code&gt; will put d after abc, giving me &lt;code&gt;['a','b','c','d','x','y','z']&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I can replace things in a list by giving it a location and telling it what to put in there.
&lt;ul&gt;
&lt;li&gt;I could do &lt;code&gt;mylist[0]='artemis'&lt;/code&gt; and the list will change to &lt;code&gt;['artemis','b','c','d','x','y','z']&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I could also give it a slice along with a list of what to put in there. Doing &lt;code&gt;mylist[1:2]=['josephine','lisbeth']&lt;/code&gt; will now give me &lt;code&gt;['artemis','josephine','lisbeth','d','x','y','z']&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;if you add additional elements, than what you replace, Python will insert them, growing the list.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Removing things from a list?
&lt;ul&gt;
&lt;li&gt;the .pop method will pop off the last item in a list.
&lt;ul&gt;
&lt;li&gt;If i give it a location, it will remove the item at that index location. &lt;code&gt;mylist.pop(3)&lt;/code&gt; will remove d from mylist giving me &lt;code&gt;['artemis','josephine','lisbeth','x','y','z']&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When I know what I want to remove, I just use the remove method instead of pop.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mylist.remove('josephine')&lt;/code&gt; will remove poor Josephine leaving us with &lt;code&gt;['artemis','lisbeth','x','y','z']&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If I’m not sure, I could check for the presence of an item before I remove it. Should prevent a program from barfing on me if that element isn’t there
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;if &amp;#39;q&amp;#39; in mylist:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; mylist.remove(&amp;#39;q&amp;#39;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;also the remove method only removes the &lt;em&gt;first&lt;/em&gt; instance of something.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Iterating and counting over lists?
&lt;ul&gt;
&lt;li&gt;the for loop!
&lt;ul&gt;
&lt;li&gt;I can use the &lt;code&gt;enumerate&lt;/code&gt; function if I want numbered items out&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I can iterate over a slice.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;range&lt;/code&gt; function is very list like in its behaviour.&lt;/li&gt;
&lt;li&gt;I can &lt;code&gt;sort&lt;/code&gt; lists.
&lt;ul&gt;
&lt;li&gt;same caveat as above. &lt;code&gt;sort&lt;/code&gt; will change the list in place and return &lt;code&gt;None&lt;/code&gt;. Don’t go assigning &lt;code&gt;mylist = mylist.sort()&lt;/code&gt;. &lt;em&gt;&lt;strong&gt;It won’t work&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;.sort(reverse=True)&lt;/code&gt; will sort in reverse&lt;/li&gt;
&lt;li&gt;sorting between mixed types in a list doesn’t work in Python 3 anymore. The types in a list, ought to be the same.&lt;/li&gt;
&lt;li&gt;Sorting list of lists works by comparing indices&lt;/li&gt;
&lt;li&gt;If I don’t want to change my original list, I can use the &lt;code&gt;sorted&lt;/code&gt; &lt;em&gt;function&lt;/em&gt; on the list.
&lt;ul&gt;
&lt;li&gt;It works on most iterables, not just lists, while the &lt;code&gt;list&lt;/code&gt; method is restricted to lists&lt;/li&gt;
&lt;li&gt;It returns a new sorted list, and keeps the original list intact.&lt;/li&gt;
&lt;li&gt;I can do &lt;code&gt;sorted('something', reverse=True)&lt;/code&gt; will return a reversed list.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I can &lt;code&gt;str&lt;/code&gt; a list and &lt;code&gt;list&lt;/code&gt; a string&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I can &lt;code&gt;split&lt;/code&gt; a string into a list, either by single characters or by a delimiter (a ; or a , or space)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;split without an argument will cut out all white space&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I can &lt;code&gt;join&lt;/code&gt;, strings and lists and stuff, but&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;join works only on a string. it’s a string method&lt;/li&gt;
&lt;li&gt;and that string generally is the glue, that will string what we give it, together&lt;/li&gt;
&lt;li&gt;&lt;code&gt;' '.join(['Hail','Caesar'])&lt;/code&gt; will join the list using that blank space I gave it.&lt;/li&gt;
&lt;li&gt;it works backwards, so that I can feed it any sequence in the end. a list, a tuple, a dictionary … all fair game&lt;/li&gt;
&lt;li&gt;Remember, it won’t work on numbers. It’ll fail.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tuples, are a kind of weird hybrid of strings and lists.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Like a string, they are immutable&lt;br&gt;
Like a list, they can contain anything at all.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;crazyTuple = (1, 2, 4, 5)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;you create them by enclosing with &lt;code&gt;()&lt;/code&gt; brackets. but that is just for you to know you are creating a tuple. I can just do &lt;code&gt;crazyTuple = 1 2 3 4 5&lt;/code&gt; and that creates a tuple just as well.&lt;/li&gt;
&lt;li&gt;I can do most everything with them just like strings and lists, slice, search, iterate blah blah
&lt;ul&gt;
&lt;li&gt;Typically used to create structures. like &lt;code&gt;bookdetails = ('title', 'author', 'pubdate', 'price')&lt;/code&gt;. you know what to expect, once you see definition. Once we figure that &lt;code&gt;[0]&lt;/code&gt; is the title, it normall will be the same for the other books too.&lt;/li&gt;
&lt;li&gt;Behind the scenes in Python, function arguments are passed as tuples.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note:&lt;/strong&gt;* If elements in my tuple are mutable (like a list), I &lt;em&gt;can&lt;/em&gt; change &lt;em&gt;their elements&lt;/em&gt;, like appending or deleting items in the list. The tuple however is immutable. I cannot delete/modify the list item as a whole.&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;extend&lt;/code&gt; if you want to append to a list in a tuple&lt;/li&gt;
&lt;li&gt;Since a tuple is immutable, it doesn’t have a sort method. I can however sort by using the &lt;code&gt;sorted&lt;/code&gt; function which will return a sorted list of the elements of the tuple, whill leaving the original tuple untouched.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Unpacking stuff&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If my variables on the left, match up to the number of items in the structure on the right, &lt;code&gt;x, y, z = (10, 20, 30)&lt;/code&gt; then they get assigned to each. &lt;code&gt;x&lt;/code&gt; is assigned &lt;code&gt;10&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;,&lt;code&gt;20&lt;/code&gt; and &lt;code&gt;z&lt;/code&gt;,&lt;code&gt;30&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dictionaries&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hash tables, hash maps in other languages&lt;/li&gt;
&lt;li&gt;While in a list, I have values of my choice, the index is always numeric. so item 0 is a cookie, item 1 is cookie-dough and so on, with a dictionary, I get to define the indexes too! I can now say endresult is a cookie, ingredient is cookie-dough and on and on&lt;/li&gt;
&lt;li&gt;while if you want to append to a list, you use an append method, if you want to add keys (user defined indexes), you just assign it to a dictionary with its corresponding value. So I can just add &lt;code&gt;cookie_recipe[sugar]=100&lt;/code&gt; to my cookie recipe dictionary above. if the key is already in there, it just gets updated with the new value. if not, the key and the value get added to the dictionary.&lt;/li&gt;
&lt;li&gt;Keys are unique. Values can repeat. But keys can exist only once in a dictionary&lt;/li&gt;
&lt;li&gt;I can use most immutable data types as keys. strings, integers, tuples that don’t contain mutable data like lists etc.&lt;/li&gt;
&lt;li&gt;I can use &lt;code&gt;in&lt;/code&gt; to look for keys in a dictionary. &lt;code&gt;'sugar' in cookie_recipe&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;get&lt;/code&gt; method will look for a key for you. If it exists it will return the key, or if there isn’t, it returns &lt;code&gt;None&lt;/code&gt;. I could even customise the none with a message. If i do &lt;code&gt;d.get('somekey', 'No such key')&lt;/code&gt;, it will print “No such key” if the key isn’t found.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;setdefault&lt;/code&gt; method will set a key in the dictionary along with the value, if it does not already exist in the dictionary. If it exists already, it will return the existing value.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If I want to convert strings to numbers and want to do a sanity check (I would not want to convert text after all, Hello is not a number :P) then I can use the &lt;code&gt;isdigit&lt;/code&gt; method on the string. It’s a &lt;em&gt;string&lt;/em&gt; method to use on &lt;em&gt;strings&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sets, can be thought of as dictionaries without any values.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each value in a set can occur only once.&lt;/li&gt;
&lt;li&gt;create them by going &lt;code&gt;myset = set()&lt;/code&gt; and then I can willy-nilly add values with &lt;code&gt;myset.add(10)&lt;/code&gt; or &lt;code&gt;myset.add(32)&lt;/code&gt;. If I try adding same value twice, no dice. It is stored only once. Every value is unique&lt;/li&gt;
&lt;li&gt;I can use an iterable to add multiple items at once with the &lt;code&gt;update&lt;/code&gt; method. I can pass a list for example, and it will add all the unique values to the list. &lt;code&gt;myset.update([44, 777, 44, 56, 89, 777])&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I cannot have mutable / changeable data as elements of set. No lists, no dicts etc. Strings, Numbers are ok&lt;/li&gt;
&lt;li&gt;While sets &lt;em&gt;look&lt;/em&gt; like lists, they are unordered with no indexing.&lt;/li&gt;
&lt;li&gt;I can iterate over them, though.&lt;/li&gt;
&lt;li&gt;To look for something in a set, use the &lt;code&gt;in&lt;/code&gt; operator&lt;/li&gt;
&lt;li&gt;To remove the item use the &lt;code&gt;remove&lt;/code&gt; method&lt;/li&gt;
&lt;li&gt;I can do set operations. &lt;code&gt;s1 - s2&lt;/code&gt; will show me items that are unique to s1. (it removes the common elements between the sets) or vice versa&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;symmetric_difference&lt;/code&gt; method will show me unique elements from &lt;em&gt;both&lt;/em&gt; sets. stripping off the common elements. &lt;code&gt;s1.symmetric_difference(s2)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;to find if a set is a subset of another I could use the &amp;lt;&amp;gt;= operators. Is s2 a subset of s1? &lt;code&gt;s2 &amp;lt; s1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I can combine sets (union) &lt;code&gt;s1|s2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Or I can find the common elements with intersection &lt;code&gt;s1 &amp;amp; s2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h3 class="relative group"&gt;Learning / Feedback/ Experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Reuven keeps going, Alright? And I keep nodding my head here :)&lt;/li&gt;
&lt;li&gt;Still miss lots of stuff, writing code. Missing colons, no surrounding quotes, missing commas, so many commas … not converting strings to integers and then wondering how I get such large results from simple addition&lt;/li&gt;
&lt;li&gt;But I’m done!&lt;/li&gt;
&lt;li&gt;These were the basics, and I could run through them, but I did not realise I had so many gaps in my basics.&lt;/li&gt;
&lt;li&gt;As I keep saying Reuven is amazing. He points out the pitfalls and keeps reminding me of important issues and shows various methods to solve things, keeps encouraging me and I could go on and on. Lerner fan for life!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythonbasics/" &gt;Read all about my Python basics journey here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 007 - Python Basics, Variables, Basic Data Types, Strings and Loops</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-007-python-basics-variables-basic-data-types-strings-and-loops/</link><pubDate>Tue, 14 Jul 2020 18:26:08 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-007-python-basics-variables-basic-data-types-strings-and-loops/</guid><description>&lt;p&gt;Started with the &lt;a href="https://store.lerner.co.il/intro-python-fundamentals" target="_blank" rel="noreferrer"&gt;Reuven Lerner, Intro Python:Fundamentals&lt;/a&gt; course today.&lt;br&gt;
Made surprising headway, even though today was crazily demanding with work and personal stuff.&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h3 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The difference between &lt;code&gt;==&lt;/code&gt; and &lt;code&gt;is&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;If you want to see if two things are equal, use &lt;code&gt;==&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;like, is &lt;code&gt;2+2&lt;/code&gt; == &lt;code&gt;4&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you want to know if two objects are the same thing. if they are just pointers to the same memory location, use &lt;code&gt;is&lt;/code&gt;. The heuristic is, if you are checking for singleton values, something that there is only one thing of; then in Python, we use &lt;code&gt;is&lt;/code&gt;. Use sparingly . Make sure you check mostly to see if things are the same object or practically to see if something is &lt;code&gt;None&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;mostly to check for the presence or absence of things.&lt;/li&gt;
&lt;li&gt;like &lt;code&gt;x = None&lt;/code&gt; and then I go check &lt;code&gt;if x is None&lt;/code&gt; …&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;True / False heuristic in Python
&lt;ul&gt;
&lt;li&gt;Nearly everything in Python is true&lt;/li&gt;
&lt;li&gt;except for &lt;code&gt;False&lt;/code&gt;, &lt;code&gt;None&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt; or anything empty (empty lists, dictionaries, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Learnt how working with strings in reverse works
&lt;ul&gt;
&lt;li&gt;if I want the last element in a string, I could reference it by calculating it’s length and lopping one off (since indexes start at 0), like with the string &lt;code&gt;s = 'Halt! Who goes there?'&lt;/code&gt; I could access the last element by &lt;code&gt;s[len(s)-1]&lt;/code&gt; or the last but one, with a &lt;code&gt;s[len(s)-2]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;This is made a lot more convenient by just dropping the &lt;code&gt;len(s)&lt;/code&gt; stuff, just leaving the &lt;code&gt;- numeral&lt;/code&gt; part - &lt;code&gt;s[-1]&lt;/code&gt; or &lt;code&gt;s[-2]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;This makes so much sense in my head now, if what I am doing is counting straight and then subtracting one. I should remember, things sometimes are simpler than they seem :)&lt;br&gt;
For some reason, I always imagined, Python could see the length of my string, so why couldn’t there be a reverse string way of doing things like &lt;code&gt;s.rev[0]&lt;/code&gt; that would just count backwards 😂&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Strings are immutable. They can’t be changed. I can just process a copy and generate new ones, though.&lt;/li&gt;
&lt;li&gt;just realised that the f in f-strings stands for &lt;em&gt;formatted strings&lt;/em&gt;, since when I write raw strings, I use an r for, duh, &lt;em&gt;raw strings&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Slicing involves carving out a small contiguous part out of a larger string. The thing to note is that when I say &lt;code&gt;s[0:4]&lt;/code&gt; it means &lt;em&gt;upto, &lt;strong&gt;but not including&lt;/strong&gt; 4&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;If I say &lt;code&gt;s[0:100]&lt;/code&gt;, slices are forgiving and give me upto the end of my small string, without throwing an error.&lt;/li&gt;
&lt;li&gt;Empty colons in slices imply endings. &lt;code&gt;s[:10]&lt;/code&gt; means start from 0 and go up to 9. Or &lt;code&gt;s[9:]&lt;/code&gt; means start at 9 and go upto the end. Ergo &lt;code&gt;s[:]&lt;/code&gt; means from the beginning to the end.&lt;/li&gt;
&lt;li&gt;I can have step sizes to step over. The default, hidden size is 1. I can step, oh, say every three elements by append &lt;code&gt;:3&lt;/code&gt; to the end of my slice like so, &lt;code&gt;s[0:20:3]&lt;/code&gt;, basically [start&amp;#x1f51a;step size]&lt;/li&gt;
&lt;li&gt;I can also have negative step sizes which will give me the results in reverse. The most common one being -1, because the quickly reverses a string for me (commonly done). But it works with other step sizes too. A -2 will start counting backwards every other character from the end. A reverse slice begins with the end character and then beginning. So &lt;code&gt;s[10:5:-1]&lt;/code&gt; to carve out a slice backwards.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sequences are strings, tuples and lists. They all can be sliced and diced and iterated upon.&lt;/li&gt;
&lt;li&gt;Heuristic, &lt;code&gt;else&lt;/code&gt; in a &lt;code&gt;for&lt;/code&gt; loop is to match stuff when I don’t encounter a &lt;code&gt;break&lt;/code&gt;. the &lt;code&gt;else&lt;/code&gt; part matches the &lt;code&gt;for&lt;/code&gt; to form the &lt;code&gt;for-else&lt;/code&gt; construct, even though the break is inside the for loop&lt;/li&gt;
&lt;li&gt;&lt;code&gt;while&lt;/code&gt; loops are for when you don’t know the end of what you are looking for. there is not finite end. No 0 - 10 happening. You are just searching for something in an amorphous swamp. The swamp is vast, there is no way to say from this end of the swamp to that end.You only give up when you find what you are looking for, or when you decide it’s time to give up (some preset condition).
&lt;ul&gt;
&lt;li&gt;make sure there is a counter that breaks stuff or I might loop forever&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;Learning / Feedback/ Experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Realising why Python notebooks are used. Very, very, very, handy to quickly write prose and code at the same time. It fits my mental model of programming perfectly!&lt;/li&gt;
&lt;li&gt;I keep thinking strings and characters are English and forget to quote them! The number of &lt;code&gt;NameErrors&lt;/code&gt; I get, is not funny.&lt;/li&gt;
&lt;li&gt;Thing that keeps biting me when I write &lt;code&gt;or&lt;/code&gt; statments. I should remember to say &lt;code&gt;if x='blah' or x='meh'&lt;/code&gt;. I keep writing &lt;code&gt;if x='blah' or 'meh'&lt;/code&gt;, &lt;em&gt;which is wrong.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;I keep using a lot of superfluous variables. I should be more intentful. Instead of just printing an expression, I tend to figure out the expression, assign to a variable and then print it. Good for building, probably bad for optimal use. But I won’t worry about it too much now. Just something to improve on in the long term.&lt;/li&gt;
&lt;li&gt;Reuven is a painstakingly methodical teacher. If he’s so good in his videos, I am jealous of folks attending his live classes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythonbasics/" &gt;Read all about my Python basics journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 006 - Starting and Quitting Comprehensions</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-006-starting-and-quitting-comprehensions/</link><pubDate>Mon, 13 Jul 2020 18:21:31 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-006-starting-and-quitting-comprehensions/</guid><description>&lt;p&gt;I know I said, I’d start with the basics, Reuven, but please forgive me this once :)&lt;br&gt;
Will do the rest, bottom up :)&lt;/p&gt;
&lt;p&gt;Have started up with this, because I’m &lt;em&gt;fascinated&lt;/em&gt; with how folks manage to build in so much functionality into short, easy to read statements.&lt;br&gt;
To my mind, comprehensions are the pithy proverbs of the programming world.&lt;br&gt;
So here goes …&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;h3 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;This style of writing code, comes from functional programming&lt;/li&gt;
&lt;li&gt;Functional Programming is another style of writing code
&lt;ul&gt;
&lt;li&gt;It assumes that data is immutable. (Or at least it treats it as such) It does not change the originals I work with. &lt;em&gt;(I assume this means that I always work on a copy or something)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;we work with sequences of data and create new ones based on the old ones &lt;em&gt;(changing case of a sentence, comes to mind)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;There are a bunch of techniques/patterns/heuristics that’ll let me do that&lt;/li&gt;
&lt;li&gt;We can treat functions as data and pass them around as arguments to other functions.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;functools&lt;/code&gt; module assists with writing such code&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Why code in such a manner? Some benefits include them being easier to read, easier to debug, shorter, more understandable.&lt;/li&gt;
&lt;li&gt;Distributed Computing / Multiprocessing across processors and cores/threads makes these techniques more relevant in this day and age&lt;/li&gt;
&lt;li&gt;My personal need is to write easy to read code, like when I see a well crafted list comprehension&lt;/li&gt;
&lt;li&gt;If I want to square a list of numbers, my current go to is to generate a new list, using a for loop. Comprehensions are a better way of doing this&lt;/li&gt;
&lt;li&gt;For loops are far when I want to execute something on each item of something iterable, like a list or a dictionary. when i want to have a statement happen&lt;/li&gt;
&lt;li&gt;If just want to transmute the elements of list into something else, change each element, like square them all above, then comprehensions are my friend&lt;/li&gt;
&lt;li&gt;Here’s a list comprehension to square a list of numbers from the list &lt;code&gt;numbers&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[one_number * one_number for one_number in numbers]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The square brackets make it a list comprehension. If I want dictionary comprehensions, I would abut them with curly braces {}. And if I use (), I’ll get a generator expression (which I know only the bare basics about)&lt;/li&gt;
&lt;li&gt;For loops and comprehensions might look similar, but they really are different&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note:&lt;/strong&gt; whatever expression you use to generate output has to return something. like the square expression above . because what I want to do is catch all my results in a container. functions (like the &lt;code&gt;print&lt;/code&gt; function) that return &lt;code&gt;None&lt;/code&gt; as their result, cannot work here. They will &lt;em&gt;display&lt;/em&gt; stuff, but store only &lt;code&gt;None&lt;/code&gt; in our comprehension container :)&lt;/li&gt;
&lt;li&gt;I can also write the comprehesion over multiple lines (works because they are bounded by the list brackets here or bounded by other brackets elswhere)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;one_number&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;one_number&lt;/span&gt;		 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;one_number&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;here with the breakdown of the lines, the first line becomes my output generator; the expression I want to use and the second line, the data I want to process. Much more readable this way&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;learning / feedback/ experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Exercises today required a bit of head scratching and a bit of research, but were relatively simple&lt;/li&gt;
&lt;li&gt;I should keep in mind that the computer can go crazy too. I kept wondering why my code wouldn’t run and and kept banging my head for an hour. Even Rueven’s solution was what I did. Until I restarted my Jupyter note book and everything worked the way I expected.&lt;/li&gt;
&lt;li&gt;Should have a time limit on how much struggling I do. From the last week, it looks like I am a real sucker for pain otherwise. Half an hour tops and then go look up the solution.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Have reached the second set of exercises and realised why Reuven told me to start with the basics. I failed with the second one in this set. I just know, there is a simple solution and I cannot seem to get it. This basically means … yes … that my foundations are creaky.&lt;br&gt;
Note to self, walk before you can run. By Jove, you should’ve learnt that by now! :)&lt;br&gt;
So this is me, waving goodbye sorrowfully to comprehensions.&lt;br&gt;
Will start with the basic Python course tomorrow.&lt;br&gt;
But I’ll be back soon enough, damn it!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythoncomprehensions/" &gt;Read all about my comprehensions journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 005 - Magic Methods and Winding Up OOP</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-005-magic-methods-and-winding-up-oop/</link><pubDate>Sun, 12 Jul 2020 19:23:05 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-005-magic-methods-and-winding-up-oop/</guid><description>&lt;p&gt;Done with &lt;a href="https://store.lerner.co.il/courses/object-oriented-python/" target="_blank" rel="noreferrer"&gt;Reuven Lerner’s OOP basics&lt;/a&gt;&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 

&lt;h3 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;len&lt;/code&gt; does the right thing across multiple types of objects.
&lt;ul&gt;
&lt;li&gt;it counts characters in a string, elements in a list, and key-value pairs in a dictionary. how does it know how to do that?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;that is because &lt;code&gt;len&lt;/code&gt; uses a magic method (methods that have a &lt;code&gt;__&lt;/code&gt; for a prefix and suffix)
&lt;ul&gt;
&lt;li&gt;len uses the &lt;code&gt;__len__&lt;/code&gt; method which i can use in my own classes, to implement a &lt;code&gt;len&lt;/code&gt; method for my classes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If I choose to do so, I need to realise what those underlying methods expect to return and return the same type in my classes. &lt;code&gt;__len__&lt;/code&gt; expects to return integers, so when I implement it in my classes, I ought not to return a string. Once again &lt;a href="https://store.lerner.co.il/courses/object-oriented-python/" target="_blank" rel="noreferrer"&gt;Reuven&lt;/a&gt; strongly suggests using common sense :)&lt;/li&gt;
&lt;li&gt;same thing when i try to print something. it calls the magic method &lt;code&gt;__str__&lt;/code&gt; to do stuff. or if i try to do repr to check for raw representations, the &lt;code&gt;__repr__&lt;/code&gt; method is called.&lt;/li&gt;
&lt;li&gt;Python is filled with these methods which I can use to allow my classes to have standard Python like functionality. like a &lt;code&gt;print(doggie)&lt;/code&gt; should give me details about the cute pup object i just created, if I have taken the time and attention to implement the &lt;code&gt;__str__&lt;/code&gt; or &lt;code&gt;__repr__&lt;/code&gt; methods&lt;/li&gt;
&lt;li&gt;most of these methods come with the base primitive class &lt;code&gt;object&lt;/code&gt; which every class inherits from. so i get them for free. and then i can override them and customise them to what I want to show.&lt;/li&gt;
&lt;li&gt;people try standard methods on new objects. implementing them is much better than creating my own and asking people to use ’em.&lt;/li&gt;
&lt;li&gt;if both are equal or really similar, ok to just use only &lt;code&gt;__repr__&lt;/code&gt;. later when I have experience and other needs, i can implement &lt;code&gt;__str__&lt;/code&gt; too&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;learning / feedback/ experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Despite warning myself above, I went ahead and made the mistake of returning a whole lovely string, instead of an integer, when I tried to implement the &lt;code&gt;len&lt;/code&gt; method on my class XD&lt;/li&gt;
&lt;li&gt;and then I forgot to add the f prefix to an f-string and wondered why it was not interpolating for nearly 30 mins&lt;/li&gt;
&lt;li&gt;Reuven has a wry sense of humour. In one of my exercises I get to create classes of animals for a zoo, with various attributes such as colour and legs and so forth. Then he has me put them in cages. After making me put 2 sheep in a cage with a wolf, he wonders if the legs of the sheep ought to be reduced or not XD&lt;/li&gt;
&lt;li&gt;The number of typos I am making is staggering. Missing colons, missing quotes, missing brackets. If this is Python, I shudder to think how I’d fare if I picked up a static language to learn XD&lt;/li&gt;
&lt;li&gt;Wasted another half an hour because I spelt colours with capitals like Black and then later looked for black and was tearing my hair out, because I knew there &lt;em&gt;were&lt;/em&gt; black animals and why in tarnation, would Python not show me them XD&lt;/li&gt;
&lt;li&gt;Saw Reuven do nested comprehensions and now I want to do that too! it took him &lt;em&gt;one&lt;/em&gt; well thought out line to do what I did in 2 multiline functions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;Final Words
 &lt;div id="final-words" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#final-words" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;This was amazing!&lt;br&gt;
I learnt so much about classes and the way they work.&lt;br&gt;
Reuven has a very joyful pedagogy.&lt;br&gt;
I love him go hahahaha like Santa Claus.&lt;br&gt;
I love the fact that he makes mistakes.&lt;br&gt;
I love that for every problem, he poses, he has various approaches.&lt;br&gt;
His fluency shines through every lesson.&lt;br&gt;
I got lucky with the &lt;a href="https://www.humblebundle.com/software/python-programming-software" target="_blank" rel="noreferrer"&gt;Pycharm Humble Bundle&lt;/a&gt;.&lt;br&gt;
But I loved this so much, that I am going to sign up for all the &lt;a href="https://store.lerner.co.il/courses/" target="_blank" rel="noreferrer"&gt;Lerner courses&lt;/a&gt;, I possibly can.&lt;br&gt;
Beginning with the basics.&lt;br&gt;
If OOP is any indicator, the journey is going to be lots of fun.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythonoop/" &gt;Read all about my OOP journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 004 - Class Attributes and Inheritance</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-004-class-attributes-and-inheritance/</link><pubDate>Sat, 11 Jul 2020 17:47:49 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-004-class-attributes-and-inheritance/</guid><description>&lt;p&gt;Learnt about Class Attributes and Inheritance, today.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;h3 class="relative group"&gt;Notes
 &lt;div id="notes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The way we &lt;em&gt;write&lt;/em&gt; functions/methods and define classes might look similar,&lt;br&gt;
&lt;code&gt;class CrazyTalk(object):&lt;/code&gt; and &lt;code&gt;def how_now_brown_cow():&lt;/code&gt;&lt;br&gt;
The way they behave/execute, though is wildly different.&lt;br&gt;
Classes run / spring to life as soon as the program launches.&lt;br&gt;
Functions don’t, unless they are called.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Realised that objects are containers.&lt;br&gt;
What you can do with the object depends on what is in it.&lt;br&gt;
Does it hold a dictionary with various methods to modify it?&lt;br&gt;
Does it just hold a bunch of text?&lt;br&gt;
Reminds me of media formats as containers.&lt;br&gt;
A mp4 file is not just an mp4 file.&lt;br&gt;
The video resolution could vary from one file to another.&lt;br&gt;
The type of audio encoding could be different.&lt;br&gt;
It could carry multiple streams of audio or video or other metadata.&lt;br&gt;
What you can do with the file or where you can play it, depends on what is &lt;em&gt;inside&lt;/em&gt; it.&lt;br&gt;
Same with classes and objects.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Any thing that we define inside a class, is an attribute. (methods, variables etc.) Reuven made a point of stressing this, so writing this down.&lt;br&gt;
If I just define a variable and try to use it, I’ll get an &lt;code&gt;UnboundLocalError&lt;/code&gt;. I need to use &lt;code&gt;className.variable&lt;/code&gt; when I call it.&lt;br&gt;
So I can just write a variable like so&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeClass&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;crazy_var&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Muahahahaha&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SomeClass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;crazy_var&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;and then call it with &lt;code&gt;SomeClass.crazy_var&lt;/code&gt; or when I do it &lt;em&gt;after&lt;/em&gt; I define &lt;code&gt;__init__&lt;/code&gt; then I can just directly define it as &lt;code&gt;SomeClass.crazy_var&lt;/code&gt; (which sounds more logical to me), like so&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeClass&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SomeClass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;crazy_var&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SomeClass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;crazy_var&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Muahahahaha&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;br&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A class attribute is associated with the class itself, while object attributes are associated with the objects that are created from the class.&lt;br&gt;
So with &lt;code&gt;car.wheels&lt;/code&gt;, the wheels are associated with the car class, but when I use car to create a Ferrari object, and it has &lt;code&gt;Ferrari.white_wall_rims&lt;/code&gt; the rims are an instance attribute that belong to the Ferrari object / instance and not the car class it was made of.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If I ask for an object’s attribute and it isn’t there, then Python goes looking upwards to check if the class has it. In the previous point, if I go &lt;code&gt;Ferrari.wheels&lt;/code&gt; it’ll work, because Python will check the &lt;code&gt;Ferrari&lt;/code&gt; object and if there are no wheels in there, it’ll go check &lt;code&gt;cars&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Name your attributes carefully.&lt;br&gt;
Don’t have the same names between class attributes and object attributes.&lt;br&gt;
Use your head!&lt;br&gt;
Don’t do that!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When we create a class, that is identical to another with one or two teeny exceptions, when they are so similar that I base the new one on the old one — those new classe are said to be &lt;em&gt;inheriting&lt;/em&gt; from the old one. They have an &lt;code&gt;is-a&lt;/code&gt; relationship.&lt;br&gt;
For e.g. a doggie &lt;code&gt;is-a&lt;/code&gt; floofy animal.&lt;br&gt;
A teddy bear &lt;code&gt;is-a&lt;/code&gt; floofy animal too.&lt;br&gt;
Both of them &lt;em&gt;inherit&lt;/em&gt; their floofiness from the floofy animal class.&lt;br&gt;
I can write that as &lt;code&gt;class Doggie(FloofyAnimal):&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Methods are attributes on a class. They are not attributes of the instance object.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you have an &lt;code&gt;__init__&lt;/code&gt; method in your inherited class, the instance will not look for &lt;code&gt;__init__&lt;/code&gt; variables/details in the parent class.&lt;br&gt;
(it’s like this in Python, Java/C++ can get stuff from the parent / grandparent. this is so, because with Python, everything is a live object whereas with the other languages, the &lt;code&gt;__init__&lt;/code&gt; stuff are declarative rules with orders of precedence (a la CSS) and the class comes alive only after all the rules are parsed.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you &lt;em&gt;do&lt;/em&gt; want to inherit something from the parents &lt;code&gt;__init__&lt;/code&gt;, then you explictly get it by using &lt;code&gt;super()&lt;/code&gt;. as in get it from the supervisor above, i guess? I’d add a line like this to my doggie class&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Python" data-lang="Python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Doggie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FloofyAnimal&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&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;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		&lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;        And then it will pull the name from the Floofy Animal class if it’s in there.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use inheritance only when it makes sense. No need to go hog wild.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;learning / feedback/ experiences from doing exercises
 &lt;div id="learning--feedback-experiences-from-doing-exercises" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#learning--feedback-experiences-from-doing-exercises" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Slowly getting the hang of list comprehensions. I should practice them more.&lt;br&gt;
Because they are very easy to read later.&lt;br&gt;
Just that, I get very confused while writing them.&lt;/li&gt;
&lt;li&gt;Doing the exercises is slowly getting easier&lt;/li&gt;
&lt;li&gt;&lt;a href="https://store.lerner.co.il/courses/object-oriented-python/" target="_blank" rel="noreferrer"&gt;Reuven&lt;/a&gt; is very hands on, has tons of jokes, and makes tons of typos.&lt;br&gt;
I’ve gone from eyes glazed, looking at the his code and struggling to understand to yelling at the screen when he mistypes something :)&lt;br&gt;
Shows that I am learning :)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://pythontutor.com/visualize.html#mode=display" target="_blank" rel="noreferrer"&gt;Python Tutor&lt;/a&gt; is very handy to see the the thousands of mistakes I make. &lt;br&gt;
Even that interface does not quite make me understand, but it gets me 80% of the way there.&lt;br&gt;
&lt;em&gt;(like when a &lt;code&gt;return&lt;/code&gt; statement of mine was nested in a loop instead of being out at the end of the for statement.)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythonoop/" &gt;Read all about my OOP journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 003 - Methods</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-003-methods/</link><pubDate>Fri, 10 Jul 2020 19:44:34 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-003-methods/</guid><description>&lt;p&gt;Learnt about methods today.&lt;br&gt;
Notes follow …&lt;/p&gt;
&lt;p&gt;My understanding about methods?
They are functions in classes that help me manipulate the data the objects contain when they are created.&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 
&lt;p&gt;I have been using something them subconsciously all along.&lt;br&gt;
The &lt;code&gt;__init__&lt;/code&gt; method, that is called/run automatically every time an object is created.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Aha&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
A nice way to unpack the &lt;code&gt;.&lt;/code&gt;notation i use&lt;/p&gt;
&lt;p&gt;Let’s say I have a class &lt;code&gt;SquareNumbers&lt;/code&gt; that has a function (method) ­— &lt;code&gt;x2&lt;/code&gt; — that will, you know, square a number.&lt;br&gt;
And then I create an object &lt;code&gt;f&lt;/code&gt; with a number and call the square method on it.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SquareNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;br/&gt; 
&lt;p&gt;What I am actually doing, when I call &lt;code&gt;f.x2()&lt;/code&gt; can also be written as &lt;code&gt;SquareNumbers.x2(f)&lt;/code&gt;.&lt;br&gt;
I am sending a message &lt;code&gt;x2&lt;/code&gt; to the &lt;code&gt;f&lt;/code&gt; object, and it will respond with however/whatever it is programmed to.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;When I define object variables in a class, I should refer to them with a &lt;code&gt;self.variable&lt;/code&gt; when I define methods.&lt;br&gt;
I figure because each object can have it’s own set of values for those variables and I want Python to find them properly.&lt;/p&gt;
&lt;p&gt;Also learnt this is not the case in most other languages.&lt;br&gt;
With some languages, you set and get values of variables of the object, using even more explicit methods, call getters &lt;em&gt;(accessors)&lt;/em&gt; and setters &lt;em&gt;(mutators).&lt;/em&gt;&lt;br&gt;
These are just fancy names for explicit methods to assign and then read data from the variables of a class.&lt;br&gt;
In our example above, I would probably have a &lt;code&gt;set_x&lt;/code&gt; function defined to set the value of &lt;code&gt;x&lt;/code&gt; like &lt;code&gt;f.set_x(20)&lt;/code&gt; (along with a corresponding &lt;code&gt;get_x&lt;/code&gt; to read it)&lt;/p&gt;
&lt;p&gt;This could also be because other programs have different categories of data (private, public) in classes, while Python does not.&lt;br&gt;
Just differences in language design philosophies, I guess.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I can create an class, that can use objects created by other other classes.&lt;br&gt;
For example, I can create a book class and then have several book objects.&lt;br&gt;
And then create a new bookshelf class, whose objects can take all my books and put them in a list/library of sorts&lt;br&gt;
This kind of relationship is called a &lt;code&gt;has-a&lt;/code&gt; relationship in programming parlance.&lt;br&gt;
(like my bookshelf &lt;code&gt;has-a&lt;/code&gt; book on it)&lt;br&gt;
It’s also called composition. I am composing a new class from other classes.&lt;br&gt;
I can do what I want with the list in the bookshelf.&lt;br&gt;
I could take their prices (if i added them) and then sum them up.&lt;br&gt;
I could take the titles and list them alphabetically, or by author.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Aha&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So what is becoming clearer to me is that classes can take user needs, and express them naturally, while leaving the creation of these calculations and listings and sortings with the programming language primitives behind the scenes.&lt;br&gt;
For my book shelf i could just go &lt;code&gt;shelf.sort.title.alphabetical()&lt;/code&gt;&lt;br&gt;
Or if I have a new need tomorrow, hmm, like finding the total prices of all my books, I could just add a &lt;code&gt;sum&lt;/code&gt; method to my bookshelf and I could go &lt;code&gt;shelf.sum()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It basically makes my code, more human. More easy to understand. More natural.&lt;/p&gt;
&lt;p&gt;Another thing that just occured is that I could swap out the primitives beneath the classes. If I find a faster, better way to sum up prices, I could just use that. While the way I would sum the books would still remain &lt;code&gt;shelf.sum()&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Doing the exercises, I realise that I need to learn a lot more Python vocabulary.&lt;br&gt;
I somehow managed to gather a number of variables into a list.&lt;br&gt;
But when I attempted to do it again, it threw an error.&lt;br&gt;
And that’s when I learnt I could &lt;code&gt;extend&lt;/code&gt; a list.&lt;br&gt;
Lots more practice needed!&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;self&lt;/code&gt; thing bit me hard!&lt;br&gt;
I spent at least a 45 minutes trying to find out why my method could not find a variable, despite me defining it correctly. I should’ve obviously referred to it with &lt;code&gt;self.variable&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;Time to call it a day.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythonoop/" &gt;Read all about my OOP journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 002 - Basic Exercises</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-002-basic-exercises/</link><pubDate>Thu, 09 Jul 2020 19:15:05 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-002-basic-exercises/</guid><description>&lt;p&gt;Did a few exercises today.&lt;br&gt;
They were simple.&lt;br&gt;
Create a few classes, change them, modify them, use a list as an attribute and so on.&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 
&lt;p&gt;In a couple of ways, this was just what I needed.&lt;br&gt;
One, I had an extremely busy day at work, and so I did not have the brain power to do anything complex, so I needed the bar really low any way.&lt;br&gt;
And two, I’ve realised, that I have always tried to just read a book and then leap mountains. I don’t know why. I must be a sucker for pain. And then when stuff does not work, I sulk and get frustrated.&lt;br&gt;
Easing into hard topics like this, makes it more enjoyable for me and I learn better.&lt;br&gt;
This is a meta skill, I should remember to use.&lt;br&gt;
Come to think of it, everything I have learnt recently, &lt;em&gt;actually learnt,&lt;/em&gt; has been this way.&lt;br&gt;
I learnt Dvorak and touch typing, slowly, key by single key.&lt;br&gt;
I learnt to diet and lose weight, by tens of grammes in the beginning.&lt;/p&gt;
&lt;p&gt;So, note to self.&lt;br&gt;
Start small.&lt;br&gt;
Do the work.&lt;br&gt;
Show up daily.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://janusworx.com/tags/pythonoop/" &gt;Read all about my OOP journey here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 001 - Beginning With Classes</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-001-beginning-with-classes/</link><pubDate>Wed, 08 Jul 2020 18:08:05 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-001-beginning-with-classes/</guid><description>&lt;p&gt;Notes I’ve taken from &lt;a href="https://store.lerner.co.il/courses/object-oriented-python/" target="_blank" rel="noreferrer"&gt;the videos I watched, today&lt;/a&gt;.
This is my attempt at Feynman-ing &lt;em&gt;(below)&lt;/em&gt;, what I learnt so far.&lt;/p&gt;
&lt;p&gt;Classes and Object Oriented Programming started to come together for me, when I saw &lt;a href="https://ele.janusworx.com/@jason/104295640623569929" target="_blank" rel="noreferrer"&gt;Kushal using them&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To use my father’s carpentry analogy, I could in theory just hammer nails into wood to join them.&lt;br&gt;
But to make a really strong joint, I could use other methods.&lt;br&gt;
I could screw pieces of wood together, which is markedly better than just nailing them.&lt;br&gt;
I could chisel wood and create a dovetail or mortise joint.&lt;/p&gt;
&lt;p&gt;So it all comes down to understanding what I want to do and figuring out the best technique to get it done.&lt;/p&gt;
&lt;!-- TEASER_END --&gt; 
&lt;p&gt;Like I mentioned in the toot, I could in theory just kludge together all my primitives and create something.&lt;br&gt;
But, if I want to create something beautiful and something that I (and others) can understand, I need to use a different method.&lt;br&gt;
Object Oriented Programming, is a popular one.&lt;/p&gt;

&lt;h3 class="relative group"&gt;Objects and Types (In Python)
 &lt;div id="objects-and-types-in-python" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#objects-and-types-in-python" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;We have objects and types/classes.&lt;br&gt;
We can think of them like we do about cells in our body.&lt;br&gt;
Python for the most part is natively made of objects.&lt;br&gt;
Nearly every primitive I have come across in Python is an object.&lt;br&gt;
Strings are objects and work a certain way / Skin cells work a certain way.&lt;br&gt;
Dictionaries work a certain weay / Optical cells in the eye, work in an very specific manner.&lt;br&gt;
Integers are objects and have their own ways of doing things, as do white blood corpuscles.&lt;/p&gt;
&lt;p&gt;Objects are a special type of &lt;em&gt;something.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A class makes objects.&lt;br&gt;
An int class makes integers. A string class makes strings. And so on and so forth.&lt;/p&gt;
&lt;p&gt;With Python even classes (the constructors) are objects.&lt;br&gt;
So, there must be some kind of God / Creator thing that makes these primitives / originator classes.&lt;br&gt;
And there is.&lt;br&gt;
It’s the &lt;code&gt;type&lt;/code&gt; class.&lt;br&gt;
It’s the base class, the &lt;a href="https://en.wikipedia.org/wiki/Turtles_all_the_way_down" target="_blank" rel="noreferrer"&gt;bottom turtle&lt;/a&gt;, if you will.&lt;br&gt;
The &lt;code&gt;type&lt;/code&gt; class creates all these primitive classes, which we then use to create other objects for our use.&lt;br&gt;
The type of the &lt;code&gt;int&lt;/code&gt; &lt;em&gt;(integer)&lt;/em&gt; class is &lt;code&gt;type&lt;/code&gt; as is the type of the &lt;code&gt;str&lt;/code&gt; &lt;em&gt;(string)&lt;/em&gt; class.&lt;br&gt;
They are all objects of type &lt;code&gt;type&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Which basically, again to use a physical analogy means that &lt;code&gt;type&lt;/code&gt; is the iron forge, which i then use to create factories, which i then use to fashion usable things.&lt;br&gt;
The forge lets me create lug nuts and chassis’ and then I take all these, to create a car factory, which lets me make cars of different types and sizes, with varying amounts of power.&lt;br&gt;
The forge lets me create some mixer, which i can then choose to setup different sorts of mixer factories. Some can make ice cream, some can make porridge.&lt;br&gt;
&lt;code&gt;type&lt;/code&gt; (the forge), creates the int class (the factory), which lets me create all sorts of integer numbers to play around with.&lt;br&gt;
&lt;code&gt;type&lt;/code&gt; (the forge), creates the dictionary class (the factory), which lets me store and sling data about in various ways.&lt;/p&gt;
&lt;p&gt;Note: This might not be true of other programming languages (for e.g. int might be a base primitive.)&lt;/p&gt;

&lt;h3 class="relative group"&gt;Attributes
 &lt;div id="attributes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#attributes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;Every class can have attributes (data, or methods to manipulate data).&lt;br&gt;
Those attribute themselves could be classes, having their own attributes.&lt;/p&gt;
&lt;p&gt;Now each of those takes memory.&lt;br&gt;
Python doesn’t gobble up all our memory however, because some (most?) objects share memory.&lt;/p&gt;
&lt;p&gt;Run &lt;code&gt;dir&lt;/code&gt; on an object to get it’s attributes.&lt;br&gt;
For example, I could do this on the &lt;code&gt;str&lt;/code&gt; class to see what it has.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;__add__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__class__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__contains__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__delattr__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__dir__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__doc__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__eq__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__format__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__ge__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__getattribute__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__getitem__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__getnewargs__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__gt__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__hash__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__init__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__init_subclass__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__iter__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__le__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__len__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__lt__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__mod__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__mul__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__ne__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__new__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__reduce__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__reduce_ex__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__repr__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__rmod__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__rmul__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__setattr__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__sizeof__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__str__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__subclasshook__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;capitalize&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;casefold&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;center&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;count&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;encode&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;endswith&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;expandtabs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;find&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;format&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;format_map&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;index&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;isalnum&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;isalpha&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;isascii&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;isdecimal&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;isdigit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;isidentifier&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;islower&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;isnumeric&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;isprintable&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;isspace&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;istitle&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;isupper&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;join&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;ljust&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;lower&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;lstrip&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;maketrans&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;partition&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;replace&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rfind&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rindex&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rjust&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rpartition&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rsplit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rstrip&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;split&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;splitlines&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;startswith&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;strip&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;swapcase&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;translate&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;upper&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;zfill&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I spy with my little eye, that any string object lets itself be split or joined or lets its case be altered and much, much more!&lt;/p&gt;
&lt;p&gt;I can go into any object I want (with few exceptions) and change its attributes!&lt;br&gt;
For example, I type &lt;code&gt;os.sep&lt;/code&gt; to get the path separator. (on a linux machine it’s &lt;code&gt;/&lt;/code&gt; and on windows it’d be &lt;code&gt;\&lt;/code&gt; and if python ever ran on classic Mac os I guess it’d be &lt;code&gt;:&lt;/code&gt;&lt;br&gt;
I can just change &lt;code&gt;os.sep&lt;/code&gt; to be &lt;em&gt;!&lt;/em&gt; or &lt;em&gt;hahaha&lt;/em&gt; or whatever i want!&lt;br&gt;
Or I could just add whatever attribute I want to any object!&lt;br&gt;
In short, I can set and get attributes on any object I want!&lt;br&gt;
Sounds pretty free-ing! Will have to see what this means in practice!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Aha&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
The inbuilt functions that I have learnt are not the norm.&lt;br&gt;
Most code is written in classes and functions are available as methods of those classes.&lt;br&gt;
Ruby natively works this way.&lt;br&gt;
Python pragmatically, has created some functions as primitives.&lt;br&gt;
(One possible reason could be, for example, rather than have a &lt;code&gt;len&lt;/code&gt; method on every in built class, they musta thought it easier to create a primitive &lt;code&gt;len&lt;/code&gt; function that worked on different classes and data types)&lt;br&gt;
In real life (and across programming languages) I should mostly be looking at object.method(), for e.g. &lt;code&gt;some_list.pop()&lt;/code&gt;&lt;br&gt;
If I want to look at how to manipulate something, the general heuristic is to look at methods first. Does an object support manipulating itself through itself? After all, it knows itself best! :)&lt;/p&gt;
&lt;p&gt;If I want to know what methods an object supports, I can of course call &lt;code&gt;dir&lt;/code&gt; on it, but a better cleaner way is to call &lt;code&gt;help&lt;/code&gt; on it. (&lt;code&gt;help(list)&lt;/code&gt;). It shows, more clearly, the methods an object supports.&lt;/p&gt;

&lt;h3 class="relative group"&gt;Why Classes
 &lt;div id="why-classes" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-classes" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;Do I &lt;em&gt;need&lt;/em&gt; to create classes?&lt;br&gt;
Of course not, I have been creating programs without them all these months.&lt;br&gt;
A couple of reasons I’d create a class,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;To stop kludginess. I don’t to expose a list of dictionaries, that contain more dictionaries that have lists as their values. better to abstract them away from the user (future me) and present simpler interfaces.&lt;/li&gt;
&lt;li&gt;I love to write well crafted prose. Classes represent complete sentences in human language. Nouns and verbs amounting to a sentence that makes sense and is well crafted.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 class="relative group"&gt;How do i create a class
 &lt;div id="how-do-i-create-a-class" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#how-do-i-create-a-class" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Aha&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
Just realised that when I create a class, I am creating a new type of primitive for myself.&lt;br&gt;
My own data type!&lt;br&gt;
I can create my own numbering system if i want to!&lt;br&gt;
&lt;em&gt;Muahahahahahahaha&lt;/em&gt;&lt;br&gt;
&lt;em&gt;(comes back to reality)&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;somethingsomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;pass&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;br/&gt;
That is all I need. 
Just to say class, create a class with this here name! And *Abracadabra-Alakazoom*, Python goes ahead and creates a new class for us! 
&lt;p&gt;As I wrote above, this is a factory, to create new &lt;code&gt;somethingsomething&lt;/code&gt; objects.&lt;br&gt;
I can do that by just assigning it a name. Like Iron man summoning his suit out of thin air.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;somethingblue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;somethingsomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;br/&gt; 
And boom! The object `somethingblue` materialises!
&lt;p&gt;This is just a blank template, of course.&lt;br&gt;
I cannot do much with this. (Right now, I don’t even know, what I can imbue this with, or use it for :P)&lt;br&gt;
So I guess, the rest of the course will probably deal with how to make classes work and function the way I want them to.&lt;/p&gt;
&lt;p&gt;I can add attributes to my classes just by declaring them.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;somethingblue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;sky&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;somethingblue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;liquid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ocean&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;somethingblue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x0000FF&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;br/&gt;
And then i could `dir(somethingblue)` and it will give me them attributes, along with a list of everything it has inherited from the parent class (here the `type` class)
&lt;p&gt;A neater way of looking at only what I defined, is to do &lt;code&gt;vars(somethingblue)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Aha&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
Heuristic - While i &lt;em&gt;can&lt;/em&gt; add attributes willy-nilly to any object I want to, it’s bad form.&lt;br&gt;
The idea being that the factory (the class) should ideally provide a set of default attributes and values, so that not too much monkeying is required.&lt;br&gt;
This process/template of assigning sane attributes is called a constructor.&lt;/p&gt;
&lt;p&gt;The way we create a class is two fold &lt;em&gt;(&lt;a href="https://en.wikipedia.org/wiki/Smalltalk" target="_blank" rel="noreferrer"&gt;very Smalltalk-esque&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I create a class.&lt;/li&gt;
&lt;li&gt;I add its attributes.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So when Python goes to create an object of the class, it does it like quite similarly&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it creates as new object when i say object = class_whatever(), using the &lt;code&gt;__new__&lt;/code&gt; method&lt;/li&gt;
&lt;li&gt;it then goes looking to see if there is an &lt;code&gt;__init__&lt;/code&gt; method in the class, and if it exists, then to use that to setup the default attributes&lt;/li&gt;
&lt;li&gt;it uses the &lt;code&gt;self&lt;/code&gt; (by convention) argument, to assign those attributes to the object. (I am applying shampoo to mine own &lt;em&gt;self&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;and &lt;em&gt;then&lt;/em&gt; assigns it to the variable that’s supposed to catch the instance.&lt;br&gt;
&lt;em&gt;(I always somehow assumed it was the other way around. A variable in memory was assigned and then created like a building. This is more nature like. Stuff grows and then is assigned a name)&lt;/em&gt;&lt;br&gt;
I can absolutely go do what I want, assign attributes however, but if I want to stay sane, I’d rather follow convention&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And that’s about all I studied today.&lt;br&gt;
Follow along the my &lt;a href="https://janusworx.com/tags/pythonoop/" &gt;Python OOP train&lt;/a&gt; here.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;P.S. The Feynman Method.&lt;/p&gt;
&lt;center&gt;&lt;iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/tkm0TNFzIeg" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;&lt;/center&gt;</description></item><item><title>A Hundred Days of Code, Day 000 - Begin Again</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-000-begin-again/</link><pubDate>Wed, 08 Jul 2020 11:01:33 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-000-begin-again/</guid><description>&lt;p&gt;How do I begin this post?&lt;/p&gt;
&lt;p&gt;By simply beginning :) Again!&lt;/p&gt;
&lt;p&gt;This probably is the fourth (or is it fifth) time, I’ll be attempting to learn how to program.&lt;br&gt;
And probably the same number of attempts at #100DaysOfCode.&lt;br&gt;
I did &lt;a href="https://janusworx.com/blog/a-hundred-days-of-code-day-047/" target="_blank" rel="noreferrer"&gt;47 days&lt;/a&gt; last time and &lt;a href="https://janusworx.com/100daysofcode-day-037-videos-final-day/" target="_blank" rel="noreferrer"&gt;37 days&lt;/a&gt; before that.&lt;/p&gt;
&lt;p&gt;I will try my utmost to go the distance this time.&lt;br&gt;
Because even if I didn’t complete a full run, I still learnt tonnes from all my previous efforts.&lt;br&gt;
I do have a beginner’s grasp of Python.&lt;br&gt;
And I hope get even better, much better, this time.&lt;/p&gt;
&lt;p&gt;What am I going to do?&lt;br&gt;
Well, I want to do Miguel Grinberg’s &lt;a href="https://courses.miguelgrinberg.com/p/flask-mega-tutorial" target="_blank" rel="noreferrer"&gt;Flask Course&lt;/a&gt;, but as I stumbled through it the last time, and when I read other folks’ code, I realised that I need to get much better at understanding Object Oriented Programming.&lt;/p&gt;
&lt;p&gt;So that’ll be the focus now.&lt;br&gt;
And Reuven Lerner’s &lt;a href="https://store.lerner.co.il/courses/object-oriented-python/" target="_blank" rel="noreferrer"&gt;OOP Course&lt;/a&gt; is what is going to help me.&lt;/p&gt;
&lt;p&gt;So here I set sail again …&lt;br&gt;
&lt;a href="https://youtu.be/aXWBQHxkYx4" target="_blank" rel="noreferrer"&gt;Now, bring me that horizon!&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Hiatus!</title><link>https://janusworx.com/personal/hiatus/</link><pubDate>Thu, 18 Jun 2020 09:10:31 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/personal/hiatus/</guid><description>&lt;p&gt;Lost a friend to the virus last night.&lt;br&gt;
&lt;em&gt;And&lt;/em&gt; a shit-ton of personal issues have cropped up at the same time.&lt;/p&gt;
&lt;p&gt;Need to go handle and process all of this.&lt;br&gt;
Will be back, when I am back.&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 047</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-047/</link><pubDate>Wed, 17 Jun 2020 11:05:49 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-047/</guid><description>&lt;p&gt;&lt;a href="https://janusworx.com/tags/flask/" &gt;Follow my whole plodding, Flask journey here.&lt;/a&gt;&lt;br&gt;
Crashed and burned even harder today.&lt;br&gt;
Tried to retrace my steps and did all the exercises again.&lt;br&gt;
I reached, once more, all the way upto the forms chapter and it just does not work. Now it won’t even display my login page.&lt;/p&gt;
&lt;p&gt;Was it worth doing?&lt;br&gt;
Oh yes.&lt;br&gt;
I gained a much better understanding of how Flask works, of what is required where.&lt;br&gt;
Will work once more at the login page tomorrow.&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 046</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-046/</link><pubDate>Tue, 16 Jun 2020 10:12:01 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-046/</guid><description>&lt;p&gt;&lt;a href="https://janusworx.com/tags/flask/" &gt;Follow my whole plodding flask journey here.&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Am still stuck at where I was yesterday.&lt;br&gt;
But made a tiny bit of progress.&lt;/p&gt;
&lt;p&gt;Yesterday, it would not even submit the form.&lt;br&gt;
And now I got it to do that.&lt;br&gt;
How? I had forgotten to close the form tag.&lt;/p&gt;
&lt;p&gt;Now while I see that it is posting perfectly in the terminal, I cannot get it to reply with a message saying that I indeed have logged in.&lt;/p&gt;
&lt;p&gt;Will start watching the videos &lt;em&gt;again&lt;/em&gt; tomorrow, to see if I have missed something.&lt;br&gt;
One thing that I am doing different from &lt;a href="https://courses.miguelgrinberg.com/p/flask-mega-tutorial" target="_blank" rel="noreferrer"&gt;the course&lt;/a&gt;, is that I am using the new style &lt;a href="https://realpython.com/python-f-strings/" target="_blank" rel="noreferrer"&gt;&lt;em&gt;f-strings&lt;/em&gt;&lt;/a&gt;, while the course uses a slightly older style.&lt;br&gt;
Could it be, that some flask module might not like it?&lt;br&gt;
Will work at it tomorrow and write down, what I figure out.&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 045</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-045/</link><pubDate>Mon, 15 Jun 2020 10:27:48 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-045/</guid><description>&lt;p&gt;&lt;a href="https://janusworx.com/tags/flask/" &gt;Follow my whole plodding journey here.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Wrote a basic login form today.&lt;br&gt;
Short story short, it shows up, but it does not respond like Miguel shows in &lt;a href="https://courses.miguelgrinberg.com/p/flask-mega-tutorial" target="_blank" rel="noreferrer"&gt;the course&lt;/a&gt;. It justs sits there … staring back at me … like an obstinate goat.&lt;/p&gt;
&lt;p&gt;Will go spelunking into what I could have done wrong, tomorrow.&lt;/p&gt;
&lt;p&gt;Learnt about adding routes and creating views and making templates.&lt;br&gt;
Thoroughly confused though.&lt;br&gt;
While I am dumbly following instructions right now, what I don’t get, is what do I need to write first? It all seems very circular to me.&lt;br&gt;
What comes first? The route, the form, the template, the chicken or the egg?&lt;/p&gt;
&lt;p&gt;Hopefully, I will gain clarity as I progress.&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 044</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-044/</link><pubDate>Sat, 13 Jun 2020 12:44:38 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-044/</guid><description>&lt;p&gt;Continuing the &lt;a href="https://courses.miguelgrinberg.com/p/flask-mega-tutorial" target="_blank" rel="noreferrer"&gt;Flask&lt;/a&gt; course.&lt;/p&gt;
&lt;p&gt;Learnt about seperation of concerns today.&lt;br&gt;
To me that means that I should try to keep related things together and disparate stuff apart.&lt;br&gt;
Case in point, we&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; created a seperate file &lt;code&gt;config.py&lt;/code&gt; to store the variables about the program in. And then to kind of secure it even more, instead of hardcoding the password in the file, it now looks for an environment variable, which I need to set before running the program.&lt;br&gt;
Another example was when we created a seperate file to process input &lt;em&gt;(for our logins)&lt;/em&gt; and then put all the login, password etc. fields in there.
This feels good. Feels like I am learning best practices and good habits already.&lt;/p&gt;
&lt;p&gt;The file I created to process login input, is called a form &lt;em&gt;(as in fill in this form? guess so)&lt;/em&gt; and uses the &lt;a href="https://wtforms.readthedocs.io/" target="_blank" rel="noreferrer"&gt;&lt;code&gt;WTForms&lt;/code&gt;&lt;/a&gt; package to do the heavy lifting.&lt;br&gt;
And that was where I learnt my next bit. Not only is Flask, made of modular pieces, it also has an ecosystem of various other modules &lt;em&gt;(called flask extensions)&lt;/em&gt; that give it extra functionality, oomph and power.&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;And here’s where I called it a day.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Who we? Why, Miguel the instructor and me, of course XD&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;WTForms is an example&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>A Hundred Days of Code, Day 043</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-043/</link><pubDate>Fri, 12 Jun 2020 13:11:40 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-043/</guid><description>&lt;p&gt;Continuing with the &lt;a href="https://courses.miguelgrinberg.com/p/flask-mega-tutorial" target="_blank" rel="noreferrer"&gt;Flask&lt;/a&gt; course.&lt;/p&gt;
&lt;p&gt;Today I learnt about how to loop, using Jinja loop blocks.&lt;br&gt;
The syntax is slowly becoming clear to me.&lt;br&gt;
Everything python related in enclosed is &lt;code&gt;{% … %}&lt;/code&gt; blocks, except for variables which use their own &lt;code&gt;{{ … }}&lt;/code&gt; syntax.&lt;/p&gt;
&lt;p&gt;What I am still confused on is the relationship between the various files, I am writing. There is html and then there are templates and there are python files themselves. Hopefully that will get clearer in the days to come.&lt;br&gt;
My naïve understanding, right now, is&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Some native python code is mainly for launching and running the app.&lt;/li&gt;
&lt;li&gt;The html templates pull data from …&lt;/li&gt;
&lt;li&gt;The flask python code I write (the routes file, as of now).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I also learnt how to extend templates. I created a base template that basically contains the header and the title, which will now be used by every new webpage I build. Right now, it’s just the home page.&lt;br&gt;
I can see a footer or header or some such persistent element that needs to be on every page, that can be created once and then extended multiple times.&lt;/p&gt;
&lt;p&gt;More, tomorrow …&lt;/p&gt;
&lt;p&gt;P.S. Looking at that finished app, and knowing my &lt;em&gt;extremely&lt;/em&gt; rudimentary Python skills, I feel like an apprentice mason, hammer and a chisel in hand, wondering, how in heck, am I going to carve &lt;a href="https://en.wikipedia.org/wiki/David_%28Michelangelo%29#/media/File:%27David%27_by_Michelangelo_Fir_JBU002.jpg" target="_blank" rel="noreferrer"&gt;David&lt;/a&gt;?&lt;/p&gt;</description></item><item><title>A Hundred Days of Code, Day 042</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-042/</link><pubDate>Thu, 11 Jun 2020 16:36:21 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-042/</guid><description>&lt;p&gt;Second day with the &lt;a href="https://courses.miguelgrinberg.com/p/flask-mega-tutorial" target="_blank" rel="noreferrer"&gt;Flask&lt;/a&gt; course.&lt;/p&gt;
&lt;p&gt;Beginning to realise that Flask is not a monolithic thing, but consists of a lot of moving parts.&lt;br&gt;
Looking forward to learning what they are as I progress along.&lt;/p&gt;
&lt;p&gt;Today I learnt how to set my Flask variable, and create an environment, so that I can run Flask consistently without problems.&lt;/p&gt;
&lt;p&gt;Miguel also teaches a simple, yet effective way to combat yak shaving.&lt;br&gt;
You know, where all you want is one simple thing, but then that depends on that other thing, which reminds you that you need that third thing and &lt;a href="https://seths.blog/2005/03/dont_shave_that/" target="_blank" rel="noreferrer"&gt;the next thing you know, you’re at the zoo, shaving a yak, all so you can wax your car.&lt;/a&gt;&lt;br&gt;
Just don’t do that other thing.&lt;br&gt;
Focus on what you are doing.&lt;br&gt;
If there is something you need, use a dummy. Mock something up.&lt;br&gt;
This is a very real, meta lesson, that I’ll carry with me for the rest of my days.&lt;/p&gt;
&lt;p&gt;So I learnt how to return a web page.&lt;br&gt;
And that got tiring really quickly.&lt;br&gt;
Which is when Miguel introduced me to templates.&lt;br&gt;
And I realise why they are needed.&lt;br&gt;
I created a basic template and also learnt about conditionals in the templating language, &lt;a href="https://jinja.palletsprojects.com/en/2.11.x/" target="_blank" rel="noreferrer"&gt;Jinja&lt;/a&gt; and then I called a stop to the day.&lt;br&gt;
More to follow tomorrow.&lt;/p&gt;</description></item><item><title>The Long Road I took to Learn Basic Python</title><link>https://janusworx.com/work/the-long-road-i-took-to-learn-basic-python/</link><pubDate>Wed, 29 Apr 2020 14:37:54 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/the-long-road-i-took-to-learn-basic-python/</guid><description>&lt;p&gt;I have been wanting to switch careers to programming for a long time now.&lt;br&gt;
Just that juggling a part time job, home work, and a broken back, always kept me from somehow giving it the time, that that I needed.&lt;/p&gt;
&lt;p&gt;It has been two years now.&lt;/p&gt;
&lt;p&gt;My lowest ebb, was September last year, when I caught a really nasty bug, was laid up in bed, for nearly a month and then checked myself into a hospital because I thought I was having a heart attack.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;In the meanwhile, people have learnt stuff, gotten careers and rocketed up their charts while I sit here spinning my wheels.&lt;br&gt;
Or at least I used to think, I was spinning my wheels, until this month.&lt;/p&gt;
&lt;p&gt;In my head, I used to be like, why is this so hard for me?&lt;/p&gt;
&lt;p&gt;I write this, to remind myself from getting discouraged.&lt;br&gt;
To remind myself of the progress I made, even if it hasn’t been much yet.&lt;br&gt;
To show my future self, that past Jason, was not a fat slob.&lt;br&gt;
He worked his ass off. And he was resilient.&lt;br&gt;
I write this, because I had a few hard days again, but this time I don’t want to slide into a pit of despair once more.&lt;/p&gt;
&lt;p&gt;The first thing, I reminded myself, was that everybody’s journey is different.&lt;br&gt;
With my physical problems, it has not been easy to focus.&lt;br&gt;
I have to juggle a ton of things, as a husband, son, consultant, patient and student.&lt;br&gt;
And while it may seem all dark and gloomy, I was surrounded by incredibly loving and helpful people, which has made my journey, a lot easier than it would have been without them. My wife, my mother, my friends … all pillars of support!&lt;br&gt;
So the pace I am at, might be much slower than other people, but it reminded me of something my physio said to me when I was sure, I would never be able to run more than 2 minutes straight.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;You might be slow.&lt;br&gt;
You might be fat.&lt;br&gt;
You might be in pain.&lt;br&gt;
But you will be better much sooner than other folks I know. &lt;br&gt;
Because you are doing it.&lt;br&gt;
While the rest are still sitting on their asses, moaning.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;The second thing I did, was to take stock of how far, I have actually come.&lt;br&gt;
Yes, I am not as financially well off as I would like to be.&lt;br&gt;
Yes, life has kicked me in the nuts, more times, than I would like to count.&lt;br&gt;
But I dug myself out of poverty.&lt;br&gt;
I am working myself to the best shape of my life.&lt;br&gt;
I could barely walk two years ago, and now I am practically running.&lt;br&gt;
I am steadily inching to being my weight in my early twenties (while being much fitter than I was then)&lt;/p&gt;
&lt;p&gt;So the problem is not me.&lt;br&gt;
It might take time.&lt;br&gt;
But I can do this.&lt;/p&gt;
&lt;p&gt;And as I am doing this second public round of a &lt;a href="https://janusworx.com/tags/100daysofcode/" &gt;hundred days of code&lt;/a&gt;, I realise all I have to do is to have no shame about my speed (or my abilities), and be resiient and persistent.&lt;/p&gt;
&lt;p&gt;And to remind me about just how far I have come, I write this down.&lt;br&gt;
I started nearly three years ago. I wasted a year, spinning my wheels.&lt;br&gt;
And then I found &lt;a href="https://janusworx.com/on-starting-with-summer-training-at-dgplug/" target="_blank" rel="noreferrer"&gt;Kushal and DGPLUG&lt;/a&gt;. A more supportive mentor and a more welcoming community, I hadn’t experienced in my life. I am still learning from them. And they still teach me with unending patience. If you are ever on IRC, just come say hi on the #learnandteach channel on Freenode. &lt;br&gt;
I started learning the basics from a &lt;a href="http://laurenipsum.org/" target="_blank" rel="noreferrer"&gt;kids book&lt;/a&gt;, because the big ones were confusing.&lt;br&gt;
I tried learning python after that, but I failed.&lt;br&gt;
I tried lots of books, and online sites, but I just could not get it.&lt;br&gt;
I realised that just learn the syntax and go, does not do a thing in my brain.&lt;br&gt;
Or the excellent &lt;a href="https://pymbook.readthedocs.io/en/latest/" target="_blank" rel="noreferrer"&gt;Python for You and Me&lt;/a&gt; would have been just the ticket.&lt;br&gt;
Then I realised that maybe learning more basics would help.&lt;br&gt;
And that this was not something I could learn in a few weeks or months.&lt;br&gt;
So I studied the raw &lt;a href="https://www.edx.org/course/introduction-to-computer-science-and-programming-7" target="_blank" rel="noreferrer"&gt;basics of computer science&lt;/a&gt;, so I could understand, what was what.&lt;br&gt;
And then I understood some.&lt;br&gt;
I then took my time and read the biggest non fiction book I ever read in my life. &lt;a href="https://janusworx.com/learning-python/" target="_blank" rel="noreferrer"&gt;The Lutz Python Book&lt;/a&gt;. &lt;br&gt;
And I understood some more.&lt;br&gt;
I went and watched a series of videos by &lt;a href="https://www.youtube.com/watch?v=YYXdXT2l-Gg&amp;amp;list=PL-osiE80TeTt2d9bfVyTiXJA-UTHn6WwU" target="_blank" rel="noreferrer"&gt;some kid on youtube&lt;/a&gt;.&lt;br&gt;
And I understood some more.&lt;br&gt;
Just doing all this took the better part of a year and a half.&lt;/p&gt;
&lt;p&gt;Now here I am.&lt;br&gt;
On the cusp of a moment, when I think the dam might break.&lt;br&gt;
Because things make sense faster now.&lt;br&gt;
I can read what other people write and actually understand.&lt;br&gt;
I can think for myself and write short programs.&lt;br&gt;
I can understand what the other folks teach and get it.&lt;br&gt;
From here on, it seems just like a matter of loads of practice.&lt;/p&gt;
&lt;p&gt;I write this though, to remind myself, that if this moment is not to be, then I needn’t worry.&lt;br&gt;
I can see how far I have come.&lt;br&gt;
I will do this.&lt;br&gt;
All I need to be is shameless in my learning, patient in my attitude, and resilient in my mind.&lt;/p&gt;
&lt;p&gt;P.S. I realised all this was inspired by an old &lt;a href="https://dailystoic.com/you-make-your-own-good-fortune/" target="_blank" rel="noreferrer"&gt;Aurelius&lt;/a&gt; quote,&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“True good fortune is what you make for yourself. Good fortune: good character, good intentions and good actions.”&lt;/p&gt;
&lt;/blockquote&gt;&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Spoiler. It wasn’t. Just an enlarged spleen acting up due to complications from the bug. Still serious. Just not a heart attack :)&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>A Hundred Days of Code, Day 006</title><link>https://janusworx.com/work/a-hundred-days-of-code-day-006/</link><pubDate>Sun, 19 Apr 2020 13:03:52 +0530</pubDate><author>feedback@janusworx.com (Mario Jason Braganza)</author><guid>https://janusworx.com/work/a-hundred-days-of-code-day-006/</guid><description>&lt;p&gt;Journal progam done!&lt;br&gt;
Yay! Find the code over at &lt;a href="https://gitlab.com/jasonbraganza/programming-practice/-/tree/master/001-personal-journal" target="_blank" rel="noreferrer"&gt;Gitlab&lt;/a&gt; or &lt;a href="https://github.com/jasonbraganza/programming-practice/tree/master/001-personal-journal" target="_blank" rel="noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The program is a lot more basic than I expected.&lt;br&gt;
It does not let me keep multiple journals :)&lt;br&gt;
But I’m happy with what I learnt.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to put together a program&lt;/li&gt;
&lt;li&gt;How to use modules&lt;/li&gt;
&lt;li&gt;Found a little extension in VSCode, called &lt;a href="https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring" target="_blank" rel="noreferrer"&gt;VSCode autoDocstring&lt;/a&gt;, that makes typing in docstrings a breeze.&lt;/li&gt;
&lt;li&gt;Oh, I learnt about docstrings, to help document what I am doing.&lt;/li&gt;
&lt;li&gt;And brushed up on the basics, loops, conditionals, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here’s to more happy programming.&lt;/p&gt;</description></item></channel></rss>