<?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: idoazzz</title>
    <description>The latest articles on DEV Community by idoazzz (@idoazzz).</description>
    <link>https://dev.to/idoazzz</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%2F232633%2Fe5a124e8-41e2-497d-8552-90cc2e100757.png</url>
      <title>DEV Community: idoazzz</title>
      <link>https://dev.to/idoazzz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/idoazzz"/>
    <language>en</language>
    <item>
      <title>Python's Type Annotations: The Best Of Both Types Worlds</title>
      <dc:creator>idoazzz</dc:creator>
      <pubDate>Sat, 16 Oct 2021 09:24:46 +0000</pubDate>
      <link>https://dev.to/idoazzz/pythons-type-annotations-the-best-of-both-types-worlds-52li</link>
      <guid>https://dev.to/idoazzz/pythons-type-annotations-the-best-of-both-types-worlds-52li</guid>
      <description>&lt;h1&gt;
  
  
  With Great Power Comes Great Responsibility
&lt;/h1&gt;

&lt;p&gt;Python is a pretty powerful language with a lot of controversial features. One of them is Typing System, I'm one of the groupies so today my mission will be to convince you it's at least not bad as people claim. &lt;br&gt;
Today, we'll talk about type systems and where Python fits in.&lt;br&gt;
Also, you'll see a way to reduce unwanted bugs and boost your codebase with the Type Annotations feature that was introduced in Python 3.5 (&lt;a href="https://www.python.org/dev/peps/pep-0484" rel="noopener noreferrer"&gt;PEP484&lt;/a&gt;). &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PEP stands for Python Enhancement Proposals, all proposals and specifications of Python's features. It's like &lt;a href="https://github.com/tc39/proposals" rel="noopener noreferrer"&gt;ECMA&lt;/a&gt;'s documents for Javascript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This feature truly makes Python a better dynamic-typed language.&lt;br&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Less Runtime Errors = Efficiency
&lt;/h3&gt;

&lt;p&gt;How many times have you met the following error:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AttributeError: 'X' object has no attribute 'Y'&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;This is one of the most annoying and time-wasting bugs that Python introduce. There are more errors that occur because of non-safety with variable types and non-existing type validations (or tests in general).&lt;br&gt;
As a dynamic-typed language, all the type errors will appear in runtime.&lt;br&gt;&lt;br&gt;
Try to recall how frustrating it meeting this type of exception in production. &lt;br&gt;
For those of you who know Javascript, you can see the huge hype over Typescript in the last few years. Why is that? Fewer bugs! &lt;br&gt;
Nowadays people understand that bugs in production are way worst from adding types in their code.&lt;/p&gt;

&lt;p&gt;But wait, let's go back and explain the fundamentals about type systems, and why I say stuff. &lt;/p&gt;


&lt;h2&gt;
  
  
  Type Systems and Airport Security
&lt;/h2&gt;

&lt;p&gt;You arrived at the airport for taking your flight to the annual vacation.&lt;br&gt;
In the entry of the airport a security guard approaches to you and ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Big Security Guy: "Let's say you have a choice between 2 options.&lt;br&gt;
(1) Passing a security check which includes long lines and cursings. &lt;br&gt;(2) you go freely into your airplane and during the flight, you'll be checked. &lt;br&gt; What would you prefer?" &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This story looks exactly like the war between dynamic and static languages. &lt;/p&gt;


&lt;h3&gt;
  
  
  Static-Typed Languages
&lt;/h3&gt;

&lt;p&gt;Your code types will be checked in the compilation process.&lt;br&gt;
Those types of languages main pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Types Safety&lt;/strong&gt; Detecting programming mistakes and redundant bugs before runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt; Better documentation for the code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you know about a bomb in your airport, you rather choose this choice (1).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;e.g: Java, C, C++&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Dynamic-Typed Languages
&lt;/h3&gt;

&lt;p&gt;Your code types will be checked only during runtime. &lt;br&gt;
Those types of languages main pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Readable&lt;/strong&gt; Tend to be more readable and natural. Living without repeated types everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt; Development flexibility with dealing with unpredictability systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instantaneous&lt;/strong&gt; Fast development cycles because of the instant launching of your code (lack of validation, even 10 seconds validation will accumulate enormous frustration).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem will be when there is a bomb on your flight.&lt;br&gt;
For more safe flight (/run) your codebase must have tests and validations that will prevent issues in runtime. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;e.g: Python, Javascript, R, Julia&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python's Place&lt;/strong&gt;&lt;br&gt;
Python is a pure dynamic-typed language.&lt;br&gt;
Our goal will be to improve the downsides of dynamic-typed languages.&lt;/p&gt;


&lt;h2&gt;
  
  
  Main Problem: More Tests
&lt;/h2&gt;

&lt;p&gt;We can agree that both types of languages codebases should have tests, but we live in an imperfect world, we don't have always the time to perform that tests, especially in large codebases in which high coverage is hard to target.&lt;br&gt;
Dynamic languages, as we said, are less safe in their essence.&lt;br&gt;
There are many cases that types are difficult to track. A common example is that it very hard tracking types of arguments in deep nested function calls. &lt;br&gt;
So to revealing the bugs that occur because of programmer's mistakes, tests should be written.&lt;br&gt;
&lt;br&gt; How can we increase our safety without making any efforts and spending more time?&lt;/p&gt;


&lt;h1&gt;
  
  
  Type Annotations
&lt;/h1&gt;
&lt;h2&gt;
  
  
  The Best Of Both Types Worlds
&lt;/h2&gt;

&lt;p&gt;Type Annotations are simply type-hints that can be attached to variables and functions declarations. &lt;br&gt;
They can be used by third-party tools such as type checkers, IDEs, and linters for real-time warnings while coding.&lt;br&gt;&lt;br&gt;
The Python runtime does not enforce function and variable type annotations, so we didn't actually make Python more static. &lt;br&gt;
Also, Python's interpreter will relate the Type Annotations as comments, so no effect on runtime. &lt;br&gt;
&lt;strong&gt;We got statically-typed language experience with the dynamic-typed language.&lt;/strong&gt; &lt;br&gt;&lt;/p&gt;

&lt;p&gt;Let's introduce some central features of Type Annotations.&lt;/p&gt;
&lt;h3&gt;
  
  
  Availiable Types
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Builtin Types&lt;/strong&gt;&lt;br&gt;
It is possible hinting each one of the builtin types: &lt;code&gt;int, str, float, bool, bytes, object, None&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Special Types&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Notice that in Python3.9+ most of the following types are changed and won't be imported anymore from &lt;code&gt;typing&lt;/code&gt; module anymore, e.g, List -&amp;gt; list.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;Any&lt;/code&gt; Any type is possible.&lt;br&gt;
&lt;code&gt;List[str]&lt;/code&gt; List of str objects.&lt;br&gt;
&lt;code&gt;Tuple[int, int]&lt;/code&gt; Tuple of two ints.&lt;br&gt;
&lt;code&gt;Tuple[int, ...]&lt;/code&gt; Tuple of int objects.&lt;br&gt;
&lt;code&gt;Dict[int, int]&lt;/code&gt; Dict with int keys to int values.&lt;br&gt;
&lt;code&gt;Iterable[int]&lt;/code&gt; Iterable which contains int objects.&lt;br&gt;
&lt;code&gt;Sequence[bool]&lt;/code&gt; Sequence of booleans.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;By the way: Sequence is an Iterable with defined length and extra functionality.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Basic Example
&lt;/h3&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;greeting&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;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&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;Hello &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If we will run the following code &lt;code&gt;greeting(3)&lt;/code&gt; we will get the following error:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;error: Argument 1 to "greeting" has incompatible type "int"; expected "str"&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Type Aliases
&lt;/h3&gt;

&lt;p&gt;It is possible to define aliases to types for more readable 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="n"&gt;Url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;retry_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&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;h3&gt;
  
  
  Generics
&lt;/h3&gt;

&lt;p&gt;TypeVar is a factory that can generate parameterized types. It can be very useful in classes that can hold different data types.&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;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypeVar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Generic&lt;/span&gt;

&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TypeVar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;T&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Generic&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&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;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Create an empty list with items of type T
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;push&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="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&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="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&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;pop&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;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;T&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&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;empty&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;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;

&lt;span class="c1"&gt;# Construct an empty Stack[int] instance
&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt;
&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="c1"&gt;# Type error
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is possible to create an object without specifying the type, the first object that will be inserted into the data structure will determine the class parameterized type (type inferring).&lt;/p&gt;

&lt;h3&gt;
  
  
  Flexibility
&lt;/h3&gt;

&lt;p&gt;Sometimes you will accept several types for your variable.  &lt;br&gt;&lt;br&gt;
&lt;strong&gt;Union&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;Union[T1,...,Tn]&lt;/code&gt;&lt;br&gt;
Specifying a set of possible types, each one of them will be accepted.&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;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&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;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;      &lt;span class="c1"&gt;# OK
&lt;/span&gt;    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;    &lt;span class="c1"&gt;# OK
&lt;/span&gt;
&lt;span class="nf"&gt;f&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="c1"&gt;# OK
&lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# OK
&lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Error
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Optional&lt;/strong&gt;&lt;br&gt;
 &lt;code&gt;Optional[T]&lt;/code&gt;&lt;br&gt;
Optional will indicates the variable holds a specified type or &lt;code&gt;None&lt;/code&gt;.&lt;br&gt;
It actually equals to &lt;code&gt;Union[T, None]&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;s&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;None&lt;/span&gt;  &lt;span class="c1"&gt;# OK
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For &lt;strong&gt;many&lt;/strong&gt; usefull annotations I recommend exploring &lt;a href="https://mypy.readthedocs.io/en/stable/kinds_of_types.html?highlight=Union#" rel="noopener noreferrer"&gt;mypy&lt;/a&gt;  docs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Using Type Annotations?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  IDE - Enforcing Like Compiler
&lt;/h3&gt;

&lt;p&gt;Better than a compiler. You got your potential errors while developing! &lt;/p&gt;

&lt;p&gt;Here few examples from Pycharm docs to understanding how awesome this thing is.&lt;br&gt;
In the next example, we can see that we perform an invalid assignment. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634070462071%2F5e1bZKtYA.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634070462071%2F5e1bZKtYA.png" alt="py_type_hint_validate_assignment_expressions.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we use the &lt;code&gt;Final&lt;/code&gt; type to mark a variable as a constant. Assignment to this constant will lead to an error.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634070541803%2F_GsIsMNvt.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634070541803%2F_GsIsMNvt.png" alt="py_type_hint_validate_final_variable.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here the IDE enforces Enum values for preventing any programmer mistakes, unified format.&lt;br&gt;
&lt;code&gt;Literal&lt;/code&gt; type makes it possible to supply specific primitive values for the variable.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634070606514%2F025q3nWA7.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634070606514%2F025q3nWA7.png" alt="py_type_hinting_literals.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we use TypedDict as a schema for function argument.&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634070642927%2F-J0vfPmmA.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634070642927%2F-J0vfPmmA.png" alt="py_type_hint_typed_dict.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Those examples are a drop in the ocean, I hope it's clear now how the IDE enforces bugs and acting as a real-time compiler enforcer.&lt;/p&gt;
&lt;h3&gt;
  
  
  Refactoring Better
&lt;/h3&gt;

&lt;p&gt;From my experience, refactoring with type validations can save a lot of time and unwanted bugs in production.&lt;br&gt;
During refactoring, you usually change parts of code that can affect many other places. As we said, for catching unwanted errors in many places we need good tests coverage, without it, there is a good potential for programmer mistakes that won't be detected.&lt;br&gt;
So, if your coverage is not good as you think, type annotations will help. &lt;/p&gt;
&lt;h3&gt;
  
  
  Type Annotations as Documentation
&lt;/h3&gt;

&lt;p&gt;Docstrings are usually the solution for documentation in Python, there are many different formats such as Epytext, reST, Google (my favorite), and more.&lt;br&gt;
There is no one standard strict format for docstrings, so it can be pretty difficult to enforce and check type problems in the codebase.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Docstrings for humans, Type Annotations for linters. *&lt;/em&gt; &lt;br&gt;
For reaching maximal experience of documentation, use type hints for enforcing any errors, and document only the non-trivial stuff. &lt;/p&gt;
&lt;h3&gt;
  
  
  Improve IDE Suggestions
&lt;/h3&gt;

&lt;p&gt;As we know, sometimes our IDEs are pretty annoying. especially when you have &lt;code&gt;int&lt;/code&gt; variable and &lt;code&gt;string&lt;/code&gt; suggestions are made. &lt;br&gt;
Type Annotations make suggestions feature more accurate and easier. Typing your variable with a specific type will autocomplete you with these specific type suggestions.&lt;/p&gt;
&lt;h3&gt;
  
  
  New Awesome Tools
&lt;/h3&gt;

&lt;p&gt;Type Annotations are not only a way of enforcing types in your code. Like every feature in Python, it is possible to access the annotations of specific code.&lt;br&gt;
PEP3107 (Function Annotations) specify how can we retrieve metadata from our code, using Type Annotations with &lt;code&gt;__annotations__&lt;/code&gt; property.&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;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&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;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;max&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="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__annotations__&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;c&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;return&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why is it good?&lt;/strong&gt; &lt;br&gt;
There are several powerful usages for this feature, a few of them are Database query mapping, Foreign-language bridges, RPC parameters encoding, and Schemas validations.&lt;br&gt;
A really good example of this feature usage is FastAPI.&lt;br&gt;
&lt;a href="https://fastapi.tiangolo.com/" rel="noopener noreferrer"&gt;FastAPI&lt;/a&gt; is a fast and modern web framework based on Python Type Annotations. Why is that? Why shouldn't we use Flask and Django and forget about those types? &lt;strong&gt;Value&lt;/strong&gt;.&lt;br&gt;
Additionally, to speed, FastAPI gives few powerful features based on type hints, for example: &lt;br&gt; &lt;br&gt;
&lt;strong&gt;OpenAPI Generation&lt;/strong&gt;&lt;br&gt;
Whenever you run your server an OpenAPI (Swagger) specification file will be generated automatically, you don't have to document your endpoints anymore! &lt;br&gt; &lt;br&gt;
&lt;strong&gt;Schemas and Data Models&lt;/strong&gt;&lt;br&gt;
Another one is data models, Using the module Pydantic, with the simple specifications of your REST requests and arguments, validation and conversion will be performed so you can hold your objects without messing around with Jsons.&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;class&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&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;str&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;tax&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;


&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/items/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Item&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;item&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is also a drop in the ocean. As a Backend Engineer who worked with few web frameworks, I can surely say that these features are truly amazing and powerful.&lt;/p&gt;




&lt;h2&gt;
  
  
  MyPy
&lt;/h2&gt;

&lt;p&gt;MyPy is a static type check for Python 2 and 3.&lt;br&gt;
We can treat MyPy as our compiler which does not output any executable, only checks and find our bugs in the input codebase.&lt;br&gt;
MyPy can type check your code and prevent bugs, it acts like a linter that runs as a static analyzer. &lt;br&gt; It is possible to create a configuration file for a more optimized and customized experience. &lt;/p&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.py
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_hi&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;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hi, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  

 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mypy&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&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;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Argument&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;print_hi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;incompatible&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;int&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;str&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;MyPy and IDE that support Type Annotations are a powerful combination.&lt;br&gt;
IDE for real-time warning and MyPy for final checkings (Possible in CI).&lt;/p&gt;


&lt;h1&gt;
  
  
  Few Words About Type Annotation Cons
&lt;/h1&gt;

&lt;p&gt;Recalling: My goal is to convince the haters that those type annotations are not bad as they claim.&lt;br&gt;
Type Annotations like every controversial feature have few drawbacks.&lt;br&gt;&lt;br&gt;
I'll talk about the most popular.&lt;/p&gt;
&lt;h3&gt;
  
  
  Adding Types to Large Codebases Without Any Types Hints
&lt;/h3&gt;

&lt;p&gt;Adapting Type Annotations with the existing codebase is a challenging topic, small repos are not such an issue because adding types will be pretty fast. Large codebases cannot add Type Annotations quickly, it can be challenging.&lt;br&gt;
You can try those two approaches combined for achieving types codebase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are few tools that are meant to solve this issue or at least help. &lt;code&gt;MonkeyType&lt;/code&gt; and &lt;code&gt;PyAnnotate&lt;/code&gt; tools can infer the types of your code &lt;strong&gt;during runtime&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It is recommended to add type hints in a graded manner, pick a subset of your code and run MyPy on this subset. Fix the errors or ignore with &lt;code&gt;# type: ignore&lt;/code&gt; and move on. Subset by subset, Part by part.
There is a big advantage having a big codebase with Type Annotations, refactoring will be easier and bugs can be detected fast.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  It takes more time to write the types during development
&lt;/h3&gt;

&lt;p&gt;Well-documented code will have types and documentation already, so what is the cost of moving the types declaration into type annotation?&lt;br&gt;
If you don't document your code, still, insert a word per variable or method declaration doesn't seem very time-consuming.&lt;/p&gt;
&lt;h3&gt;
  
  
  Reducing Readability
&lt;/h3&gt;

&lt;p&gt;Agree. In the end, it's a matter of taste, I met people that claim that type annotation contributes to the readability of their code.&lt;br&gt;
Like everything it's a cost versus benefits game. In the beginning, it can be uglier than working without any annotation but I really think that after a while you are getting used to it. &lt;br&gt;&lt;/p&gt;


&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;As PEP484 said:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Python will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention.&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;To conclude, type annotation can contribute a lot to your codebases.&lt;br&gt;
Python rules.&lt;/p&gt;

</description>
      <category>python</category>
      <category>fastapi</category>
      <category>webdev</category>
      <category>annotations</category>
    </item>
    <item>
      <title>Become a Better Engineer with Spaced Repetition</title>
      <dc:creator>idoazzz</dc:creator>
      <pubDate>Wed, 22 Sep 2021 10:00:27 +0000</pubDate>
      <link>https://dev.to/idoazzz/become-a-better-engineer-with-spaced-repetition-44da</link>
      <guid>https://dev.to/idoazzz/become-a-better-engineer-with-spaced-repetition-44da</guid>
      <description>&lt;h2&gt;
  
  
  Improving Experience by Improving Memory
&lt;/h2&gt;

&lt;p&gt;A few years ago I thought about what makes a person a good engineer?&lt;br&gt;
Think about it, it's interesting to question. &lt;br&gt;
Your main answer will probably be experience or maybe motivation.&lt;br&gt;
Motivation is an interesting topic, but today I will focus on the experience.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;If a good engineer must have a good experience, how can we boost our experience?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Can we improve the experience?
&lt;/h2&gt;

&lt;p&gt;Think about all the problems/solutions/challenges/subjects/bugs that you faced with in the past, how much of this experience is lost during the years, and more important &lt;strong&gt;how can we save those experiences?&lt;/strong&gt; Insert those experiences into the long-term memory.&lt;br&gt;
&lt;br&gt;Think about an interesting article that you read during the implementation of an arbitrary issue that you had. The chances are that few years from this moment you won't know that this article even exists!&lt;br&gt;
&lt;br&gt;I met an engineer called X (Not the real name) with perfect memory. &lt;br&gt;
Everything he sees hears, and do will be remembered for a long long long time. From my point of view, it's experience worth &lt;strong&gt;a lot&lt;/strong&gt;. &lt;br&gt; He was the best engineer I saw.&lt;br&gt;
 &lt;br&gt; What can make us act like X? &lt;br&gt;&lt;br&gt;
As a person that read a few memory books, I found it very hard using the traditional memory tricks with coding or software subjects.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What doctor will do?
&lt;/h2&gt;

&lt;p&gt;Medicine is my ideal test case! Those doctors must remember their experiences, or someone will die.&lt;br&gt;
So I wondered which technique I can use for improving my experience. &lt;br&gt;&lt;br&gt;
After a while, I found on Youtube a few videos of MD students that use a technique called Spaced Repetition. They use this technique for remembering subjects they studied for a long time. &lt;br&gt;
&lt;br&gt;This method is very simple, They summarize complex subjects with few simple points, and test themselves about those points once a while, depend on how well they remember the subject.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Spaced Repetition
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Spaced repetition is an evidence-based learning technique that is usually performed with flashcards. &lt;br&gt; Newly introduced and more difficult flashcards are shown more frequently, while older and less difficult flashcards are shown less frequently in order to exploit the psychological spacing effect.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Researches showed that everyone has a forgetting curve which means everybody will forget subjects that they read on someday.&lt;/strong&gt;&lt;br&gt;
Using Recalling we can reset the forgetting curve and have those memories for more time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intuitive Example
&lt;/h3&gt;

&lt;p&gt;Let's say you read about a subject. If you will remind yourself of the key points of this subject in the week, two weeks, month, 2 months, 4 months - Trust me you'll remember this topic for a long time compared to the scenario that not contains many repetitions.&lt;br&gt;
The things we remember the best are the things we saw frequently.&lt;br&gt;
Researches found that recalled subject will remain in your memory for significantly more time.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
This graph describes the process at a high level.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GHAaQGhg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1632239227486/pd2dEFj-R.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GHAaQGhg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1632239227486/pd2dEFj-R.png" alt="image.png"&gt;&lt;/a&gt;&lt;br&gt;
Recall is the process of reminding ourselves of a subject. With Recall we can move things from short-term memory to long-term memory easily, all you gotta do is re-read stuff! &lt;br&gt;&lt;br&gt;
Re-reading can be very exhausting. Personally, I hate read something again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spaced Repetition with &lt;em&gt;Remnote&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;So we understand that re-read stuff is not feasible, so I search for a platform that can help me perform the Recall process and store all the knowledge that I want to store without reading again my points.&lt;br&gt;
I'm using in the last year a tool called &lt;strong&gt;Remnote&lt;/strong&gt; for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Breaking down complex topics into simple intuitive bullets.&lt;/li&gt;
&lt;li&gt;Recall those bullets with Spaced Repetition.
After you broke the complex subject into key points, you can define which points will be recalled on the future.
Those points will transform to Flashcards! &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Flashcards Queue
&lt;/h3&gt;

&lt;p&gt;Remnote have a Flashcards Queue with all the flashcards that you stored.&lt;br&gt;
When you enter the queue Remnote will show you the points you summarized.&lt;br&gt;
Part of the text will be invisible (it depends on how you defined your REM, won't be discussed in this article).&lt;br&gt;
After you recalled the question/text you will specify how well you remembered this subject.&lt;/p&gt;

&lt;p&gt;Here you can see a question about Django framework.&lt;br&gt;
After I revealed the answer Remnote will ask me how good I was remembering that answer.&lt;br&gt;
According to my feedback, it will ask me the same questions with the new compatible interval.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
As you see it is possible to insert Code, Images, and more media types into a flashcard.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y2-RXB_D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1632243794047/xRNLPKeRc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y2-RXB_D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1632243794047/xRNLPKeRc.png" alt="Screen Shot 2021-09-21 at 20.02.51.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Real Life Scenario
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Reading about new Python feature.&lt;/li&gt;
&lt;li&gt;Deciding to remember this feature.&lt;/li&gt;
&lt;li&gt;Summarize with few points the feature in Remnote.&lt;/li&gt;
&lt;li&gt;Remnote will remind me of the subject once in a while ("Magic Intervals") when practicing Queue. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Self Discipline
&lt;/h3&gt;

&lt;p&gt;Remnote requires self-discipline. Effective usage will require getting into Remnote queue every day and practice few flashcards (as much as you can). &lt;br&gt;&lt;br&gt;
&lt;strong&gt;Make this task a habit.&lt;/strong&gt;&lt;br&gt;
I for example enter each day in the morning for 20 cards.&lt;br&gt;
The intervals that Remnote will remind you subjects depend on your answers in the flashcards, if it is difficult for you remembering a complex subject the flashcard will appear more frequently if it is easy to remember will be appeared less frequently - as I called the "Magic Interval". &lt;br&gt; It's important to say that there are many types of Spaced Repetition algorithms that support different intervals approaches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Knowledge DB
&lt;/h3&gt;

&lt;p&gt;Think about it, it's crazy! You have documentation of all the interesting stuff you read on. It's power and I'm sure it will help you in the future.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This article mentioned very few features that Remnote has. Please read more on Remnote homepage and watch Youtube videos of this concept. &lt;br&gt;&lt;br&gt;
For me, it helped a lot making my experience more valuable.&lt;br&gt;
Today, I summarize every interesting subject that I met. &lt;br&gt;
Read more about this concept, it will help you. &lt;/p&gt;

</description>
      <category>memory</category>
      <category>engineering</category>
      <category>improving</category>
    </item>
  </channel>
</rss>
