<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Abdur-Rahmaan Janhangeer</title>
    <description>The latest articles on DEV Community by Abdur-Rahmaan Janhangeer (@abdurrahmaanj).</description>
    <link>https://dev.to/abdurrahmaanj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F132372%2F810d79c4-ea13-435f-92a6-6014e575ab05.jpeg</url>
      <title>DEV Community: Abdur-Rahmaan Janhangeer</title>
      <link>https://dev.to/abdurrahmaanj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abdurrahmaanj"/>
    <language>en</language>
    <item>
      <title>Educative.io Author Review: Why I Don't Recommend Writing On Educative</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Tue, 13 Dec 2022 10:33:24 +0000</pubDate>
      <link>https://dev.to/abdurrahmaanj/why-i-dont-recommend-writing-on-educativeio-the-curse-of-authorship-1gph</link>
      <guid>https://dev.to/abdurrahmaanj/why-i-dont-recommend-writing-on-educativeio-the-curse-of-authorship-1gph</guid>
      <description>&lt;p&gt;One of my worst mistakes in life was accepting an Educative contract which cost me months of my time. Educative.io is a great platform with awesome content. Do check it out if you haven't. It's also built on the belief that reading is faster than watching videos. It also enjoys a solid reputation among coders. &lt;/p&gt;

&lt;p&gt;In this post i'd be drawing attention to some points which you might consider before signing a contract with Educative. This is not exactly a bad review of the platform, but sheds some light on contract termination.&lt;/p&gt;

&lt;h2&gt;
  
  
  You might end up writing the course 3 times.
&lt;/h2&gt;

&lt;p&gt;Educative has 3 review rounds: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Grammarly round&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where a Grammarly report is sent which also checks for plagiarism. This is a great initiative, but, the reviewer might ask you to change some wordings as you copied a definition as is. Well, if a canonical reference cannot be referenced, this is weird.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The casual review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this round of review lots of comments are given. Some pretty useless. Among the three reason for terminating my contract, it was stated:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Some illustrations were blurred and were asked to be replaced. Unfortunately, they still have not been rectified.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;This concerned screenshots like this one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UoxD7IKV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpilcb63s420pfhqwyoa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UoxD7IKV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpilcb63s420pfhqwyoa.png" alt="Mailman" width="880" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sorry Educative, i cannot unblur a screenshot!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The formal review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a phase where they send you a Google docs with edits to be made. Mine, for the quarter milestone had 20+ pages. Yes, 20+ pages of things to correct for only a quarter of my course!&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't give them the best of yourself
&lt;/h2&gt;

&lt;p&gt;If you write a stuffed, code-intensive course, you are digging a hole for yourself as you will have to deal with the 3 rounds of reviews for each chapter of the course. &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting penalized for a buggy Docker system
&lt;/h2&gt;

&lt;p&gt;One of the 3 points stated:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Some of the applications in the course are still not working despite numerous revisions and author calls where all issues were addressed and appropriate solutions were provided.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's true the apps were not working but why? I was writing a Flask course. And how do i know that they don't support basic things as redirection?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7gai8t2w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d4vjd06jtw7zuje58wd9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7gai8t2w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d4vjd06jtw7zuje58wd9.png" alt="No support" width="565" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clipping out &lt;code&gt;redirect&lt;/code&gt; for &lt;code&gt;render_template&lt;/code&gt; is a senseless thing to do in a Flask course.&lt;/p&gt;

&lt;p&gt;There are times when a lib version was out of date but there were lots of platform issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R-QL70rw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9oxqet7y6g3iea1hux6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R-QL70rw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9oxqet7y6g3iea1hux6q.png" alt="Mail sent by educative" width="880" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At last they even forgot why i was waiting. I reminded them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KDBHCP5J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uy7wobyuaxbltpj536cz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KDBHCP5J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uy7wobyuaxbltpj536cz.png" alt="Mail sent to educative" width="880" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And yes, there are lots of stuffs&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zkrPpzro--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bnnjw7tel5sa151hbn9z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zkrPpzro--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bnnjw7tel5sa151hbn9z.png" alt="Issue resolved" width="880" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Educative made me a better writer, definitely! But, communication is quite weird and is a waste of time if you are writing many apps for them. It cost me a lot of opportunities and it's a great feeling not having to deal with senseless, unpractical reviews at scale!&lt;/p&gt;

&lt;p&gt;This is my opinion, you are free to have a shot at it.&lt;/p&gt;

&lt;p&gt;Refs:&lt;/p&gt;

&lt;p&gt;The full mail&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hi Abdur-Rahmaan,&lt;/p&gt;

&lt;p&gt;I hope this email finds you well.&lt;/p&gt;

&lt;p&gt;As you know, your course was undergoing our Formal Review process. After thorough consideration, our team has decided that we will not be moving forward with the course as it does not meet our quality standards.&lt;/p&gt;

&lt;p&gt;Here are the key reasons we have taken this decision:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Some of the applications in the course are still not working despite numerous revisions and author calls where all issues were addressed and appropriate solutions were provided.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some illustrations were blurred and were asked to be replaced. Unfortunately, they still have not been rectified.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Many of the points repeatedly mentioned were not addressed but were crossed out in the document. Moreover, any questions asked were not answered either/ For example, It was requested to run Grammarly across the entire course to correct any typos and grammatical errors. Unfortunately, this is still not done.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We value all your efforts till now, and we highly appreciate the time that you have spent on this course.&lt;/p&gt;

&lt;p&gt;Please consider this an official termination of our contract.&lt;/p&gt;

&lt;p&gt;Please feel free to reach out to me if you have any questions. I wish you all the best in your future goals.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As for checked but requirements not met, it's solved according to me, so i check it. If it's deemed not met by the reviewer, then, they need to communicate why!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How To Have Django Packages in Flask</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Tue, 30 Aug 2022 03:50:48 +0000</pubDate>
      <link>https://dev.to/abdurrahmaanj/how-to-have-django-packages-in-flask-3n95</link>
      <guid>https://dev.to/abdurrahmaanj/how-to-have-django-packages-in-flask-3n95</guid>
      <description>&lt;p&gt;Django packages in Flask seems like a far-away dream, but &lt;a href="https://pypi.org/project/shopyo/"&gt;shopyo&lt;/a&gt; 4.6.0 allows you to install Shopyo apps from pypi.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Shopyo?
&lt;/h2&gt;

&lt;p&gt;Shopyo implements Django functionalities such as the admin panel etc by using existing Flask packages. But, it also implements Django-specifics like the &lt;code&gt;collectstatic&lt;/code&gt; command, migrations, apps, even new concepts like boxes etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the fuss about django packages?
&lt;/h2&gt;

&lt;p&gt;Shopyo allows you to use apps in your project. Shopyo apps are in the format&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;demo/
├── forms.py
├── global.py
├── info.json
├── models.py
├── static
├── templates
│   └── demo
│       ├── blocks
│       │   └── sidebar.html
│       └── dashboard.html
├── tests
│   ├── test_demo_functional.py
│   └── test_demo_models.py
└── view.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Until now, shopyo apps could not be installed but used locally. Now, the project has been updated to allow it! You can examine &lt;a href="https://github.com/shopyo/shopyo-demo"&gt;shopyo-demo&lt;/a&gt; the first shopyo app to get a feel of what it's like. Yes, you even have a sandbox to test the app, just like Django apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to change from older projects?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;init.py&lt;/code&gt; has a new variable called &lt;code&gt;installed_packages&lt;/code&gt; which should contain the installed app you want to add.&lt;/p&gt;

&lt;p&gt;Then, nothing to change really, just imports and in &lt;code&gt;info.json&lt;/code&gt; make sure to set module name as &lt;code&gt;shopyo_&amp;lt;your module name&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Having such a system for Flask is very convenient instead of having to build components from scratch time and again. Sites like &lt;a href="https://djangopackages.org/"&gt;djangopackages.com&lt;/a&gt; are very useful to find what we need real quick. &lt;/p&gt;

</description>
      <category>flask</category>
      <category>django</category>
      <category>shopyo</category>
    </item>
    <item>
      <title>Why I Love Elixir As A Long Time Python User</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Tue, 19 Apr 2022 05:45:10 +0000</pubDate>
      <link>https://dev.to/abdurrahmaanj/why-i-love-elixir-as-a-long-time-python-user-19ph</link>
      <guid>https://dev.to/abdurrahmaanj/why-i-love-elixir-as-a-long-time-python-user-19ph</guid>
      <description>&lt;p&gt;Discord uses Python for it's API and ELixir for &lt;a href="https://elixir-lang.org/blog/2020/10/08/real-time-communication-at-scale-with-elixir-at-discord/"&gt;realtime&lt;/a&gt; chat capabilities. Functional programming languages are off-putting for everyday uses but Elixir is just beautiful. Here's some musings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's very neat to depart from modulo. You want the remainder? Use rem!&lt;/p&gt;

&lt;p&gt;The comparison rule is also clearly spelt. Amazing!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;number &amp;lt; atom &amp;lt; reference &amp;lt; function &amp;lt; port &amp;lt; pid &amp;lt; tuple &amp;lt; map &amp;lt; list &amp;lt; bitstring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;String formatting without weird f letters are welcome!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="s"&gt;"Hello #{world_var}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But concatenation using &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; is weird though&lt;/p&gt;

&lt;p&gt;&lt;code&gt;["a"] ++ ["b"]&lt;/code&gt; sure gives a Python feel &lt;code&gt;["a"] + ["b"]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Map is convoluted though &lt;code&gt;dict = %{:x =&amp;gt; "a", "y" =&amp;gt; :z}&lt;/code&gt; but access feels at home: &lt;code&gt;dict["hello"]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The iterables could be clearer, the end statement just bugs me: &lt;code&gt;Enum.any?(["a", "aa", "aaa"], fn(s) -&amp;gt; String.length(s) == 3 end)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.&lt;/code&gt; is annoying in fn calls &lt;code&gt;sum.(2, 3)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The pipe operator is really coool!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fucntion() |&amp;gt; decorator()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Documenting feels a lot like docstrings&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Hello&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""

  """&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For comprehensions, i prefer the in keyword anytime&lt;/p&gt;

&lt;p&gt;&lt;code&gt;for x &amp;lt;- list, do: x+2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Filtering is sort of neat&lt;/p&gt;

&lt;p&gt;&lt;code&gt;for x &amp;lt;- 1..100,&lt;br&gt;
  is_even(x),&lt;br&gt;
  rem(x, 3) == 0, do: x&lt;/code&gt; i guess in Python we can do &lt;code&gt;[x for x in range(1, 100) if combined_conditions(x)]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;&amp;lt;&amp;lt;int&amp;gt;&amp;gt;&lt;/code&gt; to represent bytes is very interesting to have natively&lt;/p&gt;

&lt;p&gt;The raise use is also very pythonic &lt;code&gt;raise ArgumentError, message: "the argument value is invalid"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Concurreny is also weirdly simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Example&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;receive&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"World"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:listen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="c1"&gt;#PID&amp;lt;0.108.0&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's also far more friendly than Erlang and more readable than Haskell!&lt;/p&gt;

</description>
      <category>elixir</category>
    </item>
    <item>
      <title>Integrate p5js with socketio using Flask</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Fri, 15 Apr 2022 21:28:23 +0000</pubDate>
      <link>https://dev.to/abdurrahmaanj/integrate-p5js-with-socketio-using-flask-1b62</link>
      <guid>https://dev.to/abdurrahmaanj/integrate-p5js-with-socketio-using-flask-1b62</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/Abdur-rahmaanJ/p5js-socket-io"&gt;Github Repo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Main codes
&lt;/h2&gt;

&lt;p&gt;Server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;shopyo.api.module&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ModuleHelp&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask_socketio&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SocketIO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;join_room&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leave_room&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;emit&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;init&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;socketio&lt;/span&gt;

&lt;span class="n"&gt;mhelp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ModuleHelp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&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 class="nb"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="n"&gt;mhelp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blueprint_str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mhelp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blueprint&lt;/span&gt;
&lt;span class="n"&gt;module_blueprint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="n"&gt;mhelp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blueprint_str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;module_blueprint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mhelp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'index.html'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;socketio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'mouse'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mouse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
    &lt;span class="c1"&gt;# print(data)
&lt;/span&gt;    &lt;span class="n"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'mouse'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Client&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Websockets drawing app&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"styles.css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.socket.io/4.4.1/socket.io.min.js"&lt;/span&gt; &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H"&lt;/span&gt; &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/addons/p5.sound.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;


 &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#FFF&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;strokeWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Creating canvas&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createCanvas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;background&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="c1"&gt;// Start the socket connection&lt;/span&gt;
  &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://127.0.0.1:5000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// Callback function&lt;/span&gt;
  &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouse&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// console.log('received ' + data.color+ ' '+data.x)&lt;/span&gt;
    &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;strokeWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;py&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="c1"&gt;// Getting our buttons and the holder through the p5.js dom&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color_picker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#pickcolor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color_btn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#color-btn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color_holder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#color-holder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stroke_width_picker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#stroke-width-picker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stroke_btn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#stroke-btn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// Adding a mousePressed listener to the button&lt;/span&gt;
  &lt;span class="nx"&gt;color_btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mousePressed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Checking if the input is a valid hex color&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;^#&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;0-9A-F&lt;/span&gt;&lt;span class="se"&gt;]{6}&lt;/span&gt;&lt;span class="sr"&gt;$&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;|&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;^#&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;0-9A-F&lt;/span&gt;&lt;span class="se"&gt;]{3}&lt;/span&gt;&lt;span class="sr"&gt;$&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;color_picker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;color_picker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="nx"&gt;color_holder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;background-color&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter a valid hex value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="c1"&gt;// Adding a mousePressed listener to the button&lt;/span&gt;
  &lt;span class="nx"&gt;stroke_btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mousePressed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stroke_width_picker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;strokeWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;mouseDragged&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Draw&lt;/span&gt;
  &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;strokeWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mouseX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mouseY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pmouseX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pmouseY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// Send the mouse coordinates&lt;/span&gt;
  &lt;span class="nx"&gt;sendmouse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mouseX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mouseY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pmouseX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pmouseY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Sending data to the socket&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sendmouse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;px&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;py&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;strokeWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouse&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="nc"&gt;.call-picker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#AAA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#666&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;85px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.color-picker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;130px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#F3F3F3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;81px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="m"&gt;#DDD&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;61px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.color-holder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#AAA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;36px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="nc"&gt;.stroke_width_picker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#AAA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#666&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;85px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Choose color (# hex)&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"custom_color"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"#FFFFFF"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"pickcolor"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"call-picker"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"color-holder"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-holder call-picker"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Change color&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Choose stroke width&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"stroke_width"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"4"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"stroke-width-picker"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stroke_width_picker"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"stroke-btn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Change stroke width&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6xdBOVWE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9azkfipn7n1fosjypfx2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6xdBOVWE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9azkfipn7n1fosjypfx2.png" alt="Image description" width="880" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Opening same url in two tabs/windows&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Abdur-rahmaanJ/p5js-socket-io"&gt;Github Repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>p5js</category>
      <category>socketio</category>
      <category>flask</category>
    </item>
    <item>
      <title>Build A Note App In Flask The Fastest Possible (Using Shopyo)</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Wed, 13 Apr 2022 05:38:16 +0000</pubDate>
      <link>https://dev.to/abdurrahmaanj/build-a-note-app-in-flask-as-fast-as-it-can-get-using-shopyo-5gn0</link>
      <guid>https://dev.to/abdurrahmaanj/build-a-note-app-in-flask-as-fast-as-it-can-get-using-shopyo-5gn0</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/shopyo/shopyo/" rel="noopener noreferrer"&gt;Shopyo&lt;/a&gt; is a framework to get started with Flask really quick. It includes several libraries to get started by default. In this tutorial we will build a simple app to get started with. We used it for FlaskCon 2021 [&lt;a href="https://flaskcon.com/y/2021/#" rel="noopener noreferrer"&gt;site&lt;/a&gt;, &lt;a href="https://github.com/flaskcon/traveller" rel="noopener noreferrer"&gt;codebase&lt;/a&gt;]. This tuto's app is available &lt;a href="https://github.com/Abdur-rahmaanJ/shopyo-tuto/tree/stable/note_app" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  First steps
&lt;/h1&gt;

&lt;p&gt;The first step is to install the library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3.9 &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv &lt;span class="c"&gt;# create virtual env&lt;/span&gt;
&lt;span class="nb"&gt;.&lt;/span&gt; venv/bin/activate &lt;span class="c"&gt;# activate (linux version)&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;&lt;span class="nv"&gt;shopyo&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;4.4.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we create our folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;note_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We enter into the folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;note_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we create a new Shopyo project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shopyo new
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;creating project note_app...
#######################
[x] Project note_app created successfully!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A tree lookup gives&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── docs
│   ├── conf.py
│   ├── docs.rst
│   ├── index.rst
│   ├── Makefile
│   └── _static
│       └── custom.css
├── MANIFEST.in
├── note_app
├── pytest.ini
├── README.md
├── requirements.txt
├── setup.py
└── tox.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we are not interested in packaging our app for now, we can switch to the inner note_app/ folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;note_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The inner note_app folder has this structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── note_app
│   ├── app.py
│   ├── app.txt
│   ├── autoapp.py
│   ├── CHANGELOG.md
│   ├── cli.py
│   ├── config_demo.json
│   ├── config.py
│   ├── conftest.py
│   ├── __init__.py
│   ├── init.py
│   ├── manage.py
│   ├── modules
│   ├── shopyo_admin.py
│   ├── static
│   ├── tests
│   │   ├── conftest.py
│   │   └── test_configs.py
│   └── wsgi.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Creating modules
&lt;/h1&gt;

&lt;p&gt;Lets create the notes app&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shopyo startapp notes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A new folder will be created under &lt;code&gt;modules/&lt;/code&gt;. The content of &lt;code&gt;modules/note_app/&lt;/code&gt; looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;modules/notes/
├── forms.py
├── global.py
├── info.json
├── models.py
├── static
├── templates
│   └── notes
│       ├── blocks
│       │   └── sidebar.html
│       └── dashboard.html
├── tests
│   ├── test_notes_functional.py
│   └── test_notes_models.py
└── view.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are files created by default.&lt;/p&gt;

&lt;h1&gt;
  
  
  Writing the first view
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;info.json&lt;/code&gt; file lists some basics about the module, including it's url namespace (module_name) and url prefix&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"mail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"display_string"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Notes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fa-icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fa fa-store"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"notes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"show"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/notes"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's change &lt;code&gt;url_prefix&lt;/code&gt; to &lt;code&gt;"/"&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;view.py&lt;/code&gt; looks like this, which is generated by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;shopyo.api.module&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ModuleHelp&lt;/span&gt;

&lt;span class="n"&gt;mhelp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ModuleHelp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&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 class="nf"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="n"&gt;mhelp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blueprint_str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mhelp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blueprint&lt;/span&gt;
&lt;span class="n"&gt;module_blueprint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="n"&gt;mhelp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blueprint_str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="nd"&gt;@module_blueprint.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mhelp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;display_string&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's change the return string to &lt;code&gt;String from notes app&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@module_blueprint.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;String from notes app&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Running the app
&lt;/h1&gt;

&lt;p&gt;Run &lt;code&gt;shopyo rundebug&lt;/code&gt; to run the app in debug mode. &lt;/p&gt;

&lt;p&gt;Going to "&lt;a href="http://127.0.0.1:5000/" rel="noopener noreferrer"&gt;http://127.0.0.1:5000/&lt;/a&gt;" should return "String from notes app"&lt;/p&gt;

&lt;p&gt;You can learn more about the run command &lt;a href="https://shopyo.readthedocs.io/en/latest/commandline.html#run" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating models
&lt;/h1&gt;

&lt;p&gt;Our notes will have a title and a content. In &lt;code&gt;modules/notes/models.py&lt;/code&gt; write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;shopyo.api.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PkModel&lt;/span&gt;



&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PkModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; 

    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;notes&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;init&lt;/code&gt; import comes from the &lt;code&gt;init.py&lt;/code&gt; file.&lt;br&gt;
The &lt;code&gt;PkModel&lt;/code&gt; is same as &lt;code&gt;db.Model&lt;/code&gt; with by default &lt;code&gt;id&lt;/code&gt; as primary key&lt;/p&gt;

&lt;p&gt;Then we initialise the app. It uses Flask-Migrate under the hood. You can view more initialise options &lt;a href="https://shopyo.readthedocs.io/en/latest/commandline.html#initialise" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;shopyo initialise
initializing...
Cleaning...
&lt;span class="c"&gt;#######################&lt;/span&gt;
Auto importing models...
&lt;span class="c"&gt;#######################&lt;/span&gt;

Creating db...
&lt;span class="c"&gt;#######################&lt;/span&gt;

Migrating db...
&lt;span class="c"&gt;#######################&lt;/span&gt;

Upgrading db...
&lt;span class="c"&gt;#######################&lt;/span&gt;

Collecting static...
&lt;span class="c"&gt;#######################&lt;/span&gt;

Uploading initial data to db...
&lt;span class="c"&gt;#######################&lt;/span&gt;

All Done!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This worked as Shopyo adds a &lt;code&gt;shopyo.db&lt;/code&gt; as basic sqlalchemy connection string.&lt;/p&gt;

&lt;h1&gt;
  
  
  Configuring Flask-Admin
&lt;/h1&gt;

&lt;p&gt;Now let's configure flask-admin to have a quick CRUD view. Fortunately, Shopyo already has some basics ongoing.&lt;/p&gt;

&lt;p&gt;First, modify &lt;code&gt;shopyo_admin.py&lt;/code&gt; to remove Flask-Login authentications&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;url_for&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask_admin&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AdminIndexView&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask_admin&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;expose&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask_admin.contrib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sqla&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;flask_admin_sqla&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask_login&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DefaultModelView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flask_admin_sqla&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# def is_accessible(self):
&lt;/span&gt;    &lt;span class="c1"&gt;#     return current_user.is_authenticated and current_user.is_admin
&lt;/span&gt;
    &lt;span class="c1"&gt;# def inaccessible_callback(self, name, **kwargs):
&lt;/span&gt;    &lt;span class="c1"&gt;#     # redirect to login page if user doesn't have access
&lt;/span&gt;    &lt;span class="c1"&gt;#     return redirect(url_for("auth.login", next=request.url))
&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyAdminIndexView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AdminIndexView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# def is_accessible(self):
&lt;/span&gt;    &lt;span class="c1"&gt;#     return current_user.is_authenticated and current_user.is_admin
&lt;/span&gt;
    &lt;span class="c1"&gt;# def inaccessible_callback(self, name, **kwargs):
&lt;/span&gt;    &lt;span class="c1"&gt;#     # redirect to login page if user doesn't have access
&lt;/span&gt;    &lt;span class="c1"&gt;#     return redirect(url_for("auth.login", next=request.url))
&lt;/span&gt;
    &lt;span class="nd"&gt;@expose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# if not current_user.is_authenticated and current_user.is_admin:
&lt;/span&gt;        &lt;span class="c1"&gt;#     return redirect(url_for("auth.login"))
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# 
&lt;/span&gt;    &lt;span class="nd"&gt;@expose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/dashboard&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;indexs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# if not current_user.is_authenticated and current_user.is_admin:
&lt;/span&gt;        &lt;span class="c1"&gt;#     return redirect(url_for("auth.login"))
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in app.py, don't load Flask-Login by commenting it out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_extensions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
    &lt;span class="c1"&gt;# login_manager.init_app(app)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in &lt;code&gt;app.py&lt;/code&gt; import the Note model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;modules.notes.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Note&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And modify the &lt;code&gt;setup_flask_admin&lt;/code&gt; function to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup_flask_admin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Admin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My App&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;template_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bootstrap4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;index_view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;MyAdminIndexView&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ModelView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, navigating to &lt;code&gt;/admin&lt;/code&gt; gives&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3ozigkj23q00n5xsjc9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3ozigkj23q00n5xsjc9.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking on note allows you to edit the Note model. Let's add few models!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fre17hbi920kg48gr6lax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fre17hbi920kg48gr6lax.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Displaying templates
&lt;/h1&gt;

&lt;p&gt;What remains is using displaying the note on our main page.&lt;/p&gt;

&lt;p&gt;Under &lt;code&gt;modules/notes/templates/notes&lt;/code&gt; create a file called index.html with content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    {% for note in notes %}
        {{note.title}}&lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
        {{note.content}}&lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
    {% endfor %}
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the view.py to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;shopyo.api.module&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ModuleHelp&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Note&lt;/span&gt; 


&lt;span class="n"&gt;mhelp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ModuleHelp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&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 class="nf"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="n"&gt;mhelp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blueprint_str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mhelp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blueprint&lt;/span&gt;
&lt;span class="n"&gt;module_blueprint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="n"&gt;mhelp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blueprint_str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="nd"&gt;@module_blueprint.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;notes/index.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which results in:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptx26y6y8yya7zxqqe5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptx26y6y8yya7zxqqe5v.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Shopyo also provides some utils like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from shopyo.api.templates import yo_render

...
@module_blueprint.route("/")
def index():
    notes = Note.query.all()
    context = {
        'notes': notes
    }
    return yo_render('notes/index.html', context)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Trying out a demo app
&lt;/h1&gt;

&lt;p&gt;If you just want to try a demo app, just run (comment back the flask-login modifications)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir project
cd project
shopyo new -m # -m adds default modules
cd project
shopyo initialise
shopyo rundebug
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then see how an authed Flask-Admin looks like.&lt;/p&gt;

&lt;p&gt;Hope you enjoy this post!&lt;/p&gt;

&lt;p&gt;This tuto's app is available &lt;a href="https://github.com/Abdur-rahmaanJ/shopyo-tuto/tree/stable/note_app" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flask</category>
      <category>shopyo</category>
    </item>
    <item>
      <title>Github Finally Fixes Issue That Was Costing  Lot of Wasted Space</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Fri, 10 Dec 2021 11:30:30 +0000</pubDate>
      <link>https://dev.to/abdurrahmaanj/github-finally-fixes-issue-that-was-costing-tbs-of-wasted-space-30j</link>
      <guid>https://dev.to/abdurrahmaanj/github-finally-fixes-issue-that-was-costing-tbs-of-wasted-space-30j</guid>
      <description>&lt;p&gt;Github had all a GIT-in-the-cloud service needed. It added much more features, like the dark mode. It hit hard on community aspects.&lt;/p&gt;

&lt;p&gt;But it missed one thing early on, to identify how people used the app, what for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--arqklty---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s3bcywem4ojavqf5nnu6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--arqklty---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s3bcywem4ojavqf5nnu6.jpg" alt="Footpath trails" width="880" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Much like foot trails in Urban Planning. You can read more here: &lt;a href="https://www.theguardian.com/cities/2018/oct/05/desire-paths-the-illicit-trails-that-defy-the-urban-planners"&gt;Desire paths: the illicit trails that defy the urban planners&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;People sometimes use the most convenient solution in your setup even if you did not have plans for it. And it might be a flag that your design is flawed, to some degree.&lt;/p&gt;

&lt;h2&gt;
  
  
  People have always used Github forks as bookmarks
&lt;/h2&gt;

&lt;p&gt;Much to the horror of the Linux/Unix/freeBSD OpenSource community, Github users have been forking projects. Forks are not welcomed. Even a for forking &lt;a href="https://opensource.com/article/19/1/forking-good"&gt;article&lt;/a&gt; on opensource.com starts with &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Although forking is undesirable, ...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But many many of those forks were unnecessary. And they cost storage space. People have always used forks to bookmark projects. And Github has been battling wastage. At one time i remember Github offering to delete forks when PRs were merged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally fixed
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RMgZPf1h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gegyzwr3tpvn4o6cex3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RMgZPf1h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gegyzwr3tpvn4o6cex3e.png" alt="Github bookmarks" width="880" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can add your favourite project to your well favourite list. No longer need to fork!&lt;/p&gt;

</description>
      <category>github</category>
    </item>
    <item>
      <title>FlaskCon 2021 Links</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Wed, 08 Dec 2021 07:50:20 +0000</pubDate>
      <link>https://dev.to/flaskcon/flaskcon-2021-links-4jii</link>
      <guid>https://dev.to/flaskcon/flaskcon-2021-links-4jii</guid>
      <description>&lt;p&gt;FlaskCon 2021 / &lt;a href="https://youtube.com/c/flaskcon"&gt;https://youtube.com/c/flaskcon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This edition hosted another round of great Flask content, coupled with the inclusion of Podcasts. Have fun watching!&lt;/p&gt;




&lt;p&gt;Flask-Multipass - A pluggable authentication framework for Flask by Adrian Monnich&lt;br&gt;
&lt;a href="https://youtu.be/j37wYpiYRQY"&gt;https://youtu.be/j37wYpiYRQY&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Debugging flask application within a docker container using VSCode by Ashok Tankala&lt;br&gt;
&lt;a href="https://youtu.be/VjIYcJVZCP0"&gt;https://youtu.be/VjIYcJVZCP0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enabling multi-tenancy with werkzeug by Abdeali (Ali) Kothari&lt;br&gt;
&lt;a href="https://youtu.be/EP0GaIQvr0c"&gt;https://youtu.be/EP0GaIQvr0c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Building Scalable APIs Using Flask and Docker by Emma Donery&lt;br&gt;
&lt;a href="https://youtu.be/sbdQPA60BjI"&gt;https://youtu.be/sbdQPA60BjI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Application config management: Lightweight but enterprise-ready by Abdeali (Ali) Kothari&lt;br&gt;
&lt;a href="https://youtu.be/01zPKbRpgOo"&gt;https://youtu.be/01zPKbRpgOo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hassle Free Desktop Apps with Flask by Alin Climente&lt;br&gt;
&lt;a href="https://youtu.be/RApsKoC1a7s"&gt;https://youtu.be/RApsKoC1a7s&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whole stream with QnA&lt;br&gt;
&lt;a href="https://youtu.be/-KyYRB0ffns"&gt;https://youtu.be/-KyYRB0ffns&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Making Location-Searchable Sites Using Geocoding and Elasticsearch by Jay Miller&lt;br&gt;
&lt;a href="https://youtu.be/KZnXjvtgABc"&gt;https://youtu.be/KZnXjvtgABc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dockerizing Flask For Production by Nico Plyley&lt;br&gt;
[ speaker out ]&lt;/p&gt;

&lt;p&gt;Testing Flask Applications with pytest by Patrick Kennedy&lt;br&gt;
&lt;a href="https://youtu.be/OcD52lXq0e8"&gt;https://youtu.be/OcD52lXq0e8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Improve the efﬁciency of your Flask app's frontend by Randy Duodu &lt;br&gt;
&lt;a href="https://youtu.be/CvZQ6bfpL00"&gt;https://youtu.be/CvZQ6bfpL00&lt;/a&gt; &lt;br&gt;
[ audio not good, in livetream talk to be found with good audio,&lt;br&gt;
will send updated link soon ]&lt;/p&gt;

&lt;p&gt;Building Secured Flask Apps by Randy Duodu&lt;br&gt;
&lt;a href="https://youtu.be/F3jCc_RMHMU"&gt;https://youtu.be/F3jCc_RMHMU&lt;/a&gt; &lt;br&gt;
[ audio not good, in livetream talk to be found with good audio,&lt;br&gt;
will send updated link soon ]&lt;/p&gt;

&lt;p&gt;HTMX + Flask: Modern Python Web Apps, Hold the JavaScript by Michael Kennedy&lt;br&gt;
&lt;a href="https://youtu.be/kNXVFB5eQfo"&gt;https://youtu.be/kNXVFB5eQfo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whole stream with QnA&lt;br&gt;
&lt;a href="https://youtu.be/LCDa3RftUu0"&gt;https://youtu.be/LCDa3RftUu0&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Workshop: Building An Awesome SASS App by Sumukh Sridhara&lt;br&gt;
&lt;a href="https://youtu.be/biURI5jLGzM"&gt;https://youtu.be/biURI5jLGzM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Workshop: Packaging a Flask App: Deep Dive Into The Wheels of Packaging by Alexander Hultner&lt;br&gt;
&lt;a href="https://youtu.be/DThFxooHEJk"&gt;https://youtu.be/DThFxooHEJk&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Podcast: How To Leverage Flask To Win Hackathons by Anush Krishna V &lt;br&gt;
&lt;a href="https://youtu.be/dKD0rwTJ3IA"&gt;https://youtu.be/dKD0rwTJ3IA&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Podcast: Building And Shipping Flask Side Projects Fast With Abhishek Kaushik &lt;br&gt;
&lt;a href="https://youtu.be/LGGQ-zRt14k"&gt;https://youtu.be/LGGQ-zRt14k&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Podcast: Experience Learning Flask With David Carmichael &lt;br&gt;
&lt;a href="https://youtu.be/xsZpLVdEsDk"&gt;https://youtu.be/xsZpLVdEsDk&lt;/a&gt;&lt;/p&gt;




</description>
      <category>flask</category>
      <category>python</category>
      <category>flaskcon</category>
    </item>
    <item>
      <title>Getting started with Python-efl</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Tue, 26 Oct 2021 21:49:18 +0000</pubDate>
      <link>https://dev.to/abdurrahmaanj/getting-started-with-python-efl-3oke</link>
      <guid>https://dev.to/abdurrahmaanj/getting-started-with-python-efl-3oke</guid>
      <description>&lt;p&gt;&lt;a href="https://www.enlightenment.org/about-efl.md"&gt;EFL&lt;/a&gt; stands for Enlightment Foundation Libraries which was started by &lt;a href="https://en.wikipedia.org/wiki/Carsten_Haitzler"&gt;Carsten Haitzler&lt;/a&gt; aka rasterman. It started originally for the &lt;a href="https://www.enlightenment.org/"&gt;enlightenment desktop&lt;/a&gt; project.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Python-efl
&lt;/h2&gt;

&lt;p&gt;Python-efl are the python bindings for it. Here's the links i prepared so that people can get started quickly. I'll be adding more resources as i come across them!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pythonkitchen.com/how-to-install-python-efl-on-ubuntu-or-linux-mint/"&gt;https://www.pythonkitchen.com/how-to-install-python-efl-on-ubuntu-or-linux-mint/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pythonkitchen.com/python-efl-1/"&gt;https://www.pythonkitchen.com/python-efl-1/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pythonkitchen.com/python-efl-2/"&gt;https://www.pythonkitchen.com/python-efl-2/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pythonkitchen.com/python-efl-3/"&gt;https://www.pythonkitchen.com/python-efl-3/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pythonkitchen.com/python-efl-4/"&gt;https://www.pythonkitchen.com/python-efl-4/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pythonkitchen.com/python-efl-5/"&gt;https://www.pythonkitchen.com/python-efl-5/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pythonkitchen.com/python-efl-6/"&gt;https://www.pythonkitchen.com/python-efl-6/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pythonkitchen.com/python-efl-7/"&gt;https://www.pythonkitchen.com/python-efl-7/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pythonkitchen.com/python-efl-8/"&gt;https://www.pythonkitchen.com/python-efl-8/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>efl</category>
      <category>pythonefl</category>
    </item>
    <item>
      <title>Why FlaskCon insists on having publicly listed reviewers</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Tue, 12 Oct 2021 21:54:43 +0000</pubDate>
      <link>https://dev.to/flaskcon/why-flaskcon-insists-on-having-publicly-listed-reviewers-2de1</link>
      <guid>https://dev.to/flaskcon/why-flaskcon-insists-on-having-publicly-listed-reviewers-2de1</guid>
      <description>&lt;p&gt;Python conferences all have a team of reviewers. Not made public. Since the first edition of FlaskCon, we made our list public. This encourages transparency and builds trust. People often ask: Why? If some great conferences don't do it, that means it is not important or necessary. But not necessarily so ...&lt;/p&gt;

&lt;p&gt;Before we dig deeper, please have a look at Python conferences having a list of &lt;strong&gt;publicly&lt;/strong&gt; disclosed reviewers for 2021 [1]:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Conference&lt;/th&gt;
&lt;th&gt;Has public list of reviewers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PyCon US&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EuroPython&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PyCon India&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PyCon Japan&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FlaskCon&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://2019.djangocon.us/news/call-for-community-reviewers/"&gt;Django Con&lt;/a&gt; had a call for community reviewers. First come, first serve.&lt;/p&gt;

&lt;p&gt;Well, at FlaskCon we are adamant that people who review talks be competent in the field they are in. And, they should be displayed. So that we know it's not my cat's backyard buddy who is helping out with the reviews. We just want as a conference to get the best talks possible selected. &lt;/p&gt;

&lt;p&gt;So if a big conference does not have that feature, that does not mean we should tick it off. And i do think it's very weird for conferences who go to great lengths at perfecting details not to have it. An even more unsettling question is: Why keep it a secret. Is there some dark business going on? We hope no ...&lt;/p&gt;

&lt;p&gt;[1] As far as i searched&lt;/p&gt;

</description>
      <category>flaskcon</category>
      <category>flask</category>
      <category>python</category>
    </item>
    <item>
      <title>Why Choose Flask Over FastAPI</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Sun, 18 Apr 2021 21:56:37 +0000</pubDate>
      <link>https://dev.to/abdurrahmaanj/why-choose-flask-over-fastapi-n5o</link>
      <guid>https://dev.to/abdurrahmaanj/why-choose-flask-over-fastapi-n5o</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/tiangolo/fastapi"&gt;FastAPI&lt;/a&gt; positions itself as one of the best choices for API development in Python. The project is polished for sure, the &lt;a href="https://fastapi.tiangolo.com/"&gt;docs&lt;/a&gt; are sleek and the commit messages awesome. It collected some nice parts and pieced them together to produce an artifact infused and driven by pragmatism. But the community is wrong, completely wrong and over hyped in comparing FastAPI with it's father in inspiration: The awesome, one &amp;amp; only, unique Flask&lt;/p&gt;

&lt;h2&gt;
  
  
  Index
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;FastAPI: Standing on the shoulders of giants&lt;/li&gt;
&lt;li&gt;A Culture Of Pushy Marketing: When Python Is Suddenly As Fast As Golang&lt;/li&gt;
&lt;li&gt;The Tiangolo Docs Says You Are Wrong Comparing FastAPI To Flask&lt;/li&gt;
&lt;li&gt;They All Fell Into The Trap: CTO, Respected Authors, StackOverflow's Partner, Big Names and What Not&lt;/li&gt;
&lt;li&gt;What To Compare With What?&lt;/li&gt;
&lt;li&gt;Why Choose Flask Over FastAPI&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FastAPI: Standing on the shoulders of giants
&lt;/h2&gt;

&lt;p&gt;If one was to introduce and understand FastAPI, there is no better introduction than in the moustachu wizard's words:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here's some extra background that might help understanding where they come from.&lt;br&gt;
The creator of Django-Rest-Framework, Tom Christie, created a new API framework with what he thought would be the best approach for building APIs in modern Python. It was called APIStar.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;APIStar had to deal with some complexities underneath like supporting WSGI (the same used by Flask and Django) and ASGI, the new standard, etc. So, at some point, Tom decided that a new approach was needed. So, he created a new framework/toolkit form scratch, based on ASGI, called Starlette. The server part of APIStar was deprecated and from then on APIStar was only a set of tools for OpenAPI validation.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Then, FastAPI was created on top of Starlette, inheriting a lot of the ideas form APIStar (that actually come from even before, with Hug) and updating/improving them, to use standard Python type hints, dependency injection, OpenAPI with docs by default, etc.&lt;/em&gt; [1]&lt;/p&gt;

&lt;p&gt;It's also being used by Microsoft, Netflix and Uber [2]. So it's a respected package, being given serious thoughts and considerations in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Culture Of Pushy Marketing: When Python Is Suddenly As Fast As Golang
&lt;/h2&gt;

&lt;p&gt;FastAPI states in it's README [3]: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The key features are:&lt;/p&gt;

&lt;p&gt;Fast: Very high performance, on par with NodeJS and Go (thanks to Starlette and Pydantic). &lt;a href="https://github.com/tiangolo/fastapi#performance"&gt;One of the fastest Python frameworks available&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Someone raised an issue entitled: Very poor performance does not align with marketing [4]. Some developers tried to assign a meaning to the phrase &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Very high performance, on par with NodeJS and Go&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They hold that it means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you didn't use FastAPI and used Starlette directly (or another tool, like Sanic, Flask, Responder, etc) you would have to implement all the data validation and serialization yourself. So, your final application would still have the same overhead as if it was built using FastAPI. And in many cases, this data validation and serialization is the biggest amount of code written in applications.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the author is not going away with on par with. &lt;/p&gt;

&lt;p&gt;According to the Cambridge dictionary [5]:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;on par with: the same as or equal to someone or something&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;According to Oxford's learner's dictionary it means [6]:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;on a par/level with somebody/something &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;as good, bad, important, etc. as somebody/something else&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tiangolo actually sheds some light on what it actually means:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Starlette was made to be a minimal micro-framework and toolkit at the same time, so that other tools could be built on top of it, but providing a very solid foundation, and the best performance available in Python, on par with NodeJS and Go.&lt;/em&gt; [1]&lt;/p&gt;

&lt;p&gt;So unlike the attempted explanation above or what FastAPI fans would try to produce, the author is clearly saying that a minimal micro-framework in Python (that is Starlette) is as fast as Golang. &lt;/p&gt;

&lt;p&gt;Well FastAPI folks, you can't explain it better than the author. &lt;/p&gt;

&lt;p&gt;It's no wonder that the fan base attempt some wind in sail comparisons. Tiangolo &amp;amp; Co., you set the trend.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tiangolo Docs Says You Are Wrong Comparing FastAPI To Flask
&lt;/h2&gt;

&lt;p&gt;There are an awesome amount of articles stating: Why we moved from Flask to FastAPI, Why I quit Flask, How to move from Flask to FastAPI. This is just crazy. I mean, come on folks, how can you miss the basic facts?&lt;/p&gt;

&lt;p&gt;The docs might seems misleading. In discussing alternatives to FastAPI, it lists Flask [7]. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Flask is a "microframework", it doesn't include database integrations nor many of the things that come by default in Django.&lt;/p&gt;

&lt;p&gt;This simplicity and flexibility allow doing things like using NoSQL databases as the main data storage system.&lt;/p&gt;

&lt;p&gt;As it is very simple, it's relatively intuitive to learn, although the documentation gets somewhat technical at some points.&lt;/p&gt;

&lt;p&gt;It is also commonly used for other applications that don't necessarily need a database, user management, or any of the many features that come pre-built in Django. Although many of these features can be added with plug-ins.&lt;/p&gt;

&lt;p&gt;This decoupling of parts, and being a "microframework" that could be extended to cover exactly what is needed was a key feature that I wanted to keep.&lt;/p&gt;

&lt;p&gt;Given the simplicity of Flask, it seemed like a good match for building APIs. The next thing to find was a "Django REST Framework" for Flask.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's why fans go on to compare with Flask? I don't know. It's misleading for sure as people don't bother to actually read the whole page. The very same page actually lists requests saying: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;FastAPI is not actually an alternative to Requests. Their scope is very different.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So this is not really a page for comparisons, at least not all. Don't take my words for it. The docs tells you:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are comparing FastAPI, compare it against a web application framework (or set of tools) that provides data validation, serialization and documentation, like Flask-apispec, NestJS, Molten, etc. Frameworks with integrated automatic data validation, serialization and documentation. [8]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before you write Flask-bashing articles, at least read the FastAPI docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  They All Fell Into The Trap: CTO, Respected Authors, StackOverflow's Partner, Big Names and What Not
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Testdriven.io
&lt;/h4&gt;

&lt;p&gt;One of the Testdriven.io blog authors whom i respect a lot, Amal Shaji wrote an article: Moving from Flask to FastAPI [9]. It's really puzzling to see that such an author, on such a blog has such an understanding. The article goes on detailing how do the installs compare etc. Side by side comparison of views templates etc. The author mentions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can think of FastAPI as the glue that brings together Starlette, Pydantic, OpenAPI, and JSON Schema.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;it should have clicked like: well am i comparing some comparable things or not? Why not compare Flask and Starlette? The author ends with a sweeping statement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Switching to FastAPI is a solid choice.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These types of articles while seemingly genuine just repel people from Flask.&lt;/p&gt;

&lt;h4&gt;
  
  
  Yuan Gao, The CTO
&lt;/h4&gt;

&lt;p&gt;Yuan Gao wrote a somewhat lengthy article entitled: Flask vs FastAPI first impressions [10]. The person compares with visible enthusiasm:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I've recently upgraded several of our API endpoints over from Flask to FastAPI, and honestly I haven't felt such a breath of fresh air in development for a long time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The person was really thinking that jsonify was the tool for apis:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Contrast this with Flask, whose errors are HTML pages by default, and return JSON need to be jsonify()'d&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The comparison is a devastating head shaking piece, dripping all the way down:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In Flask, you access both query and request body via the request singleton, which is a magic instance that when referenced inside and endpoint handler contains stuff relating to the request. ... This is actually highly annoying.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He complains of the lack of validation in Flask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;With Flask, there aren't many options for this; you either write a lot of if statements to check every possible part of the data coming in, and then manually make sure to go update your API documentation somewhere, or you use some kind of data validation library.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even complaining of the lack of web sockets in Flask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Websockets are another feature that Flask does't support, &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And concludes with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So while it's clear to me that FastAPI is a much better framework than Flask for APIs, Flask still remains a good choice for many other HTTP tasks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A miss all over and an overall mess.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pluralsight.com
&lt;/h4&gt;

&lt;p&gt;That one got a 'wow' from me. I mean, pluralsight is busy schooling and rating developers around the world. StackOverflow partnered with them to educate devs. I don't know where to put my head. John Walk writes [14]:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This API will work for serving predictions (try it out yourself!)… but it’s entirely likely it will fall over if you try to put it into production. Notably, it lacks any data validation - any missing, misnamed, or mistyped information in the incoming request results in an unhandled exception, returning a 500 error and a singularly unhelpful response from Flask (along with some rather intimidating HTML in debug mode), while potentially firing alerts into your monitoring systems and waking up your DevOps.&lt;/p&gt;

&lt;p&gt;Frequently, error handling in Flask ends up with a brittle, tangled jumble of try-catches and protected dict access. Better approaches will use a package like pydantic or marshmallow to achieve more programmatic data validation. Fortunately, FastAPI includes pydantic validation out of the box.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I mean how can people not blame Flask when pluralsight tells them to? And Flask is not to be blamed.&lt;/p&gt;

&lt;h4&gt;
  
  
  It's Splashed All Over
&lt;/h4&gt;

&lt;p&gt;AnalyticsVidhya has an article by KAUSTUBH1828 [11] which repeats the arguments mentionned above. Section.io has one [12] by the name of "Choosing between Django, Flask, and FastAPI", Django added for better mismatch. It's published under Engineering Education. Oh my! Same goes for acubits.com [13]. Tivadar Danka from towardsdatascience.com [15] says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For many years, Flask was the number one tool for the job, but in case you haven’t heard, there is a new challenger in town. FastAPI is a relatively new web framework for Python, taking inspiration from its predecessors, perfecting them and fixing many of their flaws. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and the title of the article is: "You Should Start Using FastAPI Now". And the portrayal are indeed in bashing style like Dieter Jordens from betterprogramming.pub [16] entitled "3 Reasons to Switch to FastAPI":&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;FastAPI is based on type hints. Up to this point, Flask has just plain ignored them. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The problem is that people hush Flask down under a False starting point, and some go hard on it. Cover to cover, first letter to last dot, these articles made a faux depart.&lt;/p&gt;

&lt;h4&gt;
  
  
  Re-stating: What these articles did wrong?
&lt;/h4&gt;

&lt;p&gt;They simply compared Flask to FastAPI. They miscompared frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  What To Compare With What?
&lt;/h2&gt;

&lt;p&gt;You can compare Flask with Starlette. You can compare Flask-restx or flask-apispec to FastApi. You can compare Quart to Flask and Starlette. You can compare Quart-schema to FastAPI and Flask-aspispec. &lt;/p&gt;

&lt;p&gt;Flask is a micro web framework. Starlette is a "is a lightweight ASGI framework/toolkit". Flask is a WSGI framework and Starlette is an ASGI one. They are barebones, non-purpose specific frameworks. Flask-restx is designed to build APIs, this is closer to FastAPI. It completely misses the point saying Flask misses validation or this and that while FastAPI has this and that. When you compare, compare the frameworks that match in purpose to start with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Choose Flask Over FastAPI
&lt;/h2&gt;

&lt;p&gt;The title is just a note saying why you should not go about writing articles that way. The article is deliberately mistitled and put en relief the point that you should not compare Flask to FastAPI nor compare FastAPI to Flask. Both serve different purposes.&lt;/p&gt;

&lt;h4&gt;
  
  
  FaQ
&lt;/h4&gt;

&lt;p&gt;Point: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A miss all over and an overall mess."&lt;/p&gt;

&lt;p&gt;Why does the article just state this opinion and then do little else? Did I miss something? I was expecting some paragraphs afterwards about reasons why, but there are none to be found.&lt;/p&gt;

&lt;p&gt;This sorta just reeks of bitterness.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A miss all over and an overall mess illustrates the results you get when you compare two things which should not be compared.&lt;/p&gt;




&lt;p&gt;Point:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are certainly reasons to choose Flask over FastAPI, but this article reads like it was written by an AI.&lt;/p&gt;

&lt;p&gt;"The problem is that people hush Flask down under a False starting point, and some go hard on it. Cover to cover, first letter to last dot, these articles made a faux depart."&lt;/p&gt;

&lt;p&gt;If an actual human wrote this: I have no idea what you are trying to say.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;People make points but they are False from the start.&lt;/p&gt;




&lt;p&gt;[1] &lt;a href="https://news.ycombinator.com/item?id=22776339"&gt;https://news.ycombinator.com/item?id=22776339&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://fastapi.tiangolo.com/"&gt;https://fastapi.tiangolo.com/&lt;/a&gt;&lt;br&gt;
[3] &lt;a href="https://github.com/tiangolo/fastapi"&gt;https://github.com/tiangolo/fastapi&lt;/a&gt;&lt;br&gt;
[4] &lt;a href="https://github.com/tiangolo/fastapi/issues/1664"&gt;https://github.com/tiangolo/fastapi/issues/1664&lt;/a&gt;&lt;br&gt;
[5] &lt;a href="https://dictionary.cambridge.org/dictionary/english/par"&gt;https://dictionary.cambridge.org/dictionary/english/par&lt;/a&gt;&lt;br&gt;
[6] &lt;a href="https://www.oxfordlearnersdictionaries.com/definition/english/level_1#level_idmg_6"&gt;https://www.oxfordlearnersdictionaries.com/definition/english/level_1#level_idmg_6&lt;/a&gt;&lt;br&gt;
[7] &lt;a href="https://fastapi.tiangolo.com/alternatives/"&gt;https://fastapi.tiangolo.com/alternatives/&lt;/a&gt;&lt;br&gt;
[8] &lt;a href="https://fastapi.tiangolo.com/benchmarks/"&gt;https://fastapi.tiangolo.com/benchmarks/&lt;/a&gt;&lt;br&gt;
[9] &lt;a href="https://testdriven.io/blog/moving-from-flask-to-fastapi/"&gt;https://testdriven.io/blog/moving-from-flask-to-fastapi/&lt;/a&gt;&lt;br&gt;
[10] &lt;a href="https://dev.to/meseta/flask-vs-fastapi-first-impressions-1bnm"&gt;https://dev.to/meseta/flask-vs-fastapi-first-impressions-1bnm&lt;/a&gt;&lt;br&gt;
[11] &lt;a href="https://www.analyticsvidhya.com/blog/2020/11/fastapi-the-right-replacement-for-flask/"&gt;https://www.analyticsvidhya.com/blog/2020/11/fastapi-the-right-replacement-for-flask/&lt;/a&gt;&lt;br&gt;
[12] &lt;a href="https://www.section.io/engineering-education/choosing-between-django-flask-and-fastapi/"&gt;https://www.section.io/engineering-education/choosing-between-django-flask-and-fastapi/&lt;/a&gt;&lt;br&gt;
[13] &lt;a href="https://blog.accubits.com/flask-vs-fastapi-which-one-should-you-choose/"&gt;https://blog.accubits.com/flask-vs-fastapi-which-one-should-you-choose/&lt;/a&gt;&lt;br&gt;
[14] &lt;a href="https://www.pluralsight.com/tech-blog/porting-flask-to-fastapi-for-ml-model-serving/"&gt;https://www.pluralsight.com/tech-blog/porting-flask-to-fastapi-for-ml-model-serving/&lt;/a&gt;&lt;br&gt;
[15] &lt;a href="https://towardsdatascience.com/you-should-start-using-fastapi-now-7efb280fec02"&gt;https://towardsdatascience.com/you-should-start-using-fastapi-now-7efb280fec02&lt;/a&gt;&lt;br&gt;
[16] &lt;a href="https://betterprogramming.pub/3-reasons-to-switch-to-fastapi-f9c788d017e5owardsdatascience.com/you-should-start-using-fastapi-now-7efb280fec02"&gt;https://betterprogramming.pub/3-reasons-to-switch-to-fastapi-f9c788d017e5owardsdatascience.com/you-should-start-using-fastapi-now-7efb280fec02&lt;/a&gt;&lt;br&gt;
[16] &lt;a href="https://betterprogramming.pub/3-reasons-to-switch-to-fastapi-f9c788d017e52"&gt;https://betterprogramming.pub/3-reasons-to-switch-to-fastapi-f9c788d017e52&lt;/a&gt;&lt;br&gt;
[16] &lt;a href="https://betterprogramming.pub/3-reasons-to-switch-to-fastapi-f9c788d017e5"&gt;https://betterprogramming.pub/3-reasons-to-switch-to-fastapi-f9c788d017e5&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>flask</category>
      <category>fastapi</category>
    </item>
    <item>
      <title>Python Generators: The In-depth Article You’ve Always Wanted</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Thu, 10 Dec 2020 06:51:48 +0000</pubDate>
      <link>https://dev.to/abdurrahmaanj/python-generators-the-in-depth-article-you-ve-always-wanted-96p</link>
      <guid>https://dev.to/abdurrahmaanj/python-generators-the-in-depth-article-you-ve-always-wanted-96p</guid>
      <description>&lt;h1&gt;
  
  
  Table of contents
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Why were Python generators introduced?&lt;/li&gt;
&lt;li&gt;How do Python Generators differ from normal functions?&lt;/li&gt;
&lt;li&gt;Execution flow&lt;/li&gt;
&lt;li&gt;Immediate usefulness&lt;/li&gt;
&lt;li&gt;next and for loops&lt;/li&gt;
&lt;li&gt;Generators introduced for memory saving&lt;/li&gt;
&lt;li&gt;Generators for tasks&lt;/li&gt;
&lt;li&gt;The send method&lt;/li&gt;
&lt;li&gt;Deriving send&lt;/li&gt;
&lt;li&gt;What is yield from&lt;/li&gt;
&lt;li&gt;The last part&lt;/li&gt;
&lt;li&gt;The limit of generators: Infinity and Beyond&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Python, generators form part of the intermediate topics. Since it differs from conventional functions, beginners have to take sometimes to wrap their head around it. This article presents materials that will be useful both for beginners and advanced programmers. It attempts to give enough to understand generators in depth but don't cover all use cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why were Python generators introduced?
&lt;/h3&gt;

&lt;p&gt;Before we present generators and it's syntax, it's important to know why in the first place were generators introduced. The yield keyword does not mean generators. One has to understand the concept behind. The original PEP introduced "the concept of generators to Python, as well as a new statement used in conjunction with them, the yield statement" [1].&lt;/p&gt;

&lt;p&gt;The general use case of generators is as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When a producer function has a hard enough job that it requires maintaining state between values produced, [1]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And more explicitly&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;provide a kind of function that can return an intermediate result ("the next value") to its caller, but maintaining the function's local state so that the function can be resumed again right where it left off. [1]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So we understand that a new kind of functions was needed that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. return intermediate values&lt;/li&gt;
&lt;li&gt;2. save the state of functions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How do Python Generators differ from normal functions?
&lt;/h3&gt;

&lt;p&gt;Compared to normal functions, once you return from a function, you can go back to return more values. A normal function in contrast, once you return from it, there is no going back.&lt;/p&gt;

&lt;p&gt;Normal function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'abc'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; 
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'def'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# not reached
&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, &lt;code&gt;def&lt;/code&gt; will not be printed as the function exited before. Let's examine a basic generator example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;

    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;generator object x at 0x01ACB760&amp;gt;
0
1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the example above, once we called next, it returned a value. &lt;strong&gt;The purpose of next is to go to the next yield statement&lt;/strong&gt;. When we called next the first time, it went to the next yield since the beginning which is when &lt;code&gt;a&lt;/code&gt; was initially at 0. &lt;/p&gt;

&lt;p&gt;The second call of next started executing &lt;code&gt;a += 1&lt;/code&gt; and went to the beginning of the loop where it encountered a yield statement and returned &lt;code&gt;a&lt;/code&gt; with the updated value.&lt;/p&gt;

&lt;p&gt;By &lt;code&gt;a&lt;/code&gt; being updated we see that even when the function was exited the first time, when the program went back into it, it continued on the previous state when &lt;code&gt;a&lt;/code&gt; was 0. This accomplishes the two aims of being able to resume functions and saving the previous state.&lt;/p&gt;

&lt;p&gt;To understand it better, here are some more names that were proposed instead of yield [1] but were eventually rejected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;return 3 and continue&lt;/li&gt;
&lt;li&gt;return and continue 3&lt;/li&gt;
&lt;li&gt;return generating 3&lt;/li&gt;
&lt;li&gt;continue return 3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Guido gives a summary of generators [1]:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In practice (how you think about them), generators are functions, but with the twist that they're resumable. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Execution flow
&lt;/h3&gt;

&lt;p&gt;The following snippet gives us an idea about the execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'started'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'before yield'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after yield'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'-- 2nd call'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;started
before yield
-- 2nd call
after yield
before yield
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From it we confirm that the first call to next executes everything in the function until the first yield statement. We did not return any values but used yield purely to control the flow of execution in the same sense of return.&lt;/p&gt;

&lt;p&gt;Yield needs not to be in infinite loops, you can use several at once in the same function body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'start'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; 
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after 1st yield'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after 2nd yield'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;start
after 1st yield
after 2nd yield
Traceback (most recent call last):
  File "lab.py", line 11, in &amp;lt;module&amp;gt;
    next(z)
StopIteration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In case you called next more than there is yield statements, generator functions raise the &lt;code&gt;StopIteration&lt;/code&gt;. In case you want to auto-handle &lt;code&gt;StopIteration&lt;/code&gt; until there are no more left, use ... a for loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'start'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; 
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after 1st yield'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after 2nd yield'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In case you return a value, the loop variable will be equal to that value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'start'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after 1st yield'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after 2nd yield'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;start
1
after 1st yield
2
after 2nd yield
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Immediate usefulness
&lt;/h3&gt;

&lt;p&gt;Since we saw that we can use yield with an infinite loop, this is extremely powerful. We can break infinity in steps. Consider this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;odd_till&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;odd_num&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;odd_till&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 class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;odd_num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We yield one number and the function exits, the for loop calls it again. It yields one number and exits. And so on. It goes about it in micro steps. The operations completed in one cycle is is just an increment &lt;code&gt;n += 2&lt;/code&gt; and a check &lt;code&gt;n &amp;lt; number&lt;/code&gt;.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;odd_till(10)&lt;/code&gt; or &lt;code&gt;odd_till(10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)&lt;/code&gt; don't not cause memory errors&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  next and for loops
&lt;/h3&gt;

&lt;p&gt;Two things might puzzle you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;why was next used?&lt;/li&gt;
&lt;li&gt;how can a function with 2 yields work when a for loop is used with it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The answer lies in in the fact that generators implement the iterator protocols, the same one used by lists. Here is a class customised to act as a generator [7]:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Using the generator pattern (an iterable)
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;firstn&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 class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&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;n&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;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&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;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__iter__&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="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;

    &lt;span class="c1"&gt;# Python 3 compatibility
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__next__&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="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;next&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="k"&gt;if&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;num&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;cur&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;num&lt;/span&gt; &lt;span class="o"&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;num&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;num&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;StopIteration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;sum_of_first_n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;firstn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generators introduced for memory saving
&lt;/h3&gt;

&lt;p&gt;Consider a list comprehension:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sum([x*x for x in range(10)])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A generator expression is much, much more efficicent [2]:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sum(x*x for x in range(10))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was the second addition in the generator story.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generators for tasks
&lt;/h3&gt;

&lt;p&gt;Lets modify our two functions with print&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;odd_till&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'odd_till {} currently: {}'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;even_till&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'even_till {} currently: {}'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets have a class to run functions&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&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;deque&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RunFunc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__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="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deque&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_func&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;func&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;_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&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="k"&gt;while&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;_queue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="o"&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;_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;popleft&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;StopIteration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;usage&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;func_runner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RunFunc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;func_runner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;odd_till&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;func_runner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;even_till&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;func_runner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;odd_till&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;func_runner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;odd_till 5 currently: 1
even_till 4 currently: 0
odd_till 6 currently: 1
odd_till 5 currently: 3
even_till 4 currently: 2
odd_till 6 currently: 3
odd_till 6 currently: 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we rename the same thing we get a mini task scheduler [4]&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&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;deque&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TaskScheduler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__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="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deque&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_task&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;task&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;_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&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="k"&gt;while&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;_queue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&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;_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;popleft&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&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;_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;StopIteration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;usage&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TaskScheduler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;odd_till&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;even_till&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;odd_till&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just a point of note, why do we remove a task (popleft) and readd it (append)?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;      &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&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;_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;popleft&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&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;_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;StopIteration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's because if it was finished (exception raised) well and good, it will go straight to the except block. Else the .append will get executed. &lt;/p&gt;

&lt;p&gt;In other words if task terminated, don't add it back else add it back. &lt;/p&gt;

&lt;h3&gt;
  
  
  The send method
&lt;/h3&gt;

&lt;p&gt;Generators support a way of sending values to generators&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;times2&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;times2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&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 class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2
4
6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was an important addition. This passage explains why was send introduced and why it's important in asyncio [6]:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Python's generator functions are almost coroutines -- but not quite -- in that they allow pausing execution to produce a value, but do not provide for values or exceptions to be passed in when execution resumes ... However, if it were possible to pass values or exceptions into a generator at the point where it was suspended, a simple co-routine scheduler or trampoline function would let coroutines call each other without blocking -- a tremendous boon for asynchronous applications. Such applications could then write co-routines to do non-blocking socket I/O by yielding control to an I/O scheduler until data has been sent or becomes available. Meanwhile, code that performs the I/O would simply do something like this: &lt;code&gt;data = (yield nonblocking_read(my_socket, nbytes))&lt;/code&gt; in order to pause execution until the &lt;code&gt;nonblocking_read()&lt;/code&gt; coroutine produced a value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;yield was fundamentally changed with the addition of send. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;Redefine yield to be an expression, rather than a statement. The current yield statement would become a yield expression whose value is thrown away. A yield expression's value is None whenever the generator is resumed by a normal next() call.&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;Add a new send() method for generator-iterators, which resumes the generator and sends a value that becomes the result of the current yield-expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value.&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;send(None) can also be used instead of the first next()&lt;/p&gt;

&lt;h3&gt;
  
  
  Deriving send
&lt;/h3&gt;

&lt;p&gt;How do we derive send? A tricky question indeed. Here's a mini snippet showing how [4]&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&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;deque&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ActorScheduler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__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="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_actors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# Mapping of names to actors
&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;_msg_queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deque&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# Message queue
&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;new_actor&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 class="n"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;'''
    Admit a newly started actor to the scheduler and give it a name
    '''&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;_msg_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="bp"&gt;None&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;_actors&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 class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;actor&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send&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 class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;'''
    Send a message to a named actor
    '''&lt;/span&gt;
    &lt;span class="n"&gt;actor&lt;/span&gt; &lt;span class="o"&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;_actors&lt;/span&gt;&lt;span class="p"&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;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;actor&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;_msg_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&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="s"&gt;'''
    Run as long as there are pending messages.
    '''&lt;/span&gt;
    &lt;span class="k"&gt;while&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;_msg_queue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&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;_msg_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;popleft&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;StopIteration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# Example use
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'__main__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;printer&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt;
      &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Got:'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sched&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Receive the current count
&lt;/span&gt;      &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
      &lt;span class="c1"&gt;# Send to the printer task
&lt;/span&gt;      &lt;span class="n"&gt;sched&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'printer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# Send the next count to the counter task (recursive)
&lt;/span&gt;      &lt;span class="n"&gt;sched&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'counter'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&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 class="n"&gt;sched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ActorScheduler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;# Create the initial actors
&lt;/span&gt;  &lt;span class="n"&gt;sched&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new_actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'printer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;printer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="n"&gt;sched&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new_actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'counter'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sched&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="c1"&gt;# Send an initial message to the counter to initiate
&lt;/span&gt;  &lt;span class="n"&gt;sched&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'counter'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;sched&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above can be expanded with more areas like ready, ready to read, ready to write and writing the appropriate code to switch between the areas and ... you have a concurrent app. This is the basics of an operating system [4]. Using &lt;code&gt;sched.send&lt;/code&gt; allows to have a loop beyond the recursion limit of python. The recursion limit is &lt;code&gt;import sys; sys.getrecursionlimit()&lt;/code&gt; usually 1000. try &lt;code&gt;sched.send('counter', 1001)&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  What is yield from?
&lt;/h3&gt;

&lt;p&gt;Consider the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gen_alph&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="s"&gt;'abc'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gen_nums&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="s"&gt;'123'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gen_data&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;gen_alph&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;gen_nums&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;gen_data&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a
b
c
1
2
3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It behaves exactly as if the alphabet and number loops with their respective yields was inside gen_data.&lt;/p&gt;

&lt;p&gt;"yield from is to generators as calls are to functions" as Brett Cannon puts it [8]&lt;/p&gt;

&lt;h3&gt;
  
  
  The last part
&lt;/h3&gt;

&lt;p&gt;Generators have a close method, caught by a GeneratorExit exception:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gen_alph&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="s"&gt;'abc'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;GeneratorExit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Generator exited'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gen_alph&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generator exited
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They also have a throw method to catch errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gen_alph&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="s"&gt;'abc'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;GeneratorExit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Generator exited'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="s"&gt;'error occured'&lt;/span&gt;

&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gen_alph&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error occured
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The limit of generators: Infinity and Beyond
&lt;/h3&gt;

&lt;p&gt;If you really want the best of Python generators the internet can give you&lt;br&gt;
copied over and over by Python sites, see David Beazley's 3 parts series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.dabeaz.com/generators"&gt;Generator Tricks for Systems Programmers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.dabeaz.com/coroutines/"&gt;A Curious Course on Coroutines and Concurrency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.dabeaz.com/finalgenerator/"&gt;Generators: The Final Frontier&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also includes lots of use cases.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Abdur-Rahmaan Janhangeer is an organising member of the &lt;a href="https://www.pymug.com"&gt;Python Mauritius User Group&lt;/a&gt; (PyMUG), &lt;a href="https://www.flaskcon.com"&gt;FlaskCon&lt;/a&gt; and maintains &lt;a href="https://www.pythonkitchen.com"&gt;pythonkitchen.com&lt;/a&gt;. The present article is the continuation of his talk about deriving asyncio&lt;/em&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;[1] &lt;a href="https://www.python.org/dev/peps/pep-0255/"&gt;https://www.python.org/dev/peps/pep-0255/&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://www.python.org/dev/peps/pep-0289/"&gt;https://www.python.org/dev/peps/pep-0289/&lt;/a&gt;&lt;br&gt;
[3] &lt;a href="https://dev.to/abdurrahmaanj/add-superpowers-to-your-python-lists-using-this-feature-24nf"&gt;https://dev.to/abdurrahmaanj/add-superpowers-to-your-python-lists-using-this-feature-24nf&lt;/a&gt;&lt;br&gt;
[4] Python Cookbook, David Beazley&lt;br&gt;
[5] &lt;a href="https://docs.python.org/3/library/asyncio-task.html"&gt;https://docs.python.org/3/library/asyncio-task.html&lt;/a&gt;&lt;br&gt;
[6] &lt;a href="https://www.python.org/dev/peps/pep-0342/"&gt;https://www.python.org/dev/peps/pep-0342/&lt;/a&gt;&lt;br&gt;
[7] &lt;a href="https://wiki.python.org/moin/Generators"&gt;https://wiki.python.org/moin/Generators&lt;/a&gt;&lt;br&gt;
[8] Brett Cannon: Python 3.3: Trust Me, It's Better Than Python 2.7&lt;/p&gt;

</description>
      <category>python</category>
      <category>generators</category>
      <category>asyncio</category>
    </item>
    <item>
      <title>How to run Linux-only Python projects on windows using git mingw bash</title>
      <dc:creator>Abdur-Rahmaan Janhangeer</dc:creator>
      <pubDate>Mon, 07 Dec 2020 16:22:07 +0000</pubDate>
      <link>https://dev.to/abdurrahmaanj/how-to-run-linux-only-python-projects-using-git-mingw-bash-lml</link>
      <guid>https://dev.to/abdurrahmaanj/how-to-run-linux-only-python-projects-using-git-mingw-bash-lml</guid>
      <description>&lt;p&gt;Linux owners configure makefiles so as to have easy commands to perform operations such as &lt;code&gt;make dependencies&lt;/code&gt; to pip install required packages. Here are the dry simple steps to run makefiles in Python projects on Windows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Download &lt;a href="https://git-scm.com/download/win"&gt;git for windows&lt;/a&gt;. You should get git bash, git gui etc&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the &lt;a href="https://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe/download"&gt;mingw GUI setup&lt;/a&gt;. Install it wherever you want. After running the setup you should get a screen like that:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vF3g6NRH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r7o80ec3wph22ivqlsk1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vF3g6NRH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r7o80ec3wph22ivqlsk1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On continuing you should get under &lt;strong&gt;all packages&lt;/strong&gt;. Search for make, class bin. Right click and select mark for installation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Owkuef6s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9v92axko7a6vx5n8ydrv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Owkuef6s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9v92axko7a6vx5n8ydrv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Under installation, select apply changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JT_1DWcP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kxxwyym1bcwtijexqroj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JT_1DWcP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kxxwyym1bcwtijexqroj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm by clicking on apply&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9LSmMS8q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/205z5xab16k2x8gkdt54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9LSmMS8q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/205z5xab16k2x8gkdt54.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;My git for windows' migw is installed at &lt;code&gt;C:\Program Files\Git\mingw32&lt;/code&gt; and my mingw get is installed at &lt;code&gt;C:\MinGW&lt;/code&gt;. We need to merge the contents on the mingw32 folder with the MinGW. Ctrl+a to select all folder in MinGW then right click and copy. Then go to mingw32 folder and click paste. When asking is merge, say yes. If same files skip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify if there is &lt;code&gt;venv/&lt;/code&gt; in project gitignore. If not add it and reapply gitignore by using the following command &lt;a href="https://stackoverflow.com/questions/19663093/apply-gitignore-on-an-existing-repository-already-tracking-large-number-of-file"&gt;(see accepted answer)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create a new virtual environent.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;activate the env
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;venv
&lt;span class="nb"&gt;cd &lt;/span&gt;scripts
&lt;span class="nb"&gt;.&lt;/span&gt; activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;note the space between . and activate&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cd back &lt;code&gt;cd ../..&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;now try out any command listed &lt;a href="https://github.com/pandas-dev/pandas-blog"&gt;here&lt;/a&gt; for example &lt;code&gt;make dependencies&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Forgot to say under bin rename &lt;code&gt;mingw-get.exe&lt;/code&gt; to &lt;code&gt;make.exe&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Anything mail me &lt;code&gt;arj.python at gmail dot com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is something crazily powerful!&lt;/p&gt;

&lt;p&gt;You might want to see the other hacky way:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/abdurrahmaanj/how-to-run-a-flask-linux-only-app-on-windows-1418"&gt;How to run a Flask Linux-only app on windows&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>linux</category>
      <category>mingw</category>
      <category>bash</category>
    </item>
  </channel>
</rss>
