<head> <title>Evan Pratten</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" /> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="stylesheet" href="/assets/css/main.css"> <link rel="stylesheet" href="/assets/css/github-syntax.css"> <link href="https://fonts.googleapis.com/css?family=IBM+Plex+Mono:400,400i|IBM+Plex+Sans:100,100i,400,400i,700,700i" rel="stylesheet"> </head> <body> <div class="site-ctr"> <!-- Navbar --> <nav class="navbar navbar-dark sticky-top bg-dark navbar-expand-lg"> <!-- Navbar content --> <!-- <div class="container"> --> <a class="navbar-brand" href="/">Evan Pratten</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNavAltMarkup"> <div class="navbar-nav ml-auto"> <a class="nav-item nav-link" href="/blog">Blog</a> <a class="nav-item nav-link" href="/projects">Projects</a> <a class="nav-item nav-link" href="/about">About</a> </div> <!-- </div> --> </div> </nav> <!-- <div style="height:5vh"></div> --> <!-- Header --> <!-- <div class="header"> <div class="container"> <div class="content"> </div> </div> <div class="header-gap"></div> </div> --> <div class="reactive-bg"> <div class="post container"> <h1>Hunting snakes with a shotgun</h1> <h4>Python is a little too forgiving</h4> <hr> <p><em>2019-06-27 03:00:00 -0400</em></p> <br> <p>A rather large number of people know me as “the guy who does weird things with python”. I would object to this title, but it is quite accurate. So, here are some of the things I like playing with in python. None of these are actually breaking the language, just little known facts and syntax. At some point I will share about actually breaking the language. For now, enjoy the weird things I have found over the past 6 years.</p> <h2 id="type-hints">Type hints</h2> <p>A little known feature of python is called “type hinting” (PEP 484). This is actually quite common to see in standard libraries, and has it’s own special syntax:</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Here is a regular function </span><span class="k">def</span> <span class="nf">meep</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span> <span class="k">return</span> <span class="n">a</span><span class="o">*</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span> <span class="c1"># This function has no real reason to exsist, and is lacking any sort of documentation. # Let's add a docstring to explain what it does </span> <span class="k">def</span> <span class="nf">meep</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span> <span class="s">""" This function returns the result of a times b squared """</span> <span class="k">return</span> <span class="n">a</span><span class="o">*</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span> <span class="c1"># Ok. The docstring explains the function, but is not too helpful # what are a and b? what does this return? # For all we know, a could actually be a string (in which case, this function would return a string) # Let's fix that up with a type hint </span> <span class="k">def</span> <span class="nf">meep</span><span class="p">(</span><span class="n">a</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span> <span class="s">""" This function returns the result of a times b squared """</span> <span class="k">return</span> <span class="n">a</span><span class="o">*</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span> <span class="c1"># Thanks to the :int (called a type hint in case you didn't notice that yet), we now know that this function expects two ints. # Now, to finish this up with a secondary type hint to specify the return type </span><span class="k">def</span> <span class="nf">meep</span><span class="p">(</span><span class="n">a</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span> <span class="s">""" This function returns the result of a times b squared """</span> <span class="k">return</span> <span class="n">a</span><span class="o">*</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span> <span class="c1"># There. Now we can clearly see that this function takes too ints, and returns one int. # If only this was a requirement in the language. So many headaches could be solved. </span></code></pre></div></div> <p>Now, keep in mind that this is called a type <em>hint</em>. The python compiler (yes.. Give me a second for that one) does not actually care if you obey the hint or not. Feel free to send incorrect data into a hinted function and see what you can break. Critical functions should both hint and check the data types being provided.</p> <h2 id="type-declarations">Type declarations</h2> <p>Just like type hints for functions, python has hints for variables too.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># A regular variable. Must be declared with an initial value </span><span class="n">my_state</span> <span class="o">=</span> <span class="bp">None</span> <span class="c1"># my_state is None, as it has not been set, but needs to exist. # Let's assume that my_state is to be a state: </span><span class="k">class</span> <span class="nc">State</span><span class="p">:</span> <span class="n">status</span> <span class="o">=</span> <span class="bp">False</span> <span class="k">def</span> <span class="nf">toggle</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">status</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">status</span> <span class="c1"># Finally, its time to set the state to something useful </span><span class="n">my_state</span> <span class="o">=</span> <span class="n">State</span><span class="p">()</span> <span class="n">my_state</span><span class="o">.</span><span class="n">toggle</span><span class="p">()</span> <span class="c1"># Ok.. I hate this. Let's start by using type declarations first # Any variable can be un-initialized and just have a type. Like so: </span><span class="n">my_state</span><span class="p">:</span> <span class="n">State</span> <span class="c1"># This works for anything </span><span class="n">is_alive</span><span class="p">:</span> <span class="nb">bool</span> <span class="n">age</span><span class="p">:</span> <span class="nb">int</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span> <span class="c1"># Now, with this new knowledge, let's rewrite State </span><span class="k">class</span> <span class="nc">State</span><span class="p">:</span> <span class="n">status</span><span class="p">:</span> <span class="nb">bool</span> <span class="k">def</span> <span class="nf">toggle</span><span class="p">(</span><span class="bp">self</span><span class="p">:</span> <span class="n">State</span><span class="p">)</span> <span class="o">-></span> <span class="bp">None</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">status</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">status</span> <span class="c1"># And initialize my_state with slightly different syntax </span><span class="n">my_state</span> <span class="o">=</span> <span class="n">State</span><span class="p">(</span><span class="n">status</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> </code></pre></div></div> <p>I have not found much use for this yet. Hopefully there is something cool to use it for.</p> <h2 id="one-line-functions">One-line functions</h2> <p>This is more common knowlage. A function can be declared in one line</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Here is an adder function </span><span class="k">def</span> <span class="nf">adder1</span><span class="p">(</span><span class="n">a</span><span class="p">:</span><span class="nb">int</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span><span class="nb">int</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span> <span class="k">return</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span> <span class="c1"># Here is a one-line adder function </span><span class="n">adder2</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">a</span><span class="p">,</span><span class="n">b</span> <span class="p">:</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span> <span class="c1"># State from above can be compacted further: </span><span class="k">class</span> <span class="nc">State</span><span class="p">:</span> <span class="n">status</span><span class="p">:</span> <span class="nb">bool</span> <span class="n">toggle</span> <span class="o">=</span> <span class="k">lambda</span> <span class="bp">self</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">status</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">status</span> </code></pre></div></div> <h2 id="ternary-operations">Ternary operations</h2> <p>On the trend of one-line code, We have the one-line if/else, also known as a Ternary in more sensible languages.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Here is an if/else </span><span class="k">if</span> <span class="mi">100</span> <span class="ow">is</span> <span class="mi">5</span><span class="p">:</span> <span class="k">print</span><span class="p">(</span><span class="s">"The world has ended"</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">print</span><span class="p">(</span><span class="s">"All is good"</span><span class="p">)</span> <span class="c1"># Here is a smaller if/else </span><span class="k">print</span><span class="p">(</span><span class="s">"The world has ended"</span> <span class="k">if</span> <span class="mi">100</span> <span class="ow">is</span> <span class="mi">5</span> <span class="k">else</span> <span class="s">"All is good"</span><span class="p">)</span> </code></pre></div></div> <h2 id="compiled-python">Compiled python</h2> <p>This one is interesting. Python, like Java, is compiled into bytecode. So yes, it technically is a compiled language. To see said bytecode, take a look at any <code class="highlighter-rouge">.pyc</code> file sitting in your <code class="highlighter-rouge">__pycache__</code></p> <h2 id="blog-formatting-experiments">Blog formatting experiments</h2> <p>I am still playing with post formats, and various types of content. This is more random than I usually prefer. Let me know your thoughts on the social media platform of your choosing.</p> </div> </div> </div> <div class="container"> <hr> </div> <nav class="navbar navbar-expand-lg "> <!-- Navbar content --> <div class="container"> <span class="navbar-text"> Site design by: <a href="https://retrylife.ca">Evan Pratten</a> | This site was last updated at: 2019-08-12 19:45:00 -0400 </span> </div> </nav> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <!-- Offsets for links --> <script> (function ($, window) { var adjustAnchor = function () { var $anchor = $(':target'), fixedElementHeight = 100; if ($anchor.length > 0) { window.scrollTo(0, $anchor.offset().top - fixedElementHeight); } }; $(window).on('hashchange load', function () { adjustAnchor(); }); })(jQuery, window); </script> </body>