<?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: Flávia Bastos</title>
    <description>The latest articles on DEV Community by Flávia Bastos (@flaviabastos).</description>
    <link>https://dev.to/flaviabastos</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%2F110972%2Fe9068707-6c67-40bf-9d52-202dac1081be.png</url>
      <title>DEV Community: Flávia Bastos</title>
      <link>https://dev.to/flaviabastos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/flaviabastos"/>
    <language>en</language>
    <item>
      <title>Django Rest Framework: adding DateTimeField format serializer validation</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Wed, 15 Feb 2023 09:00:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/django-rest-framework-adding-datetimefield-format-serializer-validation-2jcp</link>
      <guid>https://dev.to/flaviabastos/django-rest-framework-adding-datetimefield-format-serializer-validation-2jcp</guid>
      <description>&lt;p&gt;Here’s an example of adding date and time validation to a DateTimeField in a serializer in the Django Rest Framework (DRF).&lt;/p&gt;

&lt;p&gt;A first pass, using only the default formats of DateTimeField(), would look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class CustomSearchFieldsSerializer(serializers.Serializer):
   start_time = serializers.DateTimeField()
   end_time = serializers.DateTimeField()

   def validate(self, data):
       # extra validation to ensure that the end date is always after the start date if data['start_time'] &amp;gt; data['end_time']:
           raise serializers.ValidationError("finish must occur after start")
       return data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sending a request to that endpoint with the following query parameters (note it only has a date, not time):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/v1/custom-search/?start_time=2022-11-01&amp;amp;end_time=2022-11-07
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns the following 400 Bad Request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   "start_time": [
       "Datetime has wrong format. Use one of these formats instead: YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HH:MM|-HH:MM|Z]."
   ],
   "end_time": [
       "Datetime has wrong format. Use one of these formats instead: YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HH:MM|-HH:MM|Z]."
   ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not exactly what we want… I want this to be flexible and accept date only as a valid option.&lt;/p&gt;

&lt;p&gt;Doing some research on the &lt;a href="https://www.django-rest-framework.org/api-guide/fields/#datetimefield" rel="noopener noreferrer"&gt;Django Rest Framework (DRF) documentation&lt;/a&gt;, I learned that I could customize the accepted formats. The next iteration 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;class CustomSearchFieldsSerializer(serializers.Serializer):
   start_time = serializers.DateTimeField(required=False,
                                          input_formats=["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d"])
   end_time = serializers.DateTimeField(required=False,
                                        input_formats=["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d"])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The valid input formats can be passed as strings in a list. We add a few options, including a date-only format (the last option in the list).&lt;/p&gt;

&lt;p&gt;Note: setting the flag “required” to False: this will make this field optional (in this case, the request could have no start and/or end time, which will then require the setting of some default values in the business logic to limit the query).&lt;/p&gt;

&lt;p&gt;For the purposes of the task I was working on, I settled on the following formats:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;input_formats=["%Y-%m-%d", "iso-8601"]

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

&lt;/div&gt;



&lt;p&gt;The first one accepts date only and the second follows the iso-8601 format, which is also the default format when nothing is set – the exact behaviour that we saw in the very first iteration. &lt;a href="https://www.w3.org/TR/NOTE-datetime" rel="noopener noreferrer"&gt;iso-8601 is an international standard for the representation of date and time formats&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;If you found this helpful, please share this article.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://flaviabastos.ca/?p=770" rel="noopener noreferrer"&gt;Django Rest Framework: adding DateTimeField format serializer validation&lt;/a&gt; was originally published at &lt;a href="https://flaviabastos.ca" rel="noopener noreferrer"&gt;flaviabastos.ca&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>todayilearned</category>
      <category>webdev</category>
      <category>django</category>
    </item>
    <item>
      <title>Book review: The Programmer’s Brain</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Wed, 23 Nov 2022 08:44:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/book-review-the-programmers-brain-9po</link>
      <guid>https://dev.to/flaviabastos/book-review-the-programmers-brain-9po</guid>
      <description>&lt;p&gt;As a software developer, I usually self-refer as a “Professional learner” and this book’s subtitle (“&lt;em&gt;What every programmer needs to know about cognition&lt;/em&gt;“) caught my eye right away.&lt;/p&gt;

&lt;p&gt;The author, Felienne Hermans, does a fantastic job explaining how our brain processes new information and shares, what I found the most valuable and immediately applicable, scientifically based tips and techniques to leverage our brain’s power to become a better programmer.&lt;/p&gt;

&lt;p&gt;I think of this book as the result of the application of Barbara Oakley’s excellent work on &lt;a href="https://www.amazon.com/Learning-How-Learn-Spending-Studying-ebook/dp/B077CRLW9Q/ref=sr_1_1?keywords=learning+how+to+learn&amp;amp;qid=1668722383&amp;amp;sprefix=learning+ho%2Caps%2C116&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Learning How to Learn&lt;/a&gt; to a Software Developer’s context – if you are not familiar with Barbara Oakley’s work, see the end of the post for more info.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, this is an excellent book. &lt;a href="https://www.manning.com/books/the-programmers-brain" rel="noopener noreferrer"&gt;Check it out!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(no, I make no commission on this; I just loved the book)&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Book Overview
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;The book is divided into 4 parts.&lt;/p&gt;

&lt;p&gt;Part 1 is about getting better at reading code. The author explains how our brains process information (and code, more specifically), and goes into practical tips on how to read code better (yes, reading code is a separate skill and you can develop it!).&lt;/p&gt;

&lt;p&gt;Part 2 deals with the thinking processes and how they affect our ability to solve problems.&lt;/p&gt;

&lt;p&gt;You know when you open some code for review and you have a hard time understanding what a chunk of code does? Part 3 is all about the cognitive load we get into when reading code and what we can do to write better code so that other people can understand our code more easily. So, unless you want to keep writing bad code for job security or #reasons, do not skip this section.  &lt;/p&gt;

&lt;p&gt;In the last part of the book, the author talks about writing code in a team/group environment. Chapter 13, “How to Onboard New Developers” in my opinion should be a must-read for any lead and team manager (yeah, go ahead and read it now; you can read it standalone from the rest of the book and still take away a lot, I promise!).&lt;/p&gt;

&lt;h2&gt;
  
  
  My takeaways
&lt;/h2&gt;

&lt;p&gt;I really liked this book (in case it’s not clear yet!) and I personally loved part 3 because I’ve been thinking a lot lately about readability, maintainability, clean code, and all that good stuff. Another important takeaway for me is to work and get really good at the basics as the building blocks to solve more complex problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  For more info about Barbara Oakley’s work
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://barbaraoakley.com/" rel="noopener noreferrer"&gt;Barbara Oakley&lt;/a&gt; is a professor of Engineering and is famous for her book “&lt;a href="https://www.amazon.com/Learning-How-Learn-Spending-Studying-ebook/dp/B077CRLW9Q/ref=sr_1_1?keywords=learning+how+to+learn&amp;amp;qid=1668722383&amp;amp;sprefix=learning+ho%2Caps%2C116&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Learning How to Learn&lt;/a&gt;“, &lt;a href="https://barbaraoakley.com/books/" rel="noopener noreferrer"&gt;among others&lt;/a&gt;. The content of the book was made into a free online course “&lt;a href="https://www.coursera.org/learn/learning-how-to-learn" rel="noopener noreferrer"&gt;Learning How to Learn” on Coursera&lt;/a&gt; by UC San Diego. I highly recommended it! If you want a shorter version, she gave a talk for the series &lt;a href="https://www.youtube.com/watch?v=vd2dtkMINIw" rel="noopener noreferrer"&gt;“Talks at Google” about this book&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;If you found this helpful, please share this article!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The post&lt;/em&gt; &lt;a href="https://flaviabastos.ca/2022/11/17/book-review-the-programmers-brain/" rel="noopener noreferrer"&gt;&lt;em&gt;Book review:&lt;/em&gt; The Programmer’s Brain&lt;/a&gt; _was originally published at _&lt;a href="https://flaviabastos.ca/" rel="noopener noreferrer"&gt;flaviabastos.ca&lt;/a&gt;&lt;/p&gt;

</description>
      <category>books</category>
      <category>book</category>
      <category>career</category>
    </item>
    <item>
      <title>Como reverter um commit no git</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Tue, 08 Nov 2022 08:00:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/como-reverter-um-commit-no-git-40og</link>
      <guid>https://dev.to/flaviabastos/como-reverter-um-commit-no-git-40og</guid>
      <description>&lt;p&gt;Existem algumas maneiras diferentes de desfazer as coisas no git, mas para o propósito deste post vamos considerar o seguinte cenário:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;um repositório com cópias locais e remotas&lt;/li&gt;
&lt;li&gt;vários colaboradores&lt;/li&gt;
&lt;li&gt;um commit recente que já foi adicionado ao repositório remoto (“merged”, pra usar o termo “git” em inglês) mas que precisa ser revertido&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;git revert&lt;/strong&gt; pra resolver esse problema! &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F2728.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%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F2728.png" alt="✨"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  RESUMÃO: passos pra reverter um commit em um repositório remoto:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;atualize a cópia local do repostitório na seu branch principal:  &lt;strong&gt;git pull&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;crie um novo branch:  &lt;strong&gt;git checkout -b remove_codigo_bugado&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;encontre o hash do commit com bugs com  &lt;strong&gt;git log&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;git revert  [-m 1 –no-edit]&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O comando acima criará um novo commit onde todas as alterações do commit original que foi adicionado ao repositório remoto serão revertidas. Isso é bom porque fazendo desse jeito você mantém o histórico do repositório inalterado.&lt;/p&gt;

&lt;p&gt;As opções opcionais mostradas no comando acima significam:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-m n&lt;/strong&gt;  : se você está revertendo um “merge” commit (o commit final que foi adicionado ao repositório remoto), você precisa passar esta opção com um número ( tem uma entrada em inglês no &lt;a href="https://translate.google.com/website?sl=en&amp;amp;tl=de&amp;amp;hl=en-US&amp;amp;client=webapp&amp;amp;u=https://stackoverflow.com/a/7100005" rel="noopener noreferrer"&gt;StackOverflow explicando o porquê&lt;/a&gt; )&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;–no-edit&lt;/strong&gt;  : (&lt;em&gt;note que são dois traços no início da opção!&lt;/em&gt;) isso vai evitar que o editor de texto padrão abra automaticamente&lt;/p&gt;

&lt;h2&gt;
  
  
  EXEMPLO passo-a-passo:
&lt;/h2&gt;

&lt;p&gt;Meu branch principal e local chamado &lt;code&gt;main&lt;/code&gt; tá assim:&lt;/p&gt;

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

└❯ git log
commit 9ebef49af9f50996f32c863604b1fc6fdce71e26 (HEAD -&amp;gt; main, origin/main, origin/HEAD)
Author: Flavia Bastos &amp;lt;meu_email&amp;gt;
Date: Tue Oct 4 19:22:55 2022 -0300

    Corrigir ortografia


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

&lt;/div&gt;

&lt;p&gt;Nesse meio tempo alguém adiciona um commit novo no repositório remoto. Quando eu puxo as alterações novas pro meu repositório local, eu vejo o commit novo ( &lt;code&gt;86d1c24f17aa7&lt;/code&gt;) e um merge commit novo ( &lt;code&gt;5aa51c6ea265cc&lt;/code&gt;) para essas alterações:&lt;/p&gt;

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

└❯ git log
commit 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df (HEAD -&amp;gt; main, origin/main, origin/HEAD)
Merge: 9ebef49 86d1c24
Author: Outra pessoa &amp;lt;outro_email&amp;gt;
Date: Thu Oct 6 17:14:15 2022 -0400

    Merge pull request #1 from Outra pessoa/caso_123

    Codigo novo cheio de firula

commit 86d1c24f17aa7fd264a26d81533e53f6f48dea24 (origin/caso_123, caso_123)
Author: Outra pessoa &amp;lt;outro_email&amp;gt;
Date: Thu Oct 6 18:08:49 2022 -0300

    Codigo novo cheio de firula

commit 9ebef49af9f50996f32c863604b1fc6fdce71e26
Author: Flavia Bastos &amp;lt;meu_email&amp;gt;
Date: Tue Oct 4 19:22:55 2022 -0300

    Corrigir ortografia


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

&lt;/div&gt;

&lt;p&gt;Observe aqui que o merge commit ( &lt;code&gt;5aa51c6ea265cc&lt;/code&gt;) também descreve os commits antecedentes no atributo “Merge”:&lt;/p&gt;

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

Merge: 9ebef49 86d1c24


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

&lt;/div&gt;

&lt;p&gt;Daí acontece que esse código sofisticado também estava com bugs e fez com que algumas coisas quebrassem feio. Quem nunca, neah? &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F1f440.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%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F1f440.png" alt="👀"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos corrigir isso rapidamente criando um branch novo a partir da última atualização da branch principal (&lt;code&gt;main&lt;/code&gt;):&lt;/p&gt;

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

└❯ git checkout -b corrige_bug
Switched to a new branch 'corrige_bug'


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

&lt;/div&gt;

&lt;p&gt;A partir da mensagem do comando &lt;code&gt;git log&lt;/code&gt; acima, sabemos que queremos o hash do commit mais recente (o primeiro da lista nesse caso), mas pode haver outros commits novos depois dele. Sempre confirme rodando o &lt;code&gt;git log&lt;/code&gt; de novo.&lt;/p&gt;

&lt;p&gt;Agora vamos reverter o commit com bug ( &lt;code&gt;5aa51c6ea265cc&lt;/code&gt;) – observe que estamos em um branch separado e estou usando a opção &lt;code&gt;-m 1&lt;/code&gt;, porque quero reverter para seu primeiro antecedente &lt;code&gt;9ebef49&lt;/code&gt; (se eu usasse -m 2 ao invés, ele reverteria para o segundo antecedente &lt;code&gt;86d1c24&lt;/code&gt;):&lt;/p&gt;

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

└❯ git revert 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df -m 1 --no-edit
[corrige_bug 560ad2d] Revert "Merge pull request #1 from Outra pessoa/caso_123"
 Date: Thu Oct 6 18:30:50 2022 -0300
 1 file changed, 1 insertion(+), 1 deletion(-)


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

&lt;/div&gt;

&lt;p&gt;O úlimo passo agora é mandar esse branch  &lt;code&gt;corrige_bug&lt;/code&gt;pro repositório remoto e dar merge na alteração:&lt;/p&gt;

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

└❯ git push origin corrige_bug
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 402 bytes | 402.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote: 
remote: Create a pull request for 'corrige_bug' on GitHub by visiting:
remote: https://github.com/FlaviaBastos/meu_projeto/pull/new/corrige_bug
remote: 
To github.com:FlaviaBastos/meu_projeto.git
 * [new branch] corrige_bug -&amp;gt; corrige_bug


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

&lt;/div&gt;

&lt;p&gt;Depois que essa última alteração for adicionada ao repositório remoto, volte para o branch principal &lt;code&gt;main&lt;/code&gt; no seu repositório local, puxe as últimas alterações e confirme com o &lt;code&gt;git log&lt;/code&gt; que o commit com erros foi revertido:&lt;/p&gt;

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

❯ git log
commit 4332e3e999c2056019cf64255f17b32a6ef1992b (HEAD -&amp;gt; main, origin/main, origin/HEAD)
Merge: 5aa51c6 560ad2d
Author: Outra pessoa &amp;lt;outro_email&amp;gt;
Date: Thu Oct 6 17:53:28 2022 -0400

    Merge pull request #2 from FlaviaBastos/corrige_bug

    Revert "Merge pull request #1 from Outra pessoa/caso_123"

commit 560ad2ddfd207fad2f609873270bdd3f645bb4b6 (origin/corrige_bug, corrige_bug)
Author: Flavia Bastos &amp;lt;my_email&amp;gt;
Date: Thu Oct 6 18:30:50 2022 -0300

    Revert "Merge pull request #1 from Outra pessoa/caso_123"

    This reverts commit 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df, reversing
    changes made to 9ebef49af9f50996f32c863604b1fc6fdce71e26.

commit 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df (HEAD -&amp;gt; main, origin/main, origin/HEAD)
Merge: 9ebef49 86d1c24
Author: Outra pessoa &amp;lt;outro_email&amp;gt;
Date: Thu Oct 6 17:14:15 2022 -0400

    Merge pull request #1 from Outra pessoa/caso_123

    Codigo novo cheio de firula


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

&lt;/div&gt;

&lt;p&gt;Ufa! Tudo resolvido! &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F1f605.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%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F1f605.png" alt="😅"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  MAS peraí, o &lt;code&gt;RESET --HARD&lt;/code&gt; faz a mesma coisa, não?
&lt;/h2&gt;

&lt;p&gt;Sim. Porém, apenas localmente. O comando &lt;code&gt;git reset&lt;/code&gt; vai mover o ponteiro do seu repositório para qualquer commit que você definir, efetivamente removendo qualquer coisa depois dele. Se você rodar um &lt;code&gt;git status&lt;/code&gt;, você não verá mais esses outros commits, nem nada de novo que precise ser feito commit e você estará reescrevendo o histórico do repositório desse jeito. Isso só é seguro se você estiver trabalhando sozinho ou em um branch que ainda não foi mandado e anexado ao repositório remoto.&lt;/p&gt;

&lt;p&gt;Se você precisar enviar as alterações de reversão de commit para um repositório remoto, você deve usar o &lt;code&gt;git revert&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pra saber mais:
&lt;/h2&gt;

&lt;p&gt;Documentação do git revert: &lt;a href="https://translate.google.com/website?sl=en&amp;amp;tl=de&amp;amp;hl=en-US&amp;amp;client=webapp&amp;amp;u=https://git-scm.com/docs/git-revert" rel="noopener noreferrer"&gt;https://git-scm.com/docs/git-revert/pt_BR&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Compartilhe esse artigo!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Como reverter um commit no git&lt;/p&gt;

&lt;p&gt;&lt;a href="http://twitter.com/share?&amp;amp;text=Como%20reverter%20um%20commit%20no%20git&amp;amp;url=https%3A%2F%2Fflaviabastos.ca%2F2022%2F11%2F08%2Fcomo-reverter-um-commit-no-git%2F" rel="noopener noreferrer"&gt;Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;O artigo&lt;/em&gt; &lt;a href="https://flaviabastos.ca/2022/10/28/como-reverter-um-commit-no-git/" rel="noopener noreferrer"&gt;Como reverter um commit no git&lt;/a&gt;_ foi publicado originalmente no _&lt;a href="https://flaviabastos.ca/" rel="noopener noreferrer"&gt;flaviabastos.ca&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>commandline</category>
      <category>ptbr</category>
    </item>
    <item>
      <title>TIL: installed packages in Python – list, and show</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Tue, 25 Oct 2022 08:00:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/til-installed-packages-in-python-list-and-show-63l</link>
      <guid>https://dev.to/flaviabastos/til-installed-packages-in-python-list-and-show-63l</guid>
      <description>&lt;p&gt;If your Python project has a very short list of required packages (in requirements, pipfile, etc), it’s easy to see all packages you have. But on large projects, the dependencies can run pretty long, not to mention the dependencies for the required packages. And what about learning more about those dependencies?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;pip list&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Will list all installed packages&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;pip show &amp;lt;package_name&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Will show information about installed packages and if you’re lucky, what other package requires that dependency&lt;/p&gt;

&lt;p&gt;And, of course, &lt;code&gt;pip -h&lt;/code&gt; will show all other pip options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example:
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;requirements.txt&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Django&amp;gt;=3.1.0,&amp;lt;3.2.0
djangorestframework&amp;gt;=3.12.2,&amp;lt;3.13.0
psycopg2&amp;gt;=2.8.6,&amp;lt;2.9.0
Pillow&amp;gt;=8.1.0,&amp;lt;8.2.0

flake8&amp;gt;=3.8.4,&amp;lt;3.9.0

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

&lt;/div&gt;



&lt;p&gt;List my packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pip list
Package Version
------------------- -------
asgiref 3.3.1
Django 3.1.7
djangorestframework 3.12.2
flake8 3.8.4
mccabe 0.6.1
Pillow 8.1.0
pip 21.0.1
psycopg2 2.8.6
pycodestyle 2.6.0
pyflakes 2.2.0
pytz 2021.1
setuptools 53.0.0
sqlparse 0.4.1
wheel 0.36.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Show more about one package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pip show pyflakes
Name: pyflakes
Version: 2.2.0
Summary: passive checker of Python programs
Home-page: https://github.com/PyCQA/pyflakes
Author: A lot of people
Author-email: code-quality@python.org
License: MIT
Location: /usr/local/lib/python3.9/site-packages
Requires: 
Required-by: flake8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;If you found this helpful, please share this article!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;List installed packages in Python&lt;/p&gt;

&lt;p&gt;&lt;a href="http://twitter.com/share?&amp;amp;text=List%20installed%20packages%20in%20Python&amp;amp;url=https%3A%2F%2Fflaviabastos.ca%2F2022%2F10%2F25%2Ftil-installed-packages-in-python-list-and-show%2F"&gt;Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;The post&lt;/em&gt; &lt;a href="http://til-installed-packages-in-python---list-and-show"&gt;TIL: installed packages in Python – list, and show&lt;/a&gt; _was originally published at _&lt;a href="https://flaviabastos.ca/"&gt;flaviabastos.ca&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>todayilearned</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to revert a commit in git</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Tue, 11 Oct 2022 08:00:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/how-to-revert-a-commit-in-git-1djc</link>
      <guid>https://dev.to/flaviabastos/how-to-revert-a-commit-in-git-1djc</guid>
      <description>&lt;p&gt;There are a few different ways to undo things in git but for the purpose of this post we will stick with the following scenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a repository with local and remote copies&lt;/li&gt;
&lt;li&gt;multi-person collaborators&lt;/li&gt;
&lt;li&gt;a recent change &lt;strong&gt;merged&lt;/strong&gt; to remote (and potentially deployed) that needs to be reverted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;git revert to the rescue!&lt;/strong&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xqCbiHOw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/2728.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xqCbiHOw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/2728.png" alt="✨" width="72" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL; DR: steps to revert a commit on a remote repo:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;on your local and main branch, pull the latest changes: &lt;strong&gt;git pull&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;create a new branch: &lt;strong&gt;git checkout -b remove_buggy_code&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;find the hash of the buggy commit with &lt;strong&gt;git log&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;git revert  [-m 1 –no-edit]&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The command above will create a new merge commit where all the changes from the original merge commit are reverted. This is good because this keeps the repository’s history unchanged.&lt;/p&gt;

&lt;p&gt;The optional tags shown above mean:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-m n&lt;/strong&gt; : if you are reverting a merge commit you need to pass this flag with a number (&lt;a href="https://stackoverflow.com/a/7100005"&gt;this StackOverflow post explains why&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;–no-edit&lt;/strong&gt; : this will skip launching the default text editor&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s run through an example:
&lt;/h2&gt;

&lt;p&gt;My local, &lt;code&gt;main&lt;/code&gt; branch 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;└❯ git log
commit 9ebef49af9f50996f32c863604b1fc6fdce71e26 (HEAD -&amp;gt; main, origin/main, origin/HEAD)
Author: Flavia Bastos &amp;lt;my_email&amp;gt;
Date: Tue Oct 4 19:22:55 2022 -0300

    Fix typo on test name

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

&lt;/div&gt;



&lt;p&gt;Then someone merges a new commit to remote. When I pull the new changes, I see the new commit (&lt;code&gt;86d1c24f17aa7&lt;/code&gt;) and a new merge commit (&lt;code&gt;5aa51c6ea265cc&lt;/code&gt;) for those changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;└❯ git log
commit 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df (HEAD -&amp;gt; main, origin/main, origin/HEAD)
Merge: 9ebef49 86d1c24
Author: Someone Else &amp;lt;another_email&amp;gt;
Date: Thu Oct 6 17:14:15 2022 -0400

    Merge pull request #1 from SomeoneElse/fancy_feature

    fancy code

commit 86d1c24f17aa7fd264a26d81533e53f6f48dea24 (origin/fancy_feature, fancy_feature)
Author: Someone Else &amp;lt;another_email&amp;gt;
Date: Thu Oct 6 18:08:49 2022 -0300

    fancy code

commit 9ebef49af9f50996f32c863604b1fc6fdce71e26
Author: Flavia Bastos &amp;lt;my_email&amp;gt;
Date: Tue Oct 4 19:22:55 2022 -0300

    Fix typo on test name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note here that the merge commit (&lt;code&gt;5aa51c6ea265cc&lt;/code&gt;) also outlines the parent commits in the “Merge” attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Merge: 9ebef49 86d1c24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, it turns out that this fancy code was also buggy and it caused some things to break really bad &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ukjLSReN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f440.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ukjLSReN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f440.png" alt="👀" width="72" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s fix this quickly by creating a new branch from this latest &lt;code&gt;main&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;└❯ git checkout -b bug_fixer
Switched to a new branch 'bug_fixer'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the output of the &lt;code&gt;git log&lt;/code&gt; command above, we know that we want the most recent (top) commit hash, but there could be other commits on top of it. Always confirm with &lt;code&gt;git log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now let’s revert the buggy commit (&lt;code&gt;5aa51c6ea265cc&lt;/code&gt;) – note we are on a separate branch and I’m using the&lt;code&gt;-m 1&lt;/code&gt;flag, because I want to revert to its first parent &lt;code&gt;9ebef49&lt;/code&gt; (-m 2 would revert to the second parent &lt;code&gt;86d1c24&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;└❯ git revert 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df -m 1 --no-edit
[bug_fixer 560ad2d] Revert "Merge pull request #1 from SomeoneElse/fancy_feature"
 Date: Thu Oct 6 18:30:50 2022 -0300
 1 file changed, 1 insertion(+), 1 deletion(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All that’s left now it to push this &lt;code&gt;bug_fixer&lt;/code&gt; branch up to remote and merge this change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;└❯ git push origin bug_fixer
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 402 bytes | 402.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote: 
remote: Create a pull request for 'bug_fixer' on GitHub by visiting:
remote: https://github.com/FlaviaBastos/my_project_name/pull/new/bug_fixer
remote: 
To github.com:FlaviaBastos/my_project_name.git
 * [new branch] bug_fixer -&amp;gt; bug_fixer

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

&lt;/div&gt;



&lt;p&gt;After this last change is merged in the remote repo, go back to the &lt;code&gt;main&lt;/code&gt; branch, pull the latest changes and confirm with &lt;code&gt;git log&lt;/code&gt; that the buggy commit was reverted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ git log
commit 4332e3e999c2056019cf64255f17b32a6ef1992b (HEAD -&amp;gt; main, origin/main, origin/HEAD)
Merge: 5aa51c6 560ad2d
Author: Someone Else &amp;lt;another_email&amp;gt;
Date: Thu Oct 6 17:53:28 2022 -0400

    Merge pull request #2 from FlaviaBastos/bug_fixer

    Revert "Merge pull request #1 from SomeoneElse/fancy_feature"

commit 560ad2ddfd207fad2f609873270bdd3f645bb4b6 (origin/bug_fixer, bug_fixer)
Author: Flavia Bastos &amp;lt;my_email&amp;gt;
Date: Thu Oct 6 18:30:50 2022 -0300

    Revert "Merge pull request #1 from SomeoneElse/fancy_feature"

    This reverts commit 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df, reversing
    changes made to 9ebef49af9f50996f32c863604b1fc6fdce71e26.

commit 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df
Merge: 9ebef49 86d1c24
Author: Someone Else &amp;lt;another_email&amp;gt;
Date: Thu Oct 6 17:14:15 2022 -0400

    Merge pull request #1 from SomeoneElse/fancy_feature

    fancy code

commit 86d1c24f17aa7fd264a26d81533e53f6f48dea24 (origin/fancy_feature, fancy_feature)
Author: Flavia Bastos &amp;lt;my_email&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Phew! Crisis averted! &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z5VYj9Ua--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f605.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z5VYj9Ua--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f605.png" alt="😅" width="72" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  But what about &lt;code&gt;reset --hard&lt;/code&gt;? Doesn’t it revert commits too?
&lt;/h2&gt;

&lt;p&gt;Yes, it does. Only locally though. &lt;code&gt;git reset&lt;/code&gt; will move the head (the pointer) of your repo to whatever commit you set it to, effectively removing anything after it – chopping anything above the head, if you will. The diff is lost. If you then do a &lt;code&gt;git status&lt;/code&gt;, you will not see those other commits anymore, nor anything new that needs to be staged and you are rewriting history. This is only safe to do if you are working solo or on a branch that has not been pushed to remote yet.&lt;/p&gt;

&lt;p&gt;If you need to push the changes to a remote repo, you need to use &lt;code&gt;git revert&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn more:
&lt;/h2&gt;

&lt;p&gt;git revert documentation: &lt;a href="https://git-scm.com/docs/git-revert"&gt;https://git-scm.com/docs/git-revert&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;If you found this helpful, please share this article!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How to revert a commit in git&lt;/p&gt;

&lt;p&gt;&lt;a href="http://twitter.com/share?&amp;amp;text=How%20to%20revert%20a%20commit%20in%20git&amp;amp;url=https%3A%2F%2Fflaviabastos.ca%2F2022%2F10%2F11%2Fhow-to-revert-a-commit-in-git%2F"&gt;Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;The post&lt;/em&gt; &lt;a href="https://flaviabastos.ca/2022/10/07/how-to-revert-a-commit-in-git/"&gt;How to revert a commit in git&lt;/a&gt; _was originally published at _&lt;a href="https://flaviabastos.ca/"&gt;flaviabastos.ca&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>commandline</category>
    </item>
    <item>
      <title>Managing local git branches with git rebase</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Thu, 03 Mar 2022 09:00:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/managing-local-git-branches-with-git-rebase-4ekp</link>
      <guid>https://dev.to/flaviabastos/managing-local-git-branches-with-git-rebase-4ekp</guid>
      <description>&lt;p&gt;When you work on a codebase with other people, you need to manage your local branches: you need to ensure that when you push some code and create a merge/pull request on the remote branch, your changes will be easily integrated with the main codebase. And by “easily” I mean preferably without merge conflicts or the dreaded message “your branch is xxx commits behind the target branch”. 👀&lt;/p&gt;

&lt;p&gt;There are many ways to accomplish this but I personally like to use git rebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  what is git rebase
&lt;/h2&gt;

&lt;p&gt;Git rebase is the tool used to combine changes from one branch into another branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  when to use git rebase
&lt;/h2&gt;

&lt;p&gt;You want to use git rebase when have a local branch with changes (for a bug fix or new feature, for example) and the main branch (the one you created your branch from) received updates and you want those updates in your local branch too, along with your changes.&lt;br&gt;&lt;br&gt;
In other words, you want to use git rebase to make sure your work is up to date with all the changes from the main branch and ready to be reviewed and potentially merged.&lt;/p&gt;

&lt;h2&gt;
  
  
  when NOT to use git rebase
&lt;/h2&gt;

&lt;p&gt;You should not use git rebase on a shared branch (say a main or dev branch). Only rebase your local, non-shared branches. Treat rebase as a clean up tool for when you are getting ready to open a merge/pull request.&lt;br&gt;&lt;br&gt;
The reason for this recommendation is because of how git rebase works – which I will not get into here but you can watch &lt;a href="https://www.youtube.com/watch?v=BFszA0io_7M"&gt;this short video&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  how to use git rebase:
&lt;/h2&gt;

&lt;p&gt;I often run into 2 different cases that will determine how I use git rebase:&lt;/p&gt;

&lt;p&gt;1- my local branch was created from the main branch (a “child” branch)&lt;/p&gt;

&lt;p&gt;2- my local branch was created a from a branch that was branched from main (a “grandchild” branch)&lt;/p&gt;

&lt;p&gt;In both cases the “main” branch received updates and I need those updates in my local branch.&lt;/p&gt;

&lt;p&gt;This is how it works:&lt;/p&gt;

&lt;h3&gt;
  
  
  git rebase – branch out of main
&lt;/h3&gt;

&lt;p&gt;I created a local branch directly out of the main branch so I can add my super-cool feature. While I’m still working on it OR if I’m ready to send it to code review, I find out that there’s one important bug fix in the main branch and I need it on my local branch too.&lt;/p&gt;

&lt;p&gt;This is the most simple case and all I need to do is to 1. get those latest changes from main and 2. add them to my branch:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$super-cool:&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git fetch &amp;amp;&amp;amp; git rebase origin/main&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That’s it. You can continue working on your super-cool feature or just push your local to the remote (for code review, I hope! 😅)&lt;/p&gt;

&lt;h3&gt;
  
  
  git rebase – branch of branch of main
&lt;/h3&gt;

&lt;p&gt;This is another case I run into often:&lt;/p&gt;

&lt;p&gt;I create a local branch “super-cool” from the main branch and add my changes to it. I send this change for code review and I want to start working &lt;em&gt;right-away&lt;/em&gt; on adding another feature that depends on the super-cool feature that have not been merged to the main branch yet.&lt;/p&gt;

&lt;p&gt;If I create a branch from main, the required code won’t be there. There are other ways to solve this (like cherry-picking, for example) but what I usually do is to create a branch from the “super-cool” branch:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$super-cool:&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git checkout -b "super-cool-premium"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now I have all the super-cool changes and can add the premium changes I want.&lt;/p&gt;

&lt;p&gt;Meanwhile my colleagues approved my pull/merge request from “super-cool” and those changes are now merged to the main branch.&lt;/p&gt;

&lt;p&gt;Now my local “super-cool-premium” branch needs to reflect that change also: I want to make it look like as if I had branched directly from latest main (without getting into much detail here, this is good because it makes the history look cleaner).&lt;/p&gt;

&lt;p&gt;In this case I use the &lt;em&gt;–onto&lt;/em&gt; variant of the rebase command in my “super-cool-premium” branch:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$super-cool-premium:&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git rebase --onto origin/main @~1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is telling git to update my local “super-cool-premium” branch by bringing the latest changes from main and applying my changes on top of it. When my super-cool-premium gets merged to main later on, the main branch history will look like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Merge branch 'super-cool-premium' into 'main'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"add super-cool-premium feature"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Merge branch 'super-cool' into 'main'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"add super-cool feature"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Merge branch 'bug-fix-34' into 'main'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"main bug fix #34"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Merge branch 'bug-fix-34' into 'main'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"main bug fix #33"&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  when git rebase has conflicts
&lt;/h2&gt;

&lt;p&gt;There are times when you try to rebase and you will get a warning that there are files with conflicts.&lt;/p&gt;

&lt;p&gt;At this point you will notice that your branch is in “detached” mode: it’s waiting for instructions on what to do next and you must pick one of the two options: resolve the conflicts and continue the rebase with –continue or abort the operation with the –abort flag.&lt;/p&gt;

&lt;p&gt;If you decide to keep going, it’s a matter of resolving the conflicts in your code editor, adding all changes (with git add; no need to create a new commit!) and telling git to continue with the rebase process:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git rebase --continue&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  managing your commits – the case for single commits
&lt;/h2&gt;

&lt;p&gt;🚨🚨🚨 &lt;em&gt;strong personal opinion disclaimer&lt;/em&gt; 🚨🚨🚨&lt;/p&gt;

&lt;p&gt;One habit that I have that I find that helps a lot with minimizing confusion and conflicts when dealing with remote public branches is that I &lt;strong&gt;always&lt;/strong&gt; only submit one single commit with my pull/merge request. Even if I need to address feedback from code review and update my code, I will still keep one single commit &lt;em&gt;(I usually amend the commit, which is a *safe* thing to do only before the branch has been merged!!&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;I can have multiple commits while I work on my local branch but before I push it to remote I will always squash the commits. No need to add “&lt;em&gt;fix bug&lt;/em&gt;“, “&lt;em&gt;fix bug again&lt;/em&gt;“, “&lt;em&gt;fix for reals&lt;/em&gt;“, “&lt;em&gt;are you kidding me&lt;/em&gt;” and so on the the main history, right? 👀 I will squash them all and give my commit a clear message like: “add super cool feature”.&lt;/p&gt;

&lt;p&gt;That way, in the main branch history you will see only one commit per feature or bug fix added (plus the actual merge commit).🤩&lt;br&gt;
This helps a lot when merging multiple branches, doing rebases, managing conflicts, reverting changes, etc. Plus the history will look soooooo tidy. I treat each bug fix/new feature as a one distinct package to be added to the codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s wrong with using git merge?
&lt;/h2&gt;

&lt;p&gt;Nothing! Git merge adds a merge commit so if you try to keep your local branch up to date with main by merging main into your branch, be aware that you will have those extra commits. And there is nothing wrong with that. Personally I don’t like it and prefer one single commit per feature or bug fix I submit and that’s why I use rebase a lot. And squash my commits (which I will write about some other time but – spoiler alert – it’s just git rebase in interactive mode 😲)&lt;/p&gt;

&lt;h2&gt;
  
  
  there’s more to git rebase
&lt;/h2&gt;

&lt;p&gt;These are two examples of git rebase that I use on a regular basis but there’s a lot more to it. &lt;a href="https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase"&gt;This tutorial goes into more depth&lt;/a&gt; on how git rebase works and brings up some considerations and warnings regarding this helpful command. One warning worth mentioning again is that you should never rebase a remote common branch (in our example, the main branch). Rebase should always be done in a local branch before it gets merged to the remote.&lt;/p&gt;




&lt;p&gt;If you found this helpful, please share this article!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Managing local git branches with git rebase&lt;/p&gt;

&lt;p&gt;&lt;a href="http://twitter.com/share?&amp;amp;text=Managing%20local%20git%20branches%20with%20git%20rebase&amp;amp;url=https%3A%2F%2Fflaviabastos.ca%2F2022%2F03%2F03%2Fmanaging-local-git-branches-with-git-rebase%2F"&gt;Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;The post&lt;/em&gt; &lt;a href="https://flaviabastos.ca/2022/02/08/managing-local-git-branches-with-git-rebase/"&gt;Managing local git branches with git rebase&lt;/a&gt; _was originally published at _&lt;a href="https://flaviabastos.ca/"&gt;flaviabastos.ca&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>howto</category>
      <category>commandline</category>
    </item>
    <item>
      <title>The difference between HTTP status codes 401 and 403: Unauthorized and Forbidden</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Wed, 17 Nov 2021 09:00:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/the-difference-between-http-status-codes-401-and-403-unauthorized-and-forbidden-76i</link>
      <guid>https://dev.to/flaviabastos/the-difference-between-http-status-codes-401-and-403-unauthorized-and-forbidden-76i</guid>
      <description>&lt;p&gt;You are working with an API and after sending a request you receive one of these two HTTP response codes: 401 or 403. What do HTTP status codes 401 and 403 mean?&lt;/p&gt;

&lt;h2&gt;
  
  
  Official specification
&lt;/h2&gt;

&lt;p&gt;If you search for the official specification, this is what you get:&lt;/p&gt;

&lt;h3&gt;
  
  
  401: Unauthorized
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. &lt;/p&gt;

&lt;p&gt;&lt;cite&gt;&lt;a href="https://httpwg.org/specs/rfc7235.html#status.401" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://httpwg.org/specs/rfc7235.html#status.401" rel="noopener noreferrer"&gt;https://httpwg.org/specs/rfc7235.html#status.401&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  403: Forbidden
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The 403 (Forbidden) status code indicates that the server understood the request but refuses to authorize it. &lt;/p&gt;

&lt;p&gt;&lt;cite&gt;&lt;a href="https://httpwg.org/specs/rfc7231.html#status.403" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://httpwg.org/specs/rfc7231.html#status.403" rel="noopener noreferrer"&gt;https://httpwg.org/specs/rfc7231.html#status.403&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hmmm…. &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F1f914.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%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F1f914.png" alt="🤔"&gt;&lt;/a&gt; These two sound pretty similar to me. And to make things even more confusing, 403 “Forbidden” says that the server refuses to “authorize” the request but it’s code 401 that is called “Unauthorized”. &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F1f635.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%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F1f635.png" alt="😵"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s simplify: airport analogy
&lt;/h2&gt;

&lt;p&gt;You need a valid flight ticket to board a plane and the flight ticket has some information: your name and the gate number, for example, along with the destination, flight time, etc.&lt;/p&gt;

&lt;p&gt;To simplify this analogy, the ticket has two parts: your identification (a username and a password to access the API) and your gate number (the resource you want to access).&lt;/p&gt;

&lt;p&gt;If the ticket is incorrect or damaged, you cannot even go through the airport security: when they check your ticket, it will be refused. You are &lt;strong&gt;Forbidden&lt;/strong&gt; to enter the boarding area of the airport.&lt;/p&gt;

&lt;p&gt;Next, let’s say that your ticket is correct (so you made through security just fine!) and the gate number in your ticket says “Gate 24” but you walk to Gate 27. The attendant &lt;strong&gt;cannot authorize&lt;/strong&gt; you to go through that gate because it’s not the right gate for your ticket.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In other words, an “incorrect ticket” is similar to messing up your credentials: wrong username and/or password and you receive back a 403 Forbidden. Using the correct credentials but trying to access a resource that is not allowed for those credentials returns you a 401 Unauthorized.&lt;/p&gt;
&lt;/blockquote&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%2Ftestfbdotblog.files.wordpress.com%2F2021%2F11%2F403-x-401.png%3Fw%3D1024" 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%2Ftestfbdotblog.files.wordpress.com%2F2021%2F11%2F403-x-401.png%3Fw%3D1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also think that 403 happens before 401, despite the natural number order: you will not receive a 401 until you resolve a 403.&lt;/p&gt;

&lt;h2&gt;
  
  
  A real example
&lt;/h2&gt;

&lt;p&gt;The screenshot below shows that I try to login to my headspace account with a incorrect password (a “damaged” ticket in our analogy) and the response code in the network tab of the developer tools shows the 403.&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%2Ftestfbdotblog.files.wordpress.com%2F2021%2F11%2Fheadspace.png%3Fw%3D1024" 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%2Ftestfbdotblog.files.wordpress.com%2F2021%2F11%2Fheadspace.png%3Fw%3D1024" alt="screenshot of login page and developer tools network tab showing 403 status code"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;403 HTTP status code when trying to login with incorrect username or password&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Important! Don’t believe everything you read!
&lt;/h2&gt;

&lt;p&gt;One important thing to note here: the official specification is &lt;strong&gt;not enforced in any way&lt;/strong&gt; and like many other things in software development, you might find out that the response codes are not consistent with the specification. If you are using a web framework, this will be configured out of the box and the return codes will work as specified but developers can override the base implementation and assign whichever code they want as responses.&lt;/p&gt;

&lt;p&gt;Of course this is a bad idea because it will lead to confusion and it’s prone to error.&lt;/p&gt;

&lt;p&gt;It takes just one Google search to prove to you that people mix these 2 status codes up all.the.time and there’s a chance that the API you are using got things backwards!&lt;/p&gt;

&lt;p&gt;Here’s a horror story for you: I once worked with an API that only used GET methods (for modifying resources as well, instead of POST!!) and all response codes, for anything, were 200. &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F1f631.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%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2F72x72%2F1f631.png" alt="😱"&gt;&lt;/a&gt; So! Watch out!&lt;/p&gt;




&lt;p&gt;If you found this helpful, please share this article!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;HTTP 401 and 403 explained&lt;/p&gt;

&lt;p&gt;&lt;a href="http://twitter.com/share?&amp;amp;text=HTTP%20401%20and%20403%20explained&amp;amp;url=https://flaviabastos.ca/2021/11/17/the-difference-between-http-status-codes-401-and-403-unauthorized-and-forbidden/" rel="noopener noreferrer"&gt;Tweet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The post&lt;/em&gt; &lt;a href="https://flaviabastos.ca/2021/11/15/the-difference-between-http-status-codes-401-and-403-unauthorized-and-forbidden/" rel="noopener noreferrer"&gt;The difference between HTTP status codes 401 and 403: Unauthorized and Forbidden&lt;/a&gt; _was originally published at _&lt;a href="https://flaviabastos.ca/" rel="noopener noreferrer"&gt;flaviabastos.ca&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>quicktip</category>
    </item>
    <item>
      <title>A caller id for your python function</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Wed, 30 Jun 2021 08:00:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/a-caller-id-for-your-python-function-4bjk</link>
      <guid>https://dev.to/flaviabastos/a-caller-id-for-your-python-function-4bjk</guid>
      <description>&lt;p&gt;Most of you might be too young to know this but there was time that the phone in your house – not in your pocket! – would ring and gasp! you had no idea who were calling! You had to ANSWER the phone to find out. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o3MKE5v4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f926-200d-2640-fe0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o3MKE5v4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f926-200d-2640-fe0f.png" alt="🤦‍♀️"&gt;&lt;/a&gt; Now we have caller ID and know exactly who is calling – and can &lt;del&gt;completely ignore the call&lt;/del&gt; decide if we are answering the call or not.&lt;/p&gt;

&lt;p&gt;When working with large applications, for debugging purposes, I find very helpful to know which function is calling what function. Breakpoints and print statements are useful tools but sometimes you just need more information. In a large codebase it’s fairly easy to get lost with breakpoints so I’ve been using the chunk of code below to print extra info and learn a little bit more about my application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import inspect
func = inspect.currentframe().f_back.f_code
print(f"in function 'my_function' called from NAME: {func.co_name} in FILENAME: {func.co_filename} on LINE#: {func.co_firstlineno}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to use
&lt;/h2&gt;

&lt;p&gt;Consider a *very* simple program (which honestly doesn’t even need our helper function, but for the sake of example, stay with me here):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
def helper_function(value):
    return value.isnumeric()

def adder(num1, num2):
    return int(num1) + int(num2)

def main():
    print("The most useless calculator!")
    first_number = input("Please enter a number: ")
    second_number = input("Please enter another number: ")
    print(f"Let's add {first_number} and {second_number}")

    if helper_function(first_number) and helper_function(second_number):
        total = adder(first_number, second_number)
        print(f"The total is {total}")
    else:
        print("Sorry, we cannot add these values...")

main()

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

&lt;/div&gt;



&lt;p&gt;The function above takes two pieces of input form the command line (lines 11 and 12), calls a helper function to check if the values entered are numbers (line 15) and if so, calls the function to add the numbers (line 16).&lt;/p&gt;

&lt;p&gt;Now, just for a moment let’s pretend that each of these functions are way more complicated than this and live in separate files. Add some more functionality, a framework, 2 cups of all-purpose flour and a webserver. Voilà! You have a web application. What if you still want to know which function called what? Let’s add our chunk of code to adder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
def helper_function(value):
    return value.isnumeric()

def adder(num1, num2):
    import inspect
    func = inspect.currentframe().f_back.f_code
    print(
        f" **** in function 'adder' called from NAME: {func.co_name} in FILENAME: {func.co_filename} on LINE#: {func.co_firstlineno}"
    )

    return int(num1) + int(num2)

def main():
    print("The most useless calculator!")
    first_number = input("Please enter a number: ")
    second_number = input("Please enter another number: ")
    print(f"Let's add {first_number} and {second_number}")

    if helper_function(first_number) and helper_function(second_number):
        total = adder(first_number, second_number)
        print(f"The total is {total}")
    else:
        print("Sorry, we cannot add these values...")

main()

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

&lt;/div&gt;



&lt;p&gt;When you run this script now (let’s save it as “watcher.py”), it will output the information about the function that called adder, in this case, main:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; python3 watcher.py 
The most useless calculator!
Please enter a number: 4
Please enter another number: 2
Let's add 4 and 2
**** in function 'adder' called from NAME: main in FILENAME: watcher.py on LINE#: 15
The total is 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the line number is the line where the parent function, in this case “main”, starts, not where our function was called from!&lt;/p&gt;

&lt;p&gt;This has been very helpful and I’ve used a lot lately. I hope it helps you too!&lt;/p&gt;

&lt;h2&gt;
  
  
  Fancypants &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a5SaVb0k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f456.png" alt="👖"&gt;
&lt;/h2&gt;

&lt;p&gt;You will need to copy this chunk of code into every function you would like to debug but that’s a bit tedious. Instead, you can turn it into a decorator and decorate the functions you want to inspect. Start by creating your decorator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
def caller_id(my_func):
    def wrapper(*args, **kwargs):
        import inspect

        my_func(*args, **kwargs)

        func = inspect.currentframe().f_back.f_code
        print(
            f"in function {my_func. __name__ } called from NAME: {func.co_name} in FILENAME: {func.co_filename} on LINE#: {func.co_firstlineno}"
        )

    return wrapper

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

&lt;/div&gt;



&lt;p&gt;Then, you can decorate your function with it. Let’s add it to adder again. Now adder looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@caller_id
def adder(num1, num2):
    return int(num1) + int(num2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;If you found this helpful, let me know on &lt;a href="https://twitter.com/FlaSustenido"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The post&lt;/em&gt; &lt;a href="https://flaviabastos.ca/?p=565"&gt;A caller id for your python function&lt;/a&gt; _was originally published at _&lt;a href="https://flaviabastos.ca/"&gt;flaviabastos.ca&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>howto</category>
      <category>python</category>
      <category>debug</category>
      <category>decorator</category>
    </item>
    <item>
      <title>git stash 101</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Wed, 26 May 2021 07:10:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/git-stash-101-1f5c</link>
      <guid>https://dev.to/flaviabastos/git-stash-101-1f5c</guid>
      <description>&lt;p&gt;git is a very useful tool for software development and you only need to know &lt;a href="https://dev.to/flaviabastos/git-most-used-git-commands-4poo"&gt;a few commands to get most of the job done&lt;/a&gt;. However, you can be a lot more productive if you go beyond the basics.&lt;/p&gt;

&lt;p&gt;One git command I started using not too long ago is git stash. In my opinion this is one command that might not be super useful if you are just starting to code or you are the only person working on a personal project. But if you start collaborating and need to switch between a new feature work to fixing a bug, for example, git stash is very helpful.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does git stash do?
&lt;/h2&gt;

&lt;p&gt;It allows you to save your work in progress out of your way, meaning, without the need to create a commit, and access that work later.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use git stash?
&lt;/h2&gt;

&lt;p&gt;When you have some work in progress but you are not ready to create a commit yet (maybe you are just exploring some options or the work is not completed yet) and you need to switch branches OR you want to go back to start point but you &lt;strong&gt;want to keep the changes for later&lt;/strong&gt;. You can then ask git to take the current changes and save they aside. In this way, when you run “git status”, you see that your repo is back to the same state it was when you first cloned it or created that branch: the recent changes are not visible anymore but they are saved in case you want to go back and work on them again. You can now checkout a different branch and start new work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In other words…&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;almost&lt;/strong&gt; like having a branch within a branch: imagine that you created a branch for some new work. You make a few changes but you think you can create a different solution for that issue. You can stash the current changes so your new branch gets “reset” to the same state as when it was created and you can try a different solution. If later on you decide that your first solution was the best one, you can stash this new code and retrieve the previous solution from the stash.&lt;/p&gt;

&lt;p&gt;The key point for git stash is to &lt;strong&gt;save the changes for later&lt;/strong&gt;. If you don’t care about the changes and just want to discard unstaged changes (changes you did not “git add” yet), you can just run &lt;code&gt;git checkout .&lt;/code&gt; (&lt;em&gt;note the . at the end!&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Each repository has its own unique stash and you can end up with entries from different branches in that repository’s stash. &lt;strong&gt;Each stash entry is assigned an index&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic stashing activities:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;CREATE STASH&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;you can &lt;strong&gt;create a stash&lt;/strong&gt; for uncommitted changes by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash push&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;OR simply&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add a message&lt;/strong&gt; to your stash for easier identification afterwards:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash -m "recursive solution"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Stash &lt;strong&gt;only one file&lt;/strong&gt; (instead of all the changes):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash push &amp;lt;path_to_file&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;INSPECT STASH&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;you can &lt;strong&gt;check&lt;/strong&gt; your stash by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;list all the &lt;strong&gt;files that changed&lt;/strong&gt; when the stash entry was created:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash show stash@{1}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;// you can omit the stash index if your stash has only one entry!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;check the &lt;strong&gt;changes in a stash&lt;/strong&gt; entry – for example, &lt;code&gt;stash@{1}&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash show -p stash@{1}&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;MANAGE STASH&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;apply one&lt;/strong&gt; item from your stash to your code &lt;strong&gt;and KEEP&lt;/strong&gt; that entry in the stash:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash apply stash@{1}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;apply one&lt;/strong&gt; item from your stash to your code &lt;strong&gt;and REMOVE&lt;/strong&gt; that entry from the stash:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash pop stash@{1}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;remove&lt;/strong&gt; one entry from the stash:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;// this will delete this entry from the stash without applying it to your code!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash drop stash@{2}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;clean up&lt;/strong&gt; (delete) the whole stash:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash clear&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There are many other options to use with git stash but these are the ones I use most often. You can check git stash documentation for more options: &lt;a href="https://git-scm.com/docs/git-stash"&gt;https://git-scm.com/docs/git-stash&lt;/a&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;If you found this helpful, let me know on &lt;a href="https://twitter.com/FlaSustenido"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The post&lt;/em&gt; &lt;a href="https://flaviabastos.ca/?p=534"&gt;git stash 101&lt;/a&gt; _was originally published at _&lt;a href="https://flaviabastos.ca/"&gt;flaviabastos.ca&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>commandline</category>
      <category>git</category>
      <category>howto</category>
    </item>
    <item>
      <title>Developing inside a Docker container</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Wed, 14 Oct 2020 08:00:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/developing-inside-a-docker-container-4310</link>
      <guid>https://dev.to/flaviabastos/developing-inside-a-docker-container-4310</guid>
      <description>&lt;p&gt;A few months ago I got a new computer and I have been very intentional about deciding what I install on it. From past experience I know that computers that are used as a development environment tend to get messy in no time since one might install all kinds of libraries, frameworks, dependencies, you name it, and to makes matters worse, you will probably run into version conflicts for any or most of those things. Hardly ever a development environment is a clean environment and I don’t know about you but there are very few things that I find more frustrating than wasting time troubleshooting development environment set up. Let me write the code already!&lt;/p&gt;

&lt;p&gt;With that in mind, I decided early on that I would avoid installing node.js on this computer, for example. In my experience, Node is notorious for giving lots of headaches with version conflict. The Node Version Manager (&lt;code&gt;nvm&lt;/code&gt;) can only do so much to alleviate the problem and I find it clunky. So, no, thanks.&lt;/p&gt;

&lt;p&gt;Well, then smarty-pants. How do you do full stack web development these days without using nvm you ask me. Excellent question! The answer: Docker.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://flaviabastos.ca/tag/docker/"&gt;I’ve written about Docker in the past&lt;/a&gt; and I just plain love it. It took me some time to understand what it does and which problems it solves but once I did, it became my go-to solution to keep things under control: you can isolate a development environment with all dependencies and runtime that your project needs. If your friend wants to run your project, they get the container and &lt;em&gt;voilà&lt;/em&gt;, the project runs on their computer without they needing to install all dependencies locally. Beautiful! &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AAazvjmJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f60d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AAazvjmJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f60d.png" alt="😍" width="72" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, a few weeks ago I &lt;a href="https://mastergatsby.com/"&gt;started a new course to learn Gatsby&lt;/a&gt; and this was the perfect scenario to test my Docker development environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker image for a dev environment
&lt;/h3&gt;

&lt;p&gt;The first thing I did was to create a base image with node.js and a few utilities installed. Here’s the Dockerfile for the image I used:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Note about this setup: I use debian as a base image but if you care about image size, consider using alpine instead.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On the file above I have also highlighted in the comments how to 1. build the image and 2. two options to run the image. These are the two steps you need to take to start using this image as a container for your development environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing how to run the image
&lt;/h3&gt;

&lt;p&gt;If all you care is to have a “start point”, or clean slate if you will, run as the first option suggests. That will put you inside the container in a prompt on the root folder. You can then run other install commands .&lt;/p&gt;

&lt;p&gt;If you are using this image as a development environment (like I am), you will want to run as the second option (the longer &lt;code&gt;docker run&lt;/code&gt; command). This command does 2 extra things that will be super helpful: 1. expose container ports so you can access the project from your browser (more about this later) and 2. map the code you are writing on the code editor in your computer to a folder inside the container so the container can “see” the changes to your code. Yes, pretty much essential.&lt;/p&gt;

&lt;p&gt;For this example, I have this repository that I cloned from GitHub and it’s a Gatsby application. So I will run the second docker run command making sure I am using the correct path to my cloned repo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inside the container
&lt;/h3&gt;

&lt;p&gt;Once I have the command prompt inside the container, I can navigate to the place in the repository that holds the &lt;code&gt;package.json&lt;/code&gt; file and then run &lt;code&gt;npm install&lt;/code&gt;. This will install all the projects dependencies inside the container.&lt;/p&gt;

&lt;p&gt;Next, I can start the development server by running &lt;code&gt;gatsby develop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I get the message that I can now view my project in the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Local: http://localhost:8000/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Not so fast, my friend!
&lt;/h3&gt;

&lt;p&gt;However, when I go to localhost:8000 I get an &lt;code&gt;ERR_CONNECTION_RESET&lt;/code&gt;. I tried 127.0.0.1 instead but I still got nothing. If I list my running containers (with &lt;code&gt;docker ps&lt;/code&gt;), I see that it’s running on 0.0.0.0 and I thought that 0.0.0.0 was another way to say “127.0.0.1” or “localhost”… Why is it not working? &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BKVM98FS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f914.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BKVM98FS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f914.png" alt="🤔" width="72" height="72"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;└❯ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8a12a061be10 gatsby "/bin/bash" 10 minutes ago Up 2 minutes 0.0.0.0:8000-&amp;gt;8000/tcp my\_project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, it turns out that when running applications inside a container, &lt;code&gt;localhost&lt;/code&gt; is the container itself and not your workstation anymore. So you need to tell the container which host it should serve the application from. However, containers have dynamic IP addresses so you don’t know beforehand which IP address the container will take.&lt;/p&gt;

&lt;h3&gt;
  
  
  What do I do now?
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;fix for this problem&lt;/strong&gt; is to give the application a “placeholder” IP address. &lt;a href="https://superuser.com/questions/949428/whats-the-difference-between-127-0-0-1-and-0-0-0-0"&gt;0.0.0.0 is that placeholder and it means “all IPV4 addresses in the local machine”&lt;/a&gt;. In this case:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gatsby develop --H 0.0.0.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, the message is different:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Local: http://localhost:8000/ On Your Network: http://172.17.0.2:8000/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And both these addresses now serve my project! &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bVxLcVlF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f60a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bVxLcVlF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f60a.png" alt="😊" width="72" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So this is it. I can now change my code and see the changes on the browser just fine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Another option
&lt;/h3&gt;

&lt;p&gt;If you use &lt;a href="https://code.visualstudio.com/"&gt;VSCode&lt;/a&gt; as your editor, it has now an extension called “Remote – Containers” that will open your repository inside a Docker container for you (no need to build the image) and allow you to manage the container from its own UI. Note that you still need Docker installed locally for this extension to work.&lt;/p&gt;

&lt;p&gt;One thing to note is that it’s possible to manage the port exposing through VSCode and using this project as a test, I did not need to specify any host for my development server command. The extension provides a way to expose the ports (select the one the project is running on, right-click and “forward the port”):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ALOaDIB4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://testfbdotblog.files.wordpress.com/2020/09/port_forwarded.png%3Fw%3D417" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ALOaDIB4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://testfbdotblog.files.wordpress.com/2020/09/port_forwarded.png%3Fw%3D417" alt="" width="417" height="286"&gt;&lt;/a&gt;Port forwarding in Remote-Containers in VSCode&lt;/p&gt;

&lt;p&gt;The project is now accessible on 127.0.0.1:8000 in the browser.&lt;/p&gt;

&lt;p&gt;For more information on using the VSCode Remote Containers extension I recommend &lt;a href="https://css-tricks.com/a-gentle-introduction-to-using-a-docker-container-as-a-dev-environment/"&gt;this excellent article&lt;/a&gt;, that goes into a lot more detail than I did!&lt;/p&gt;

&lt;p&gt;I hope this post helps you keep your development environment organized.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;If you found this helpful, let me know on &lt;a href="https://twitter.com/FlaSustenido"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The post&lt;/em&gt; &lt;a href="https://wp.me/pa0b0y-8d"&gt;Developing inside a Docker container&lt;/a&gt; _was originally published at _&lt;a href="https://flaviabastos.ca/"&gt;flaviabastos.ca&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>commandline</category>
      <category>howto</category>
      <category>javascript</category>
      <category>devenvironment</category>
    </item>
    <item>
      <title>How to permit nested parameters in Rails</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Wed, 30 Sep 2020 08:28:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/how-to-permit-nested-parameters-in-rails-20cj</link>
      <guid>https://dev.to/flaviabastos/how-to-permit-nested-parameters-in-rails-20cj</guid>
      <description>&lt;h3&gt;
  
  
  The context
&lt;/h3&gt;

&lt;p&gt;Rails 5 introduced a big change in how it handles &lt;code&gt;ActionController::Parameters&lt;/code&gt; (the parameters that you get on your Controllers): before Rails 5, if you called your params you would get a hash back and after Rails 5, you get a &lt;code&gt;ActionController::Parameters&lt;/code&gt; object. You can see that by calling &lt;code&gt;params.inspect&lt;/code&gt; and if you call &lt;code&gt;.to_h&lt;/code&gt; on these parameters you should be good to go.&lt;/p&gt;

&lt;p&gt;However, you might get an empty hash when calling &lt;code&gt;.to_h&lt;/code&gt; on some parameters because they were not explicitly permitted – see the result of inspecting my params (note the “permitted: false” at the very end):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ActionController::Parameters {"friends" =&amp;gt; {"park" =&amp;gt; "Doggoland", "dogs"=&amp;gt;[{"id"=&amp;gt;73, "name"=&amp;gt;"Milou", "household"=&amp;gt;"Tintin"}, {"id"=&amp;gt;74, "name"=&amp;gt;"Snoopy", "household"=&amp;gt;"Charlie Brown"}]}} permitted: false&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Permitting params was showing up back in Rails 4 when Strong Parameters were introduced as part of security features and &lt;a href="https://eileencodes.com/posts/actioncontroller-parameters-now-returns-an-object-instead-of-a-hash/"&gt;this blog post goes through some examples&lt;/a&gt; of why just calling &lt;code&gt;.to_h&lt;/code&gt; might be an issue now that Rails 5 returns objects instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Permitting parameters
&lt;/h3&gt;

&lt;p&gt;One good way to permit some parameters is by creating a private helper function in your controller that will explicitly permit the parameters you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private def nice\_params params.permit(:id, :name, :email).to\_h end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When accessing your params, instead of &lt;code&gt;params[:name],&lt;/code&gt; you use &lt;code&gt;nice_params[:name]&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Permitting nested parameters
&lt;/h3&gt;

&lt;p&gt;Things get a little more complicated when you have a nested data structure. &lt;a href="https://api.rubyonrails.org/classes/ActionController/StrongParameters.htmlhttps://api.rubyonrails.org/classes/ActionController/StrongParameters.html"&gt;The documentation only gets one level deep&lt;/a&gt; and I had something more complicated than that. Let’s use the following as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"friends" =&amp;gt; { "park" =&amp;gt; "Doggoland", "dogs"=&amp;gt;[{"id"=&amp;gt;73, "name"=&amp;gt;"Milou", "household"=&amp;gt;"Tintin"}, {"id"=&amp;gt;74, "name"=&amp;gt;"Snoopy", "household"=&amp;gt;"Charlie Brown"}] } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My nice_params function 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;def nice\_params params.permit( friends: [:park, dogs: [:id, :name, :household]] ).to\_h end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One very important thing to notice is that the nested list must be placed last!&lt;/p&gt;

&lt;p&gt;I hope this helps someone else with deep nested params. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z5VYj9Ua--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f605.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z5VYj9Ua--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f605.png" alt="😅" width="72" height="72"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;If you found this helpful, let me know on &lt;a href="https://twitter.com/FlaSustenido"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The post&lt;/em&gt; &lt;a href="https://wp.me/pa0b0y-7V"&gt;How to permit nested parameters in Rails&lt;/a&gt;_ was originally published at _&lt;a href="https://flaviabastos.ca/"&gt;flaviabastos.ca&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>howto</category>
      <category>rails</category>
    </item>
    <item>
      <title>5 razões pra começar a aprender JavaScript</title>
      <dc:creator>Flávia Bastos</dc:creator>
      <pubDate>Wed, 16 Sep 2020 11:25:00 +0000</pubDate>
      <link>https://dev.to/flaviabastos/5-razoes-pra-comecar-a-aprender-javascript-3if1</link>
      <guid>https://dev.to/flaviabastos/5-razoes-pra-comecar-a-aprender-javascript-3if1</guid>
      <description>&lt;p&gt;Se você já programa há algum tempo e não sabe JavaScript ou se está pensando em aprender a programar e não sabe por onde começar, aqui está a minha lista de motivos porque eu acho que você deveria aprender JavaScript (ou simplesmente “JS” no resto desse post):&lt;/p&gt;

&lt;h2&gt;
  
  
  JS é o que faz a internet ser interativa
&lt;/h2&gt;

&lt;p&gt;Antes de JS, a internet era meio sem-graça: um monte de texto, uns links e olhe lá umas imagens com animação. JS mudou tudo e passou a oferecer uma experiência muito mais interativa pros usuários. Sabe a tela de login do seu email ou do acesso ao site do banco? Então, tem JS pra você clicar no botão e ir pra outra página. E quando você vai preencher um formulário e os campos já vão sugerindo o resto do text? É o JS que faz isso.&lt;br&gt;&lt;br&gt;
Só pra deixar claro, existem outras maneiras de se implementar as funcionalidades que eu descrevi aí mas na maioria das vezes quem está fazendo esse trabalho é o JS. E pra ser bem sincera, hoje em dia é quase impossível navegar na internet sem usar nada de JS….&lt;/p&gt;
&lt;h2&gt;
  
  
  Não precisa instalar nada pra começar
&lt;/h2&gt;

&lt;p&gt;Uma coisa que eu acho bem legal é que como JS é basicamente a “língua oficial” da internet, você não precisa instalar nada no seu computador pra começar a usar e aprender JS. O seu navegador já é suficiente! Aqui sugiro 3 opções, da mais simples pra mais “complicada” (que daí vai precisar instalar ferramentas pra te ajudar a escrever código):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use o &lt;a href="https://www.javascript.com/try"&gt;site de JavaScript do Pluralsight&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;abra uma nova aba no seu navegador e aperte as teclas &lt;code&gt;CTRL + SHIFT + I&lt;/code&gt;. Esse é o atalho pra abrir o “Developer Tools” (“Ferramentas de desenvolvimento” numa tradução livre) no Chrome ou no Firefox ( &lt;strong&gt;acho&lt;/strong&gt; que funciona em outros navegadores mas não tenho certeza). Clique em “Console” e o painel vai parecer o seguinte (estou mostrando no Chrome):&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VabbcmMN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://testfbdotblog.files.wordpress.com/2020/08/chrome_dev_tools.png%3Fw%3D932" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VabbcmMN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://testfbdotblog.files.wordpress.com/2020/08/chrome_dev_tools.png%3Fw%3D932" alt="" width="880" height="303"&gt;&lt;/a&gt;Ferramentas de desenvolvimento do Chrome&lt;/p&gt;

&lt;p&gt;Clique na linha onde tem o sinal de maior e escreva o seguinte (incluindo as aspas): “Ola mundo!”. Aperte &lt;code&gt;ENTER&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Parabéns, você acabou de escrever seu primeiro programa em JS. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hc4fuN-c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f389.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hc4fuN-c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f389.png" alt="🎉" width="72" height="72"&gt;&lt;/a&gt; O browser avaliou seu código e escreveu de volta o conteúdo. Esse caso é bem simples, claro, e não teve nenhum processamento mas dá pra fazer muitas outras coisas só nesse painel. Se quiser escrever uma função com linhas múltiplas, segure a tecla &lt;code&gt;SHIFT&lt;/code&gt; enquanto aperte o &lt;code&gt;ENTER&lt;/code&gt; pra inserir uma linha nova e não “executar” o console imediatamente.&lt;/p&gt;

&lt;p&gt;Com linhas múltiplas você pode começar a escrever coisas mais interessantes como por exemplo funções. Essa função aí em baixo usa uma lista de nomes e interage com cada nome, um de cada vez:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zrDf0oGj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://testfbdotblog.files.wordpress.com/2020/08/map_chrome_devtools.png%3Fw%3D935" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zrDf0oGj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://testfbdotblog.files.wordpress.com/2020/08/map_chrome_devtools.png%3Fw%3D935" alt="" width="880" height="316"&gt;&lt;/a&gt;Exemplo de função em JavaScript&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// código da tela:amigos = ["frodo", "sam", "pippin", "merry"]gritos = function gritando(arr) { return arr.map(nome =&amp;gt; nome.toUpperCase());}gritos(amigos)// depois da linha acima, o resultado na tela é:// (4) ["FRODO", "SAM", "PIPPIN", "MERRY"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Esse são exemplos bem simples mas é só pra mostrar o que dá pra fazer (e eu só sei o que tem escrever porque já usei muito JS e olhei na documentação; não dá pra saber de outra forma!)&lt;br&gt;&lt;br&gt;
Uma desvantagem do console é que não dá pra salvar nada. Fechou a janela do navegador, perdeu. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FGwvZdKv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f61e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FGwvZdKv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f61e.png" alt="😞" width="72" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a terceira opção é você usar um arquivo com extensão &lt;code&gt;.html&lt;/code&gt;(a “língua” de formatação da internet) e inserir o seu JS dentro dele. Por exemplo:&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Você pode simplesmente salvar esse arquivo com o nome que quiser, por exemplo, “exemplo.html” e abrir no navegador (clique em &lt;code&gt;CTRL + O&lt;/code&gt; — “o” maiúculo de “open”, “abrir” em inglês — e escolha o arquivo que acabou de salvar). O navegador vai mostrar só texto “Mensagem na tela” que é o que está no HTML na linha 20, mas pra você ver a mensagem do JS (linha 15), abra a ferramenta de desenvolvimento (&lt;code&gt;CTRL + SHIFT + I&lt;/code&gt;). Pra editar esse arquivo você provavelmente vai querer usar um editor de texto e embora seu computador deva ter algum instalado, eles não costumam ser indicados pra desenvolvimento. Outras opções incluem: &lt;a href="https://code.visualstudio.com/Download"&gt;VSCode&lt;/a&gt; ou &lt;a href="https://www.sublimetext.com/3"&gt;Sublime&lt;/a&gt; ou &lt;a href="https://atom.io/"&gt;Atom&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tem muito recurso gratuito disponível
&lt;/h2&gt;

&lt;p&gt;Se você sabe um pouco de inglês, tem muitas opções de materiais gratuitos para aprender JS. Dois dos meus favoritos são os seguintes (precisa criar conta pra acessar os dois, mas são grátis): &lt;a href="https://www.freecodecamp.org/"&gt;freeCodeCamp&lt;/a&gt; e o &lt;a href="https://javascript30.com/"&gt;JavaScript 30&lt;/a&gt; do &lt;a href="https://twitter.com/wesbos"&gt;Wes Bos&lt;/a&gt;. Em português tem a documentação do &lt;a href="https://developer.mozilla.org/pt-BR/docs/Aprender/Getting_started_with_the_web/JavaScript_basico"&gt;MDN&lt;/a&gt; mas eu realmente não conheço nenhum curso no momento pra recomendar.&lt;/p&gt;

&lt;h2&gt;
  
  
  A linguagem está em crescimento e oferece muita funcionalidade
&lt;/h2&gt;

&lt;p&gt;Esse é um ponto que muitas pessoas usam para criticar a linguagem: parece que todo dia tem uma ferramenta nova em JS. Embora isso seja um exagero, não está muito longe da verdade. Mas na minha opinião esse é um ponto positivo, pois conforme a linguagem vem crescendo, ela vai ocupando mais espaços na área de desenvolvimento pra web e hoje em dia é viável ser programador web sabendo só JS. Em conjunto com outras ferramentas do ecossistema (como &lt;a href="https://nodejs.org/en/"&gt;Node.js&lt;/a&gt; pra rodar do lado do servidor e &lt;a href="https://reactjs.org/"&gt;React.js&lt;/a&gt; pra fazer a interação com o usuário), dá pra escrever aplicações completas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dá pra fazer fazer coisas bem legais!
&lt;/h2&gt;

&lt;p&gt;Voltando um pouco ao primeiro ponto, a maioria do que você conhece da internet que permite você interagir com o conteúdo de um site, tem JS envolvido. Tem até aplicação feita 100% em JS: um exemplo é &lt;a href="https://www.youtube.com/watch?v=toNFfAaWghU&amp;amp;list=PLu8EoSxDXHP6CGK4YVJhL_VWetA865GOH&amp;amp;index=31&amp;amp;t=0s"&gt;esse joguinho escrito só com JS que o Wes Bos ensina no curso&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=toNFfAaWghU&amp;amp;list=PLu8EoSxDXHP6CGK4YVJhL_VWetA865GOH&amp;amp;index=31&amp;amp;t=0s"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--teo4HQXk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://testfbdotblog.files.wordpress.com/2020/07/whackamole.png%3Fw%3D288" alt="Imagem de um jogo chamado whackamole" width="288" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então resumindo, se você quer começar a aprender a programar, JS é uma ótima opção pra começar. Se você já programa em outras linguagens mas tem aquele preconceito com JS, tá na hora de superar isso aí. A internet só está evoluindo. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zCyXRrdx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zCyXRrdx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png" alt="🙂" width="72" height="72"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Se você tem perguntas ou sugestões, me conta &lt;a href="https://twitter.com/FlaSustenido"&gt;lá no Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O post “&lt;a href="https://wp.me/pa0b0y-74"&gt;5 razões pra começar a aprender JavaScript&lt;/a&gt;” foi publicado originalmente no blog flaviabastos.ca&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>iniciante</category>
      <category>ptbr</category>
    </item>
  </channel>
</rss>
