<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Luciano Scarpulla</title>
    <subtitle>Personal blog about coding, aviation and more.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://luciano.live/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://luciano.live"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2024-06-26T00:00:00+00:00</updated>
    <id>https://luciano.live/atom.xml</id>
    <entry xml:lang="en">
        <title>How I gained my first 100+ stars on GitHub</title>
        <published>2024-06-26T00:00:00+00:00</published>
        <updated>2024-06-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              luciano
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://luciano.live/blog/how-i-gained-stars/"/>
        <id>https://luciano.live/blog/how-i-gained-stars/</id>
        
        <content type="html" xml:base="https://luciano.live/blog/how-i-gained-stars/">&lt;p&gt;I wanted to reflect on how I got my first 100+ stars on a GitHub repository.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;awesome-lists&quot;&gt;Awesome lists&lt;&#x2F;h2&gt;
&lt;p&gt;What are awesome lists?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;An awesome list is a list of awesome things curated by the community. There are awesome lists about everything from CLI applications to fantasy books.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I really like browsing GitHub for &#x27;awesome lists&#x27;, one of my favourites is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;awesome-selfhosted&#x2F;awesome-selfhosted&quot;&gt;awesome-selfhosted&lt;&#x2F;a&gt; which contains a list of selfhosted tools and resources.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to create my own collection of free and open-source aviation projects that I know of. While working in aviation, I always had those sources in mind but I never kept a written collection of it, so I am doing this also for my personal benefit.&lt;&#x2F;p&gt;
&lt;p&gt;As of the writing of this post, my list contains almost 20 entries (mostly data sources). In the coming days I intend to expand it further with more data and tools.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i-got-spotted&quot;&gt;I got spotted&lt;&#x2F;h2&gt;
&lt;p&gt;Shortly after publishing the list, I got spotted by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;x.com&#x2F;cyb_detective&quot;&gt;Cyber Detective&lt;&#x2F;a&gt;, an account which specializes on Open Source Intelligence (OSINT). They shared a link of my repository on X which then got 8k views.&lt;&#x2F;p&gt;
&lt;p&gt;I was quite surprised by the rapidity at which my list (just a simple README file) got discovered. It is probably due to the &#x27;osint&#x27; and &#x27;awesome-list&#x27; tags that I put on GitHub.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;growth-so-far&quot;&gt;Growth so far&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;api.star-history.com&#x2F;svg?repos=lucianosrp&#x2F;open-source-aviation&amp;amp;type=Date&amp;amp;theme=dark&quot; alt=&quot;GitHub stars chart&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;My list was featured in other people&#x27;s awesome-list which is nice to see. To make it more &quot;attractive&quot;, I decided to add a Python script that will look for any data source present in that file and append a table containing information for each data source.&lt;&#x2F;p&gt;
&lt;p&gt;I even added a GitHub action to run the script every day, but I recently turned that off as I was not happy with the way it commits the repository.&lt;&#x2F;p&gt;
&lt;p&gt;Overall, I think the key to success was the simplicity of the content as well as a good series of tags to make it more &#x27;discoverable&#x27; on GitHub.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My first experience with Coursera</title>
        <published>2024-04-06T00:00:00+00:00</published>
        <updated>2024-04-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              luciano
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://luciano.live/blog/my-experience-with-coursera/"/>
        <id>https://luciano.live/blog/my-experience-with-coursera/</id>
        
        <content type="html" xml:base="https://luciano.live/blog/my-experience-with-coursera/">&lt;h2 id=&quot;why-coursera&quot;&gt;Why Coursera?&lt;&#x2F;h2&gt;
&lt;p&gt;Apart from University, most of the professional learnings I had were via other &quot;non-conventional&quot; means such as Youtube videos and plain-text tutorials.&lt;&#x2F;p&gt;
&lt;p&gt;Learning this way, can have many advantages, for example:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You can learn at your own pace&lt;&#x2F;li&gt;
&lt;li&gt;You can watch and repeat over and over without being pressed by deadlines and exams&lt;&#x2F;li&gt;
&lt;li&gt;You manage your own curriculum by choosing the topics you actually want to learn&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;However, it can become hard to prove the knowledge and skills you acquired online without any kind of &quot;valid proof&quot; or certificate. Sometimes, the best way of proving your skills is to just do it, and that is why I think showcasing what you can do is very important.&lt;&#x2F;p&gt;
&lt;p&gt;Recently, I was encouraged to take on a course for then getting a certificate. I went on Google and searched a topic I have known and learned but which I would like to further develop and prove my knowledge with a certification.&lt;&#x2F;p&gt;
&lt;p&gt;Pytorch is a library used for Machine Learning which is a hot topic that hasn&#x27;t stopped trending. Coursera offered an intermediate course by IBM on it so I decided to give it a try.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;first-impressions&quot;&gt;First impressions&lt;&#x2F;h2&gt;
&lt;p&gt;Compared to what you can usually find on Youtube and other websites, the course seems to be very &quot;cheap&quot; with a synthetic voice over and poorly made slides. But the explanations and concepts are still very simple and easy to understand. I was just surprised that the average quality of the course is not in par with what you would normally have on a free platform.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;is-it-actually-worth-it&quot;&gt;Is it actually worth it?&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;I guess no.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;But I did a 7 days free trial and managed to complete the course within that timeframe.&lt;&#x2F;p&gt;
&lt;p&gt;I did learn new things and I think that the overall experience is decent. But I don&#x27;t think it is worth the starting price of 45 Euros per month.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-next&quot;&gt;What next&lt;&#x2F;h2&gt;
&lt;p&gt;I still cannot find a good course on AI which is better than what you can find freely online. I guess the price you pay is just for a fancy certificate to put on LinkedIn?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I was wrong about Rye</title>
        <published>2024-03-14T00:00:00+00:00</published>
        <updated>2024-03-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              luciano
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://luciano.live/blog/wrong-about-rye/"/>
        <id>https://luciano.live/blog/wrong-about-rye/</id>
        
        <content type="html" xml:base="https://luciano.live/blog/wrong-about-rye/">&lt;p&gt;While talking about Rye, in the previous post I wrote that the lack of implementations for VScode or Pycharm had made me reluctant to adopt it full time.&lt;&#x2F;p&gt;
&lt;p&gt;By &quot;lack of implementations&quot; I meant that there was no python environment finder suited for Rye&#x27;s virtual environment. I probably did not use Rye properly in the first time, since Rye&#x27;s virtual env is &lt;em&gt;literally&lt;&#x2F;em&gt; a Virtualenv, and so it can be discovered by all majors IDEs.&lt;&#x2F;p&gt;
&lt;p&gt;Somehow, I first thought Rye had its own virtual environment type!&lt;&#x2F;p&gt;
&lt;p&gt;Since finding this out, I now intend to use it full-time and will post more about it whenever needed.&lt;&#x2F;p&gt;
&lt;p&gt;My tips for using it is to make sure to &lt;code&gt;rye sync&lt;&#x2F;code&gt; after every &lt;code&gt;rye add&lt;&#x2F;code&gt; since this last command does not install the actual packages that will be listed on the project configuration itself. Although I like this behaviour, I would love to have an option to default &lt;code&gt;rye sync&lt;&#x2F;code&gt; after every &lt;code&gt;rye add&lt;&#x2F;code&gt; (similar to &lt;code&gt;cargo add&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Also, &lt;code&gt;uv&lt;&#x2F;code&gt; integration does not come as a default. It needs to be enabled in the global rye configurations!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The airport compass</title>
        <published>2024-02-25T00:00:00+00:00</published>
        <updated>2024-02-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              luciano
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://luciano.live/blog/airport-compass/"/>
        <id>https://luciano.live/blog/airport-compass/</id>
        
        <content type="html" xml:base="https://luciano.live/blog/airport-compass/">&lt;p&gt;A few years ago, I got inspired by a very interesting figure published on a paper by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;gboeing&quot;&gt;Geoff Boeing&lt;&#x2F;a&gt; called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;appliednetsci.springeropen.com&#x2F;articles&#x2F;10.1007&#x2F;s41109-019-0189-1&quot;&gt;&quot;Urban spatial order: street network orientation, configuration, and entropy&quot;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This figure represents the distribution of the orientation of every street of major cities. I like how it gives a quick representation of each city&#x27;s layout and how evident are the various levels of entropy.&lt;&#x2F;p&gt;
&lt;p&gt;Shortly after seeing this chart, I immediately thought of replicating this view for airports&#x27; traffic worldwide.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources-and-code&quot;&gt;Sources and code&lt;&#x2F;h2&gt;
&lt;p&gt;For this project I used two major open-source datasets:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The airlines routes data comes from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpatokal&#x2F;openflights&quot;&gt;@jpatokal&lt;&#x2F;a&gt;&#x27;s OpenFlights repository&lt;&#x2F;li&gt;
&lt;li&gt;The airports data is from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;davidmegginson&#x2F;ourairports-data&#x2F;&quot;&gt;@davidmegginson&lt;&#x2F;a&gt;&#x27;s OurAirports repository&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I made the source-code available on my GitHub &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lucianosrp&#x2F;airport-compass&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;outcomes&quot;&gt;Outcomes&lt;&#x2F;h2&gt;
&lt;p&gt;I first generated the top 15 airports by number of destinations. Each chart (or compass) displays the distribution of outbound flights and aligns those for each initial bearing. The longer the yellow bar, the more frequent is that bearing. For example, if an airport has most of the departures pointing West (or 270°), you would see the longest bar pointing left.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;airport-compass&#x2F;Where-is-it-going-15.png&quot; alt=&quot;15 Airports view&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Some airports like New York JFK and London Heathrow (LHR) represent an important hub for transatlantic flights. In these charts, we can see how LHR has a long bar towards West (towards the North America) and JFK has one towards East (Europe).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;airport-compass&#x2F;LHR-dark.png&quot; alt=&quot;LHR&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Other airports&#x27; compasses, instead, are majorly driven by the geographical constrains of their location. Tokyo&#x27;s Narita Intl. Airport is a very good example to illustrate this case. It has virtually no routes pointing eastwards! This is because Japan has the Pacific Ocean to its east side and most of the routes connecting Japan to North America are flying with an initial bearing pointing North! (Since this would be the shortest great circle path)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;airport-compass&#x2F;NRT-dark.png&quot; alt=&quot;NRT&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to&quot;&gt;How-to&lt;&#x2F;h2&gt;
&lt;p&gt;As I said earlier in this post, I am using two freely available datasets and published the source code to replicate these charts. Everything is made entirely using Python:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;To merge and transform the data I used &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pandas.pydata.org&#x2F;&quot;&gt;pandas&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;matplotlib.org&#x2F;&quot;&gt;matplotlib&lt;&#x2F;a&gt; is used for the visualization&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;data&quot;&gt;Data&lt;&#x2F;h3&gt;
&lt;p&gt;First, I set a constant to represent the number of airports I want to have in the final view. In this example, we are going to start with 30. The csv data can be conveniently loaded directly from GitHub using the &lt;code&gt;read_csv&lt;&#x2F;code&gt; method.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pandas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;TOP_AIRPORTS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# Getting airlines&amp;#39; routes data:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;routes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd.read_csv(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;    &amp;quot;https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;jpatokal&#x2F;openflights&#x2F;master&#x2F;data&#x2F;routes.dat&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;    usecols&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;    names&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;airline&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;origin&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;destination&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This first dataset doesn&#x27;t come with headers, hence why we need to use the &lt;code&gt;names&lt;&#x2F;code&gt; argument to specify the column names. Also, we are just interested in knowing the origin and destination airport of each route (Column 2 and 4), I also added the airline IATA code (Column 0) because I was curious, but not needed for this project.&lt;&#x2F;p&gt;
&lt;p&gt;We are also not interested in displaying all airports on this dataset. To do so, we can get the Top airports by grouping the data, ordering it and accessing only until the &lt;code&gt;TOP_AIRPORTS&lt;&#x2F;code&gt; constant number:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# Selecting only top airports&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;top_airports&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    routes.groupby(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;origin&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .destination.count()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .sort_values(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;ascending&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;False&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .index[:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;TOP_AIRPORTS&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;routes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; routes.loc[routes.origin.isin(top_airports)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, we are just having data about each airlines&#x27; routes. But in order to plot the data into small compasses, we will need to calculate the initial bearing of each airport pair. And in order to do so, we also need the coordinates of each airport:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# Getting airports data:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;airports&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd.read_csv(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;    &amp;quot;https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;davidmegginson&#x2F;ourairports-data&#x2F;main&#x2F;airports.csv&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;    usecols&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;ident&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;iata_code&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;latitude_deg&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;longitude_deg&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;While looping for &lt;code&gt;origin&lt;&#x2F;code&gt; and &lt;code&gt;destination&lt;&#x2F;code&gt; we also make sure that the columns in the airport dataset are suffixed with &quot;_origin&quot; and &quot;_destination&quot; respectively. We can now calculate the bearing (angle) for each pair:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; numpy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# Getting initial bearing for each route:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;angle&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np.degrees(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    np.arctan2(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        df.latitude_deg_destination&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; df.latitude_deg_origin,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        df.longitude_deg_destination&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; df.longitude_deg_origin,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Numpy can do all the math for us with a resulting column &quot;angle&quot; which contains all angles for each pair.&lt;&#x2F;p&gt;
&lt;p&gt;Since we would want to have a sense of the &quot;distribution&quot; of routes for each angle, we can make a resulting dataframe by doing a final aggregation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# Aggregating final data:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;res&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df.groupby([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;origin&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;angle&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]).destination.count()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;visualization&quot;&gt;Visualization&lt;&#x2F;h3&gt;
&lt;p&gt;We can dynamically create the layout of our &quot;poster&quot; by dividing the total number of airports by the number of columns we want to have:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ncols&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nrows&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(top_airports)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; ncols&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can set up the figure and axes of our plot:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fig, axes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; plt.subplots(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;    nrows&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;nrows,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;    ncols&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;ncols,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;    subplot_kw&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;projection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;polar&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;    figsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;(ncols&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 1.9&lt;&#x2F;span&gt;&lt;span&gt;, nrows&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 2.6&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can fill each axis with a for-loop:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; ax, airport&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; zip&lt;&#x2F;span&gt;&lt;span&gt;(axes.flatten(), top_airports):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    airport_data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; res.loc[airport]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ax.bar(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        np.radians(airport_data.index),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        airport_data.values,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;        width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;0.3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;        color&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;C2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;        alpha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;0.5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ax.set_title(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;airport&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;}\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt; fontdict&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;fontweight&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;bold&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ax.set_yticks([])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ax.set_rlabel_position(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;90&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ax.set_xticklabels([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;E&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;N&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;W&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;S&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt; fontdict&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;dict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;fontsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here, &lt;code&gt;axes.flatten()&lt;&#x2F;code&gt; conveniently &quot;flattens&quot; out the nested array that &lt;code&gt;axes&lt;&#x2F;code&gt; is. We don&#x27;t need the ticks for the Y axis so we turn them off using &lt;code&gt;ax.set_yticks([])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;set_xtickslabels&lt;&#x2F;code&gt; currently raise a &lt;code&gt;UserWarning&lt;&#x2F;code&gt; which we can safely ignore.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fig.suptitle(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;Where is the traffic going?&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt; fontsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt; fontweight&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;bold&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fig.text(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;0.05&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 0.005&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;Made by Luciano Scarpulla&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fig.tight_layout(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;pad&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fig.savefig(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;Where is it going &lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;{TOP_AIRPORTS}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;.png&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt; dpi&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;300&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;what-s-next&quot;&gt;What&#x27;s next?&lt;&#x2F;h2&gt;
&lt;p&gt;I first developed this years ago and re-adapted my old code for this post. There are some changes and improvements that can be made:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The data is grouped by each unique bearing. This can be fixed by simply rounding the angles, or distributing the angles into different buckets (e.g 130-140 degrees, 140-150, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;The image is a static outlook at airlines&#x27; routes of 2014. A seasonal outlook could be made so that you could notice the differences in the &quot;orientation&quot; in certain airports.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;airport-compass&#x2F;Where-is-it-going-30.png&quot; alt=&quot;30 Airports view&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Switching to Rust as a Python developer</title>
        <published>2024-02-02T00:00:00+00:00</published>
        <updated>2024-02-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              luciano
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://luciano.live/blog/switching-to-rust/"/>
        <id>https://luciano.live/blog/switching-to-rust/</id>
        
        <content type="html" xml:base="https://luciano.live/blog/switching-to-rust/">&lt;p&gt;Learning Rust for the past months has been one best learning experiences I have had since learning Python. If you have to pick a new language to learn in 2024, I would definitely recommend Rust!&lt;&#x2F;p&gt;
&lt;p&gt;Here are the top features that I particularly enjoy as a Python developer!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-rust&quot;&gt;Why Rust?&lt;&#x2F;h2&gt;
&lt;p&gt;You may want to know why I wanted to learn Rust out of the many other languages out there. First, I wanted to pick a lower-level language as I think it would nicely complete with my current knowledge of Python. By learning a lower-level language I can familiarize myself more with hardware resources and architectures as well as learning how to optimize for performance. As a Python developer, I kept looking more and more at rust-dependent code such as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pola.rs&#x2F;&quot;&gt;Polars&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.pydantic.dev&#x2F;latest&#x2F;&quot;&gt;Pydantic&lt;&#x2F;a&gt;, there is definitely a trend for applications to have a core backend written in Rust and using Python as a code interface. This is one of the main reasons I am choosing to learn Rust among many other great languages.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;static-typing&quot;&gt;Static typing&lt;&#x2F;h2&gt;
&lt;p&gt;Although I really like the dynamic nature of Python, I have been starting to appreciate the comfort of having typehints in the code I write. Typehints improve code readability and blends with most code editors and &lt;strong&gt;lsps&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Writing typehints in my Python code has actually saved me time! Every time I am using the wrong parameter for a function or when looking for a bug, I can always keep an eye for the warnings that wouldn&#x27;t normally be there if I hadn&#x27;t put typehints in the first place!&lt;&#x2F;p&gt;
&lt;p&gt;All of this makes me code with more ease. Moving to a statistically typed language is exciting and brings me even more comfort because I know there is little room for silly errors. Which brings me to the next amazing feature Rust has.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-compiler&quot;&gt;The compiler&lt;&#x2F;h2&gt;
&lt;p&gt;I love how the compiler is the best code companion in Rust. After compilation, I am comfortable that there are not going to be any major issues since most of them were caught by the compiler. Rust makes sure that your script is safe to run. And if any errors are raise during compilation, these are presented in a very clear way and it even provide helpful solutions. As I learn my way through Rust, I often learn things just by compiling my scripts!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;portability&quot;&gt;Portability&lt;&#x2F;h2&gt;
&lt;p&gt;Python is a great language which offers a lot of flexibility on what to develop and how. But sharing your Python app is sometimes difficult. You always need to consider the environment in which Python needs to be interpreted and run. Moving to a compiled language really made me discover the advantage of having a single binary file that can be executed in different machines with very few difficulties.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cargo&quot;&gt;Cargo&lt;&#x2F;h2&gt;
&lt;p&gt;I tried various library mangers in Python. Although I mainly use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;anaconda.com&quot;&gt;anaconda&lt;&#x2F;a&gt; for my day-to-day development which suits most of my cases, I sometimes will use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;python-poetry.org&quot;&gt;poetry&lt;&#x2F;a&gt; and I even start experimenting with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rye-up.com&quot;&gt;rye&lt;&#x2F;a&gt;. But still, to this day, managing environments and packages in Python can be very difficult, especially because there could be many different ways to pack a library and each library will bring its own sometimes messy requirements. Some popular libraries are very easy to install in any Os but others can be very cumbersome! Cargo brings serenity to all of this. You can easily add libraries to your Rust project, compile it and run it without having to do any manual work. Learning Rust has been particularly pleasant for me especially because of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;cargo&#x2F;&quot;&gt;Cargo&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;safety&quot;&gt;Safety&lt;&#x2F;h2&gt;
&lt;p&gt;More specifically Null safety and error handling. Yes - not necessarily memory safety since with Python I never really had to deal with memory leaks by leaving the garbage collector do its job. In Rust, there two main &lt;strong&gt;Enums&lt;&#x2F;strong&gt; that makes handling null values and errors very trivial. These are &lt;code&gt;Option&lt;&#x2F;code&gt; and &lt;code&gt;Result&lt;&#x2F;code&gt; respectively.&lt;&#x2F;p&gt;
&lt;p&gt;In Python, you can convey that a function might return a value or &lt;code&gt;None&lt;&#x2F;code&gt; with the &lt;code&gt;Option&lt;&#x2F;code&gt; typehint or, more recently, with the notation &lt;code&gt;| None&lt;&#x2F;code&gt;. But this still leave room for the usuals &lt;code&gt;ValueError&lt;&#x2F;code&gt; or &lt;code&gt;AttributeError&lt;&#x2F;code&gt; and leave the optional freedom to programer to handle null cases.&lt;&#x2F;p&gt;
&lt;p&gt;Consider the following example in Python:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; random&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; foo&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; random.randint(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;Hello&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; bar&lt;&#x2F;span&gt;&lt;span&gt;(s:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(s,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; s.upper()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;random_val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; foo()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; bar(random_val)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;HELLO&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, this is a very basic examples! There are chances for this program to run successfully but let&#x27;s see why it may not.&lt;&#x2F;p&gt;
&lt;p&gt;The function &lt;code&gt;bar&lt;&#x2F;code&gt; is expecting a value of type &lt;code&gt;str&lt;&#x2F;code&gt;, but since the function &lt;code&gt;foo&lt;&#x2F;code&gt; may return a string or &lt;code&gt;None&lt;&#x2F;code&gt;, line &lt;code&gt;8&lt;&#x2F;code&gt; will raise an &lt;code&gt;AttributeError&lt;&#x2F;code&gt; since &lt;code&gt;None&lt;&#x2F;code&gt; does not have the method &lt;code&gt;.upper&lt;&#x2F;code&gt;. The rest of the code really won&#x27;t be run until &lt;code&gt;foo&lt;&#x2F;code&gt; returns &lt;code&gt;&quot;Hello&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We can make this code &lt;em&gt;safer&lt;&#x2F;em&gt; with one extra line of code:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; random&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; foo&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; random.randint(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;Hello&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; bar&lt;&#x2F;span&gt;&lt;span&gt;(s:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(s,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; s.upper()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;random_val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; foo()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; bar(random_val)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;HELLO&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I love the approach that Rusts takes to handle this case using &lt;code&gt;Option&lt;&#x2F;code&gt;. Here is how the previous example would look like written in Rust:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Unfortunately&lt;&#x2F;em&gt;, we need to add a package to address the random behavior of the &lt;code&gt;foo&lt;&#x2F;code&gt; function as Rust does not have it to the standard library.&lt;&#x2F;p&gt;
&lt;p&gt;Here I am using Cargo to add the package &lt;em&gt;rand&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; add rand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;use&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; rand&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;{thread_rng,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; Rng&lt;&#x2F;span&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; foo&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; rng&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; thread_rng&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; rng&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;gen_range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;        Some&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;Hello&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;        None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; bar&lt;&#x2F;span&gt;&lt;span&gt;(s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;unwrap_or&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;to_uppercase&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; random_val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; foo&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; res&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; vec!&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;HELLO&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;to_string&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;to_string&lt;&#x2F;span&gt;&lt;span&gt;()];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;    assert!&lt;&#x2F;span&gt;&lt;span&gt;(res&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;contains&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;bar&lt;&#x2F;span&gt;&lt;span&gt;(random_val)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With this code, &lt;code&gt;foo&lt;&#x2F;code&gt; uses the &lt;code&gt;Option&lt;&#x2F;code&gt; and it&#x27;s variant &lt;code&gt;Some&lt;&#x2F;code&gt; which literally means that there is a value, and &lt;code&gt;None&lt;&#x2F;code&gt; - no value.&lt;&#x2F;p&gt;
&lt;p&gt;This makes so that any function that uses the output of &lt;code&gt;foo&lt;&#x2F;code&gt; would need to handle each variant of the Enum &lt;code&gt;Option&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The same would be true for the &lt;code&gt;Result&lt;&#x2F;code&gt; enum which has &lt;code&gt;Ok&lt;&#x2F;code&gt; and &lt;code&gt;Err&lt;&#x2F;code&gt; as a variant. With Rust you could simply use the &lt;code&gt;unwrap_or&lt;&#x2F;code&gt; method to get the &lt;code&gt;Ok&lt;&#x2F;code&gt; value or use a match pattern like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;use&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; rand&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;{thread_rng,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; Rng&lt;&#x2F;span&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; random_error&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;, ()&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; rng&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; thread_rng&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; rng&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;gen_range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;        Ok&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;Result A&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;        Err&lt;&#x2F;span&gt;&lt;span&gt;(())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; random_error&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    match&lt;&#x2F;span&gt;&lt;span&gt; val {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;        Ok&lt;&#x2F;span&gt;&lt;span&gt;(result)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;We safely got the result, {result}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;        Err&lt;&#x2F;span&gt;&lt;span&gt;(_)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;We received an error!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;&#x2F;h2&gt;
&lt;p&gt;I spent quite some words describing how &lt;em&gt;good&lt;&#x2F;em&gt; Rust is and how &lt;em&gt;bad&lt;&#x2F;em&gt; Python can get. But there is a whole new post that can be made on how good Python is compared to Rust, in terms of its rapid prototyping, learning curves, huge community, and much more! I won&#x27;t stop using Python as I think it is a fundamental language for data analytics but I am ready to start experimenting with Rust for tools that would require more control and performance.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Python tools I use</title>
        <published>2024-01-10T00:00:00+00:00</published>
        <updated>2024-01-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              luciano
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://luciano.live/blog/python-tools/"/>
        <id>https://luciano.live/blog/python-tools/</id>
        
        <content type="html" xml:base="https://luciano.live/blog/python-tools/">&lt;p&gt;As previously mentioned in this blog, Rust is becoming more and more used in Python libraries such as Pydantic and Polars. But recently we are also getting python tools written in Rust!&lt;&#x2F;p&gt;
&lt;p&gt;Few months ago, I followed the development of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rye-up.com&#x2F;&quot;&gt;Rye&lt;&#x2F;a&gt; as an alternative Python project and package manager. Later on, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.astral.sh&#x2F;ruff&#x2F;&quot;&gt;Ruff&lt;&#x2F;a&gt; made its debut as a linter and formatter substituting the popular &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;flake8.pycqa.org&#x2F;en&#x2F;latest&#x2F;&quot;&gt;flake-8&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;black.readthedocs.io&#x2F;en&#x2F;stable&#x2F;&quot;&gt;black&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to their powerful backend written in Rust, these tools all provide a substantial upgrade in terms of performance and flexibility compared to the tools they are aiming to replace (up to 100x faster).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ruff&quot;&gt;Ruff&lt;&#x2F;h2&gt;
&lt;p&gt;I found &lt;code&gt;ruff format&lt;&#x2F;code&gt; to be the easiest tool to replace. I often bind the reformat command to a shortcut or to reformat while saving. But more often, I tend to reformat the whole project before committing. The performance of Ruff allows me to confidently reformat thousands of lines knowing that I will not need to wait long.&lt;&#x2F;p&gt;
&lt;p&gt;Adopting &lt;code&gt;ruff format&lt;&#x2F;code&gt; together with &lt;code&gt;ruff check&lt;&#x2F;code&gt; in your pipelines can substantially reduces your actions time!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rye&quot;&gt;Rye&lt;&#x2F;h2&gt;
&lt;p&gt;Even before Astral&#x27;s ruff and uv were available, I got Rye a try. Rye was the first attempt to implement a &quot;Cargo for Python&quot; - a 360 degrees project and package management at your fingertips. I immediately found Rye very easy to use and, to some extent, similar to Poetry! However, the lack of implementations for VScode (at the time of testing) or Pycharm had made me reluctant to adopt it full time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;uv&quot;&gt;Uv&lt;&#x2F;h2&gt;
&lt;p&gt;Uv is the latest addition to the Rust-born Python family tools. It is the fastest package manager out there and is able to quickly resolve most of your painful package dependencies. It is also a replacement for &lt;code&gt;venv&lt;&#x2F;code&gt;, so you can quickly set up a new virtual environment for your Python project.&lt;&#x2F;p&gt;
&lt;p&gt;After Uv was released, Astral also announced the takeover of Rye and implemented uv as the core package manager for Rye.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-i-use-what-i-am-not-using-and-what-s-next&quot;&gt;What I use, what I am not using and what&#x27;s next&lt;&#x2F;h2&gt;
&lt;p&gt;I now fully use ruff on a daily basis both at work and for private projects. It is so easy to use that I often forget it is running.&lt;&#x2F;p&gt;
&lt;p&gt;Due to the current lack of support for Pycharm (the IDE I use at work) I am not currently using either Rye nor Uv at work, but I am still using them on my local machine for personal projects.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;ruff-graph-dark.svg&quot; alt=&quot;Ruff linter performance&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I look forward to see what Astral is developing next - perhaps a &quot;Clippy for Python&quot; or a rust-based static type checker to substitute mypy? Everything seems to be possible at this point.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
