<?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: Antonio Morrone</title>
    <description>The latest articles on DEV Community by Antonio Morrone (@antomor).</description>
    <link>https://dev.to/antomor</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%2F278618%2F4930e3e7-b93d-426c-9ba2-2cbce8093738.jpeg</url>
      <title>DEV Community: Antonio Morrone</title>
      <link>https://dev.to/antomor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/antomor"/>
    <language>en</language>
    <item>
      <title>Iterators &amp; Generators in Python</title>
      <dc:creator>Antonio Morrone</dc:creator>
      <pubDate>Sun, 27 Dec 2020 15:54:22 +0000</pubDate>
      <link>https://dev.to/antomor/iterators-generators-in-python-1i1h</link>
      <guid>https://dev.to/antomor/iterators-generators-in-python-1i1h</guid>
      <description>&lt;p&gt;This post aims to describe the basic mechanisms behind iterators and generators.&lt;/p&gt;

&lt;h2&gt;
  
  
  Iterator protocol
&lt;/h2&gt;

&lt;p&gt;As in many programming languages, Python allows to iterate over a collection. The iteration mechanism is often useful when we need to scan a sequence, operation that is very common in programming.&lt;br&gt;
In Python the iterator protocol involves two components: an &lt;em&gt;iterable&lt;/em&gt; and an &lt;em&gt;iterator&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Iterable
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;iterable&lt;/em&gt; is the container through which we want to iterate. It is the object that needs to be scanned to retrieve all the elements (or some of them). Some of well-known iterables are lists, tuples, dictionaries, ranges. In the &lt;em&gt;iterator protocol&lt;/em&gt; the &lt;em&gt;iterable&lt;/em&gt; exposes a &lt;strong&gt;&lt;strong&gt;iter&lt;/strong&gt;&lt;/strong&gt; method that returns an &lt;em&gt;iterator&lt;/em&gt; object.&lt;/p&gt;
&lt;h2&gt;
  
  
  Iterator
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;iterator&lt;/em&gt; is the data structure that allows the scan through the container. It could seem a complication, but actually, with the separation of concerns, it lets the developer separate the concept of container, from the concept of iteration. The container object doesn't need to keep the state of an iteration and furthermore, on the same object, many iterations at the same time can take place, so keeping the iteration state in a different object is a must. The container is a collection of elements, while the iterator is kind of an handler of the container, it exposes the same elements (owned by the container) one-by-one with a specific order and . In the &lt;em&gt;iterator protocol&lt;/em&gt;, the &lt;em&gt;iterator&lt;/em&gt; exposes two methods:  &lt;strong&gt;&lt;strong&gt;iter&lt;/strong&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;strong&gt;next&lt;/strong&gt;&lt;/strong&gt;. While the first one return the object itself (it allows the usage of both container and iterator in &lt;em&gt;for&lt;/em&gt; and &lt;em&gt;in&lt;/em&gt; statements), the latter return the next item from the container. What does it make the iterator end the iteration? The &lt;strong&gt;StopIteration&lt;/strong&gt; exception.&lt;/p&gt;
&lt;h2&gt;
  
  
  Iterable and Iterator Examples
&lt;/h2&gt;

&lt;p&gt;Below an example of iterator protocol implementation:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And its usage:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Generator
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Generators&lt;/em&gt; are methods with yield statements. The &lt;em&gt;yield&lt;/em&gt; statement has the power to suspend the function execution and store its state, so that it can be resumed. Behind the scenes, python returns the control to the function caller and save the function state; in this way, at the next execution, the function will start where it left, without letting the developer worrying about the state of the function. &lt;em&gt;Generators&lt;/em&gt; ARE &lt;em&gt;iterators&lt;/em&gt;, but not vice-versa.&lt;/p&gt;

&lt;p&gt;Here an example of generator:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;and its usage:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Async generator
&lt;/h3&gt;

&lt;p&gt;Like &lt;em&gt;generators&lt;/em&gt; they are &lt;strong&gt;async&lt;/strong&gt; function with a &lt;em&gt;yield&lt;/em&gt; statement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Iterators are iterables.&lt;/li&gt;
&lt;li&gt;Iterators are objects that implement the &lt;code&gt;iterator protocol&lt;/code&gt; consisting in implementing both &lt;code&gt;__iter__&lt;/code&gt; and &lt;code&gt;__next__&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Iterator iterations stop when &lt;code&gt;StopIteration&lt;/code&gt; is raised.&lt;/li&gt;
&lt;li&gt;Generators are methods with yield statements.&lt;/li&gt;
&lt;li&gt;Async generators are async methods with yield statements.&lt;/li&gt;
&lt;li&gt;Whenever possible, generator must be the preferred method due to its simplicity, while the protocol implementation gives much more control.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3.7/library/stdtypes.html#iterator-types"&gt;Iterator types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3.7/library/stdtypes.html#generator-types"&gt;Generator types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3.7/reference/expressions.html#yieldexpr"&gt;Yield expression&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/2776829/difference-between-pythons-generators-and-iterators"&gt;Generators and iterators&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>iterator</category>
      <category>generator</category>
    </item>
    <item>
      <title>Mongodb Query Profiler</title>
      <dc:creator>Antonio Morrone</dc:creator>
      <pubDate>Sat, 10 Oct 2020 16:16:18 +0000</pubDate>
      <link>https://dev.to/antomor/mongodb-query-profiler-4kf9</link>
      <guid>https://dev.to/antomor/mongodb-query-profiler-4kf9</guid>
      <description>&lt;p&gt;Some months ago, I was creating a web page to show some aggregated data, but I soon noticed the API used to retrieve the data was very slow. After investigating on the possible issue, we discovered the bottleneck: the database. The solution was to re-structure the data to make it consumable from a web page.&lt;/p&gt;

&lt;p&gt;Although I had used sometimes the SQLServer profiler, I had no experience about MongoDB profiler, so here below the steps involved to analyse a MongoDB query.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It doesn't apply to our case, but in many situations performance problems are related to missing or wrongly implemented &lt;a href="https://docs.mongodb.com/manual/indexes/"&gt;MongoDB Indexes&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Enable MongoDB profiler
&lt;/h2&gt;

&lt;p&gt;By default, MongoDB doesn't profile any query. It is possible to set the profiling level executing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setProfilingLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;profile_level&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;profile_level&lt;/code&gt; can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0&lt;/code&gt; - the profiler is off, so it doesn't collect any data.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; - the profiler collects data only if the operation takes more than &lt;code&gt;slowms&lt;/code&gt; (a configurable threshold).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2&lt;/code&gt; - the profiler collects data for all operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;IMPORTANT: At the end of the analysis, please remember to disable profiling with: &lt;code&gt;db.setProfilingLevel(0)&lt;/code&gt;, since that it can affect MongoDB performance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Retrieve last query profile
&lt;/h2&gt;

&lt;p&gt;Once profiling is enabled, it is possible to retrieve last query &lt;strong&gt;profiled&lt;/strong&gt; (meaning that the query must be executed after setting the profiling level) with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;limit&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="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;pretty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Explain
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://docs.mongodb.com/manual/reference/command/explain/#dbcmd.explain"&gt;explain command&lt;/a&gt; comes in handy, since that it provides information on many common operations such as &lt;code&gt;aggregate&lt;/code&gt;, &lt;code&gt;count&lt;/code&gt;, &lt;code&gt;distinct&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;findAndModify&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt;. Nevertheless a method with the same name, is available on &lt;code&gt;collection&lt;/code&gt; and &lt;code&gt;cursor&lt;/code&gt; also.&lt;/p&gt;

&lt;p&gt;So if we want to analyse the information associated with an &lt;code&gt;aggregate&lt;/code&gt; operation we can execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;collection_name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;explain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;verbosity&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;collection_name&amp;gt;&lt;/code&gt; is the name of the collection on which the aggregation is performed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;verbosity&amp;gt;&lt;/code&gt; is the level of verbosity we want to extract.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Explain verbosity
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;explain&lt;/code&gt; command accepts one of the following verbosity levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;queryPlanner&lt;/code&gt; - It returns the &lt;a href="https://docs.mongodb.com/manual/reference/explain-results/#explain.queryPlanner"&gt;queryPlanner&lt;/a&gt; information about the winning plan evaluation.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;executionStats&lt;/code&gt; - It returns &lt;a href="https://docs.mongodb.com/manual/reference/explain-results/#explain.queryPlanner"&gt;queryPlanner&lt;/a&gt; and the &lt;a href="https://docs.mongodb.com/manual/reference/explain-results/#explain.executionStats"&gt;executionStats&lt;/a&gt; information, but rejected plans are not included in the latter.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allPlansExecution&lt;/code&gt; - It returns &lt;a href="https://docs.mongodb.com/manual/reference/explain-results/#explain.queryPlanner"&gt;queryPlanner&lt;/a&gt; and the &lt;a href="https://docs.mongodb.com/manual/reference/explain-results/#explain.executionStats"&gt;executionStats&lt;/a&gt; information about all the evaluated plans (including also rejected plans).&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Only by understanding how the query was executed by MongoDB, we were able to improve its performance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Not our case, but I would remind that performance problems are often associated to missing or wrongly implemented indexes. If so, please have a look at &lt;a href="https://docs.mongodb.com/manual/indexes/"&gt;MongoDB Indexes&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.mongodb.com/manual/tutorial/manage-the-database-profiler/"&gt;MongoDB database profiler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.mongodb.com/manual/reference/explain-results/"&gt;Explain results&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.mongodb.com/manual/indexes/"&gt;MongoDB Indexes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mongodb</category>
      <category>database</category>
    </item>
    <item>
      <title>Browser Extension Development</title>
      <dc:creator>Antonio Morrone</dc:creator>
      <pubDate>Sat, 10 Oct 2020 16:07:09 +0000</pubDate>
      <link>https://dev.to/antomor/browser-extension-development-45oc</link>
      <guid>https://dev.to/antomor/browser-extension-development-45oc</guid>
      <description>&lt;p&gt;Web extensions or browser plugins can be used to improve browser functionalities. The following examples summarize the different goals they can have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://noscript.net/"&gt;no-script&lt;/a&gt; - to block script served from not-trusted domains&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/gorhill/uBlock#ublock-origin"&gt;ublock Origin&lt;/a&gt; - it is "a wide-spectrum blocker"&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://addons.mozilla.org/it/firefox/addon/dark-mode-zen/"&gt;dark-mode&lt;/a&gt; - it changes the appearance of web pages&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://addons.mozilla.org/it/firefox/addon/react-devtools/"&gt;React Developer Tools&lt;/a&gt; - to inspect react-specific properties of a page that makes use of React.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Anatomy of an extension
&lt;/h2&gt;

&lt;p&gt;The main components of a browser extension are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manifest.json - it is the only mandatory file and it describes the extension itself. It is as an entry-point for the browser to declare what are the files/resources/permissions will be used.&lt;/li&gt;
&lt;li&gt;Background scripts - They contain the logic that are not strictly related to the single web-page. They are loaded when the extension is loaded and remain active until the extension is disabled or uninstalled.&lt;/li&gt;
&lt;li&gt;Content scripts - Unlike background scripts, they are loaded into web pages, so they can manipulates DOM exactly like normal script can do.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;UI components - They includes all the parts that permit a user to interact with the extension, by means of an HTML document. There are three different UI components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars"&gt;sidebar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups"&gt;popup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Options_pages"&gt;options page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Web-accessible resources -  They include all the resources that are made available to the scripts (e.g. HTML, images, jss, css)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extension pages - They are additional pages used to handle specific user interactions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Web-extension toolbox
&lt;/h2&gt;

&lt;p&gt;As for many browser APIs, also the web extension APIs can behave differently according with the browser on which they are executed. In case of cross-browser development it could be handful &lt;a href="https://github.com/mozilla/webextension-polyfill/"&gt;web-extension polyfill&lt;/a&gt; developed by Mozilla.&lt;/p&gt;

&lt;p&gt;Furthermore, to ease the development process, there is also &lt;a href="https://github.com/webextension-toolbox/webextension-toolbox"&gt;web-extension toolbox&lt;/a&gt; and its related &lt;a href="https://github.com/webextension-toolbox/generator-web-extension"&gt;yeoman generator&lt;/a&gt;. Among the others it provides the following functionalities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compiles the extension via webpack to &lt;code&gt;dist/&amp;lt;vendor&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Watches all extension files and re-compiles on demand&lt;/li&gt;
&lt;li&gt;Reloads extension or extension page as soon something changed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After answering to some questions, it generates a ready-to-run web extension.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development
&lt;/h2&gt;

&lt;p&gt;You only need to run &lt;code&gt;npm run dev &amp;lt;vendor_name&amp;gt;&lt;/code&gt;, where  can be &lt;code&gt;chrome&lt;/code&gt;, &lt;code&gt;firefox&lt;/code&gt;, &lt;code&gt;opera&lt;/code&gt; or &lt;code&gt;edge&lt;/code&gt;; now you can load the generated extension in the browser of choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build
&lt;/h2&gt;

&lt;p&gt;As easy as running &lt;code&gt;npm run build &amp;lt;vendor_name&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;So, what are you waiting for? Are you ready to develop your own browser plugin? I am planning mine ;-)&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions"&gt;MDN Browser Extensions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webextension-toolbox/webextension-toolbox"&gt;webextension-toolbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mozilla/web-ext"&gt;Mozilla web-ext&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>webextension</category>
    </item>
  </channel>
</rss>
