<?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: João Maranhão</title>
    <description>The latest articles on DEV Community by João Maranhão (@joaomaranhao).</description>
    <link>https://dev.to/joaomaranhao</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%2F355163%2F5708f641-7701-45f3-ace1-0993b6acb360.jpg</url>
      <title>DEV Community: João Maranhão</title>
      <link>https://dev.to/joaomaranhao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joaomaranhao"/>
    <language>en</language>
    <item>
      <title>Moving Away from Debian, Trying WSL, and Coming Back to Linux the Right Way</title>
      <dc:creator>João Maranhão</dc:creator>
      <pubDate>Thu, 15 May 2025 03:24:39 +0000</pubDate>
      <link>https://dev.to/joaomaranhao/moving-away-from-debian-trying-wsl-and-coming-back-to-linux-the-right-way-2ea1</link>
      <guid>https://dev.to/joaomaranhao/moving-away-from-debian-trying-wsl-and-coming-back-to-linux-the-right-way-2ea1</guid>
      <description>&lt;p&gt;In the past few days, I switched distros. Again. But this time it was different. Not because of hype or testing the “latest cool thing.” It was necessity. My laptop running Debian was freezing, shutting down randomly, and to top it off, I had to disable IPv6 just to get &lt;code&gt;pip&lt;/code&gt; or any Python requests to work without timeouts. Terrible experience.&lt;/p&gt;

&lt;p&gt;So I thought: &lt;strong&gt;I'll try Windows 11 with WSL&lt;/strong&gt;. Fine, no more freezes, IPv6 worked, but WSL started consuming more RAM than it should, and the system got weird with many open tabs. Flickering screen, slowdowns... and I have 20GB RAM.&lt;/p&gt;

&lt;p&gt;Then the thought came: &lt;strong&gt;Back to Linux?&lt;/strong&gt; Yeah, but this time I wanted something polished. Something that just works out of the box, no juggling with drivers, no tweaking terminal transparency or fixing Gnome tray issues. I’ve used Fedora, Arch, Ubuntu, Debian... all gave me some headaches at some point.&lt;/p&gt;

&lt;p&gt;So I tested &lt;strong&gt;Linux Mint with Cinnamon&lt;/strong&gt;. And man, &lt;strong&gt;it was a pleasant surprise&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cinnamon: Looks like Gnome, but actually works
&lt;/h2&gt;

&lt;p&gt;I’ve always liked the idea of Gnome, but in practice, I had to fix a thousand things. On Mint + Cinnamon, everything I used to “fix” was already working:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transparent terminal&lt;/li&gt;
&lt;li&gt;Functional tray&lt;/li&gt;
&lt;li&gt;125% screen scaling without hacks&lt;/li&gt;
&lt;li&gt;Flatpak + Flathub installed and ready&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Best part: &lt;strong&gt;no freezes&lt;/strong&gt;. No fuss. Felt like a ready-to-go system.&lt;/p&gt;




&lt;h2&gt;
  
  
  The game changer: less PPAs, more Flatpak
&lt;/h2&gt;

&lt;p&gt;I’ve always been systematic about setups. But I learned an important lesson coming back to Linux:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;The less you mess with APT, the more stable it gets.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My current approach is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GUI apps?&lt;/strong&gt; Flatpak.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminal tools?&lt;/strong&gt; APT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Languages?&lt;/strong&gt; Managed via &lt;code&gt;asdf&lt;/code&gt;, keeping the system clean.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps my &lt;code&gt;apt update&lt;/code&gt; fast, the system clean and easy to maintain.&lt;br&gt;&lt;br&gt;
I avoid adding PPAs whenever possible. They slow down updates, break on distro upgrades, and have caused headaches before.&lt;/p&gt;




&lt;h2&gt;
  
  
  What about smaller or less “mainstream” distros?
&lt;/h2&gt;

&lt;p&gt;I used to be wary of distros outside the “big four” — Fedora, Debian, Arch, Ubuntu... But now I see that’s just nonsense.&lt;/p&gt;

&lt;p&gt;What really changes between distros is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;package manager&lt;/strong&gt; (and its speed)&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;out-of-the-box experience&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;level of polish&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;How much they &lt;strong&gt;respect your time&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here Mint impressed me. It nails exactly what others miss: delivering a polished, ready-to-use system with sensible defaults.&lt;/p&gt;

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

&lt;p&gt;If you’ve gone through the distro-hopping phase and want &lt;strong&gt;a system that just works&lt;/strong&gt;, no freezes, no driver hassle, no daily desktop fixes, give &lt;strong&gt;Linux Mint with Cinnamon&lt;/strong&gt; a try.&lt;/p&gt;

&lt;p&gt;Using Flatpak + APT wisely + language managers like &lt;code&gt;asdf&lt;/code&gt; gives you control, lightness, and stability. The system stays clean, fast, and predictable.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>Refactoring Is About Clarity. Clarity Builds Confidence. Confidence Scales.</title>
      <dc:creator>João Maranhão</dc:creator>
      <pubDate>Tue, 08 Apr 2025 20:16:46 +0000</pubDate>
      <link>https://dev.to/joaomaranhao/refactoring-is-about-clarity-clarity-builds-confidence-confidence-scales-2jjn</link>
      <guid>https://dev.to/joaomaranhao/refactoring-is-about-clarity-clarity-builds-confidence-confidence-scales-2jjn</guid>
      <description>&lt;p&gt;When we start programming, all we care about is making it work.&lt;br&gt;&lt;br&gt;
But as the codebase grows, the game changes. Maintaining and evolving messy code drains energy and kills products.&lt;/p&gt;

&lt;p&gt;It’s not about rules. It’s about decisions.&lt;/p&gt;

&lt;p&gt;Here are some insights I carry with me — with simple Python examples. Practical. Clear. The way I wish I had learned them from the beginning.&lt;/p&gt;


&lt;h2&gt;
  
  
  💡 1. Duplicated Code Is Always a Sign
&lt;/h2&gt;

&lt;p&gt;If you're copying and pasting with small changes... refactoring is calling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_monthly_salary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hours_worked&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hourly_rate&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hours_worked&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;hourly_rate&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_overtime_salary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;overtime_hours&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hourly_rate&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;overtime_hours&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;hourly_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hourly_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;multiplier&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;hourly_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;multiplier&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See the clarity? One single point of change. Explicit rule. Now the code becomes a tool — not a riddle.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 2. Bad Names Are Invisible Debt
&lt;/h2&gt;

&lt;p&gt;Ever opened a function and thought, &lt;em&gt;"WTF does this do?"&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Yeah, we've all been there.&lt;/p&gt;

&lt;p&gt;Renaming is refactoring. And you don’t have to be a genius — just descriptive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;prc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;apply_discount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;percent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;percent&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tell me: which one makes sense instantly?&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 3. Long Functions Are Productivity Traps
&lt;/h2&gt;

&lt;p&gt;100-line functions aren’t power skills. They’re ticking time bombs.&lt;br&gt;&lt;br&gt;
Refactoring here means &lt;strong&gt;extracting responsibilities into new methods&lt;/strong&gt;. That’s the gold.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# validation
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Empty order.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid total.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# calculation
&lt;/span&gt;    &lt;span class="n"&gt;tax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;
    &lt;span class="n"&gt;total_with_tax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tax&lt;/span&gt;

    &lt;span class="c1"&gt;# sending
&lt;/span&gt;    &lt;span class="nf"&gt;send_confirmation_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;total_with_tax&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;validate_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculate_total_with_tax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;send_confirmation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Empty order.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid total.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_total_with_tax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean, readable, testable.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 4. Refactoring Works Better With Tests
&lt;/h2&gt;

&lt;p&gt;Refactoring without tests is like changing tires while the car is moving.&lt;br&gt;&lt;br&gt;
You &lt;em&gt;can&lt;/em&gt; do it — but you really shouldn’t.&lt;/p&gt;

&lt;p&gt;Before any major refactor, write a test to &lt;em&gt;freeze the current behavior&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Then change everything under the hood — and make sure it still runs the same from the outside.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 5. “Make It Work First. Then Make It Right.”
&lt;/h2&gt;

&lt;p&gt;This quote follows me daily. Refactoring is about &lt;strong&gt;postponing structural decisions&lt;/strong&gt; until you have more context.&lt;br&gt;&lt;br&gt;
Not procrastination — just better timing.&lt;/p&gt;

&lt;p&gt;So: made it work? Great.&lt;br&gt;&lt;br&gt;
Now clean the trail.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Refactoring is an act of respect.&lt;br&gt;&lt;br&gt;
For those maintaining your code. For those building on top of it. For yourself three months from now.&lt;/p&gt;

&lt;p&gt;You don’t need a sprint.&lt;br&gt;&lt;br&gt;
You don’t need permission.&lt;br&gt;&lt;br&gt;
You just need to realize refactoring is &lt;strong&gt;not extra work&lt;/strong&gt; — it’s part of the craft.&lt;/p&gt;

&lt;p&gt;Wanna talk code, AI or automation? Hit me up on &lt;a href="https://linkedin.com/in/joaofmaranhao" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or check out my projects on &lt;a href="https://github.com/joaomaranhao" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. Let's level up together.&lt;/p&gt;




</description>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Simplifying Python Development: A Step-by-Step Guide to Setting up a Python Project with Git and GitHub</title>
      <dc:creator>João Maranhão</dc:creator>
      <pubDate>Wed, 11 Jan 2023 13:41:55 +0000</pubDate>
      <link>https://dev.to/joaomaranhao/simplifying-python-development-a-step-by-step-guide-to-setting-up-a-python-project-with-git-and-github-1cll</link>
      <guid>https://dev.to/joaomaranhao/simplifying-python-development-a-step-by-step-guide-to-setting-up-a-python-project-with-git-and-github-1cll</guid>
      <description>&lt;p&gt;The purpose of this article is to provide a clear path and understanding of how you would set up a Python environment on your machine.&lt;/p&gt;

&lt;p&gt;Keep in mind that the following content is written thinking on a Linux environment. If you use another OS, make the necessary changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Python
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install pyenv
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/pyenv/pyenv#simple-python-version-management-pyenv" rel="noopener noreferrer"&gt;GitHub - pyenv/pyenv: Simple Python version management&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This allows you to simply choose the Python version you want to use. It allows you to set the global version for the system or a local version for specific projects or directories.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use &lt;code&gt;pyenv&lt;/code&gt; to install Python
&lt;/h3&gt;

&lt;p&gt;Once &lt;code&gt;pyenv&lt;/code&gt; is installed, you can use it to install the version of Python you want to use.&lt;/p&gt;

&lt;p&gt;You can also use &lt;strong&gt;&lt;code&gt;pyenv local&lt;/code&gt;&lt;/strong&gt; command to set a local version of Python for a specific directory, this way you can have a different version of Python for different projects.&lt;/p&gt;

&lt;p&gt;To test your installation, you can open a terminal and run the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This should print the version of Python you have installed, which should be the version you set using &lt;strong&gt;&lt;code&gt;pyenv&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Install pip&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/strong&gt; is a package manager for Python that makes it easy to install and manage packages. It is included with Python 3.4 and later, so you don't need to install it separately.&lt;/p&gt;

&lt;p&gt;If your python version is less than 3.4 then you need to install pip separately&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Create and activate a virtual environment&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A virtual environment is an isolated environment where you can install packages without interfering with the system-wide packages. To create a virtual environment, you can use the &lt;strong&gt;&lt;code&gt;venv&lt;/code&gt;&lt;/strong&gt; package.&lt;/p&gt;

&lt;p&gt;In your project’s directory, run the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This will create a new directory called &lt;code&gt;venv&lt;/code&gt; on your current working directory, where you can install your packages.&lt;/p&gt;

&lt;p&gt;To activate your virtual environment, you need to run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your virtual environment is active, you should see the name of the environment in the terminal prompt, indicating that it is active. Any packages you install while the environment is active will be installed in the &lt;strong&gt;&lt;code&gt;venv&lt;/code&gt;&lt;/strong&gt; directory and will not affect other projects or your system Python installation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Git to manage your project
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install Git
&lt;/h3&gt;

&lt;p&gt;The process to install Git on Linux can vary depending on the distribution you are using. You can use the package manager specific to your distribution to install Git.&lt;/p&gt;

&lt;p&gt;For example, on Ubuntu or Debian, you can use the &lt;strong&gt;&lt;code&gt;apt-get&lt;/code&gt;&lt;/strong&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Fedora or CentOS, you can use the &lt;strong&gt;&lt;code&gt;yum&lt;/code&gt;&lt;/strong&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once Git is installed, you can check its version running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should print the version of Git installed on your machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start a local Git repository
&lt;/h3&gt;

&lt;p&gt;To start a local Git repository for your project, you can follow these steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a new &lt;strong&gt;&lt;code&gt;.git&lt;/code&gt;&lt;/strong&gt; directory in your project, which will store all the information about your repository, such as the history of commits and the current state of the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Python’s &lt;code&gt;.gitgnore&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;You can download Python’s .gitignore from Github by entering this command on your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore &lt;span class="nt"&gt;-O&lt;/span&gt; .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can stage and commit the &lt;strong&gt;&lt;code&gt;.gitignore&lt;/code&gt;&lt;/strong&gt; file to our local repository by running these commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add .gitignore
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"chore: add .gitignore"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's also a good practice to review the contents of the .gitignore file downloaded from Github and modify it as per your specific use case.&lt;/p&gt;

&lt;p&gt;You can also add additional files or directories that you want to ignore in your project by modifying the contents of the &lt;strong&gt;&lt;code&gt;.gitignore&lt;/code&gt;&lt;/strong&gt; file and then committing the changes to the repository. This way, you can ensure that the files you want to ignore are consistently excluded from your Git repository in all branches.&lt;/p&gt;

&lt;p&gt;You can use conventional commits in your Git repository to make it easier to understand and track the changes that have been made to the code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;Conventional Commits&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Install &lt;code&gt;black&lt;/code&gt; to code formatting
&lt;/h3&gt;

&lt;p&gt;Black can be installed by running &lt;code&gt;pip install black&lt;/code&gt;. It requires Python 3.7+ to run.&lt;/p&gt;

&lt;h4&gt;
  
  
  VS Code
&lt;/h4&gt;

&lt;p&gt;If you use VS Code, you can add to your configuration file the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"python.formatting.provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"black"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"editor.formatOnSave"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don’t forget to also install the recommended Python extensions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a &lt;code&gt;requirements.txt&lt;/code&gt; file
&lt;/h3&gt;

&lt;p&gt;To create a &lt;strong&gt;&lt;code&gt;requirements.txt&lt;/code&gt;&lt;/strong&gt; file, you can use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a file called &lt;strong&gt;&lt;code&gt;requirements.txt&lt;/code&gt;&lt;/strong&gt; in the current directory and list all the packages with versions that are installed in your environment.&lt;/p&gt;

&lt;p&gt;Add the &lt;strong&gt;&lt;code&gt;requirements.txt&lt;/code&gt;&lt;/strong&gt; file to the repository by running &lt;strong&gt;&lt;code&gt;git add requirements.txt&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Commit the file to the repository by running &lt;strong&gt;&lt;code&gt;git commit -m "chore: add requirements.txt"&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a GitHub repository
&lt;/h2&gt;

&lt;p&gt;Go to the GitHub website (&lt;strong&gt;&lt;a href="https://github.com/" rel="noopener noreferrer"&gt;https://github.com/&lt;/a&gt;&lt;/strong&gt;) and sign in to your account.&lt;/p&gt;

&lt;p&gt;Click on the "+" button in the top right corner of the page, and select "New repository" from the menu. Give a name to your repository and an optional description and choose whether you want your repository to be public or private.&lt;/p&gt;

&lt;p&gt;Add the remote repository on GitHub using the command:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;git remote add origin git@github.com:yourusername/easy_python_project.git&lt;/code&gt;&lt;/strong&gt;, replace &lt;strong&gt;&lt;code&gt;yourusername&lt;/code&gt;&lt;/strong&gt; with your github username.&lt;/p&gt;

&lt;p&gt;Finally, push your local repository to the newly created GitHub repository by running:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;git push -u origin main&lt;/code&gt;&lt;/strong&gt; or any other branch name you want to push.&lt;/p&gt;

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

&lt;p&gt;In conclusion, setting up a Python project with Git and GitHub is relatively easy to do.&lt;/p&gt;

&lt;p&gt;By following the steps outlined in this article, you'll be able to set up a clean and organized environment for your Python projects, regardless of the operating system you're using.&lt;/p&gt;

&lt;p&gt;The important thing to keep in mind is to review the steps and make any necessary adjustments depending on the operating system you are using.&lt;/p&gt;

&lt;p&gt;If you have any questions, suggestions or just want to say hi, feel free to reach out to me!&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://twitter.com/joaofmaranhao" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What is Poetry? And why you should use it?</title>
      <dc:creator>João Maranhão</dc:creator>
      <pubDate>Thu, 05 Jan 2023 23:56:56 +0000</pubDate>
      <link>https://dev.to/joaomaranhao/what-is-poetry-and-why-you-should-use-it-1g99</link>
      <guid>https://dev.to/joaomaranhao/what-is-poetry-and-why-you-should-use-it-1g99</guid>
      <description>&lt;p&gt;If you're a Python developer, you've probably heard of this tool for managing your Python projects. But, in case you still don't know it, I'll explain a little more about what it is and why it's worth adopting.&lt;/p&gt;

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

&lt;p&gt;Poetry is a package and dependency manager for Python projects. It was created to make the project management process easier and more enjoyable, allowing you to easily create and publish your packages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Poetry?
&lt;/h2&gt;

&lt;p&gt;Now that you know what Poetry is, I'm going to talk about some of the reasons why it might be useful for you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ease of use: It is very easy to use and has an intuitive interface. This means that even if you are new to the Python language, you will be able to use Poetry without too much difficulty.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dependency Management: This allows you to easily manage your project's dependencies, ensuring that you always have the correct versions of the libraries you need. This can save you a lot of time and frustration over the course of your project development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better Project Organization: This helps you organize your project in a clearer and more structured way. This can be especially useful if you are working on a large or complex project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easy Publishing: Makes it very easy to publish your Python packages to PyPI (Python Package Index). This means you can easily share your project with other developers and let them use it in their projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, Poetry is an amazing tool for any Python developer who wants to make project management easier and more enjoyable. If you're not already using it in your projects, I recommend checking it out and seeing how it can simplify your life.&lt;/p&gt;

</description>
      <category>oracle</category>
    </item>
    <item>
      <title>Building a Saas in public with Typescript!</title>
      <dc:creator>João Maranhão</dc:creator>
      <pubDate>Fri, 19 Aug 2022 00:03:51 +0000</pubDate>
      <link>https://dev.to/joaomaranhao/building-a-saas-in-public-with-typescript-2b07</link>
      <guid>https://dev.to/joaomaranhao/building-a-saas-in-public-with-typescript-2b07</guid>
      <description>&lt;p&gt;Hey there, I’m starting today a project where I’m gonna build a Saas in public and document it.&lt;/p&gt;

&lt;p&gt;If you want to follow me on that project, I’ll be doing live coding streams on Twitch.&lt;/p&gt;

&lt;p&gt;You can check out the schedule of those live streams on my &lt;a href="https://www.twitch.tv/joaofmaranhao/about" rel="noopener noreferrer"&gt;Twitch channel&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;I’ll also update that project here on &lt;a href="http://Dev.to" rel="noopener noreferrer"&gt;Dev.to&lt;/a&gt;, so feel free to follow me and interact as you wish!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the project?
&lt;/h2&gt;

&lt;p&gt;The project is an application to manage veterinary clinics.&lt;br&gt;
Users should be able to create appointments, register clients, and more.&lt;/p&gt;

&lt;p&gt;The goal here is to make an MVP as soon as I can, so I can validate it with clients.&lt;/p&gt;

&lt;p&gt;Keep in mind that, the business rules will be updated as needed.&lt;br&gt;
Here is the first concept of the project backend:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsb02w0a90r436xu39mvy.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsb02w0a90r436xu39mvy.JPG" alt="Database UML and Business rules" width="800" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What tools I’m gonna use?
&lt;/h2&gt;

&lt;p&gt;Some of you guys, are following me because of my project where I created a script to automate the content creation of an Youtube channel with Python. (If you don’t know what I’m talking about, you can check out the text &lt;a href="https://dev.to/joaomaranhao/how-i-used-python-to-automate-a-youtube-channel-ph0"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;But for this project here, I’m going to use a different selection of tools.&lt;/p&gt;

&lt;p&gt;The stack that I choose for that project is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typescript&lt;/li&gt;
&lt;li&gt;NodeJS (Nest, Prisma)&lt;/li&gt;
&lt;li&gt;Postgres&lt;/li&gt;
&lt;li&gt;ReactJS (Next)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, if you want to learn about those topics, this is a perfect oportunity to see how this works, and how to get an idea off the ground.&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://twitter.com/joaofmaranhao" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Check out my &lt;a href="https://www.twitch.tv/joaofmaranhao/about" rel="noopener noreferrer"&gt;Twitch channel&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Take a look at my &lt;a href="https://www.github.com/joaomaranhao" rel="noopener noreferrer"&gt;Github&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>node</category>
      <category>saas</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What kind of jobs should I apply with this portfolio?</title>
      <dc:creator>João Maranhão</dc:creator>
      <pubDate>Tue, 19 Jul 2022 23:44:54 +0000</pubDate>
      <link>https://dev.to/joaomaranhao/what-kind-of-jobs-should-i-apply-with-this-portfolio-574f</link>
      <guid>https://dev.to/joaomaranhao/what-kind-of-jobs-should-i-apply-with-this-portfolio-574f</guid>
      <description>&lt;p&gt;Since my last article was so successful, I would like to ask you what area would this project fall into?&lt;/p&gt;

&lt;p&gt;For those who haven't seen the article, here's the link:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/joaomaranhao" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ox-hqbXy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--0DJMU3YN--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/355163/637e334f-14a4-4131-a6c6-5daade0b5d24.jpg" alt="joaomaranhao"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/joaomaranhao/how-i-used-python-to-automate-a-youtube-channel-ph0" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How I Used Python to Automate a Youtube Channel&lt;/h2&gt;
      &lt;h3&gt;João Maranhão ・ Jul 16 ・ 4 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#python&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;I'm looking for my first job as a software developer, I'm applying for front-end, back-end jobs, but this project specifically doesn't fit exactly into any of these areas.&lt;/p&gt;

&lt;p&gt;I have a few other projects I've done, including my personal website.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://www.joaomaranhao.com.br/" rel="noopener noreferrer"&gt;
      joaomaranhao.com.br
    &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;I'm studying both front-end and back-end, I like both.&lt;/p&gt;

&lt;p&gt;I would like your opinion about my portfolio, is it good for a first job?&lt;/p&gt;

&lt;p&gt;I know I need to do more projects, and I'm already doing it, but I'd like feedback.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>help</category>
      <category>career</category>
    </item>
    <item>
      <title>How I Used Python to Automate a Youtube Channel</title>
      <dc:creator>João Maranhão</dc:creator>
      <pubDate>Sat, 16 Jul 2022 18:58:36 +0000</pubDate>
      <link>https://dev.to/joaomaranhao/how-i-used-python-to-automate-a-youtube-channel-ph0</link>
      <guid>https://dev.to/joaomaranhao/how-i-used-python-to-automate-a-youtube-channel-ph0</guid>
      <description>&lt;p&gt;When I started coding, the first thing I did to put my new knowledge into practice was to automate a process that was done every day at my job.&lt;/p&gt;

&lt;p&gt;I worked with video editing and, at least once a day, I had to download a media with the recordings to a backup server and then pull them to my machine to start editing. So, I decided to create a script that would do this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why automate?
&lt;/h2&gt;

&lt;p&gt;By automating everyday processes, it was as if I was “gaining” time. If a daily task that takes 5 minutes to do is automated, in 5 business days, you will have 25 minutes more to do something else. In a month, 1 hour and 40 minutes; in a year, 20 hours…Multiply that by more tasks or users and you have considerable numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  How did the inspiration come about?
&lt;/h2&gt;

&lt;p&gt;Studying JavaScript, I watched a series of videos from &lt;a href="https://www.youtube.com/watch?v=kjhu1LEmRpY&amp;amp;list=PLMdYygf53DP4YTVeu0JxVnWq01uXrLwHi&amp;amp;ab_channel=FilipeDeschamps" rel="noopener noreferrer"&gt;Fillipe Deschamps&lt;/a&gt;, where he teaches how to create a YouTube channel that generates content programmatically.&lt;/p&gt;

&lt;p&gt;In short, he accesses a Wikipedia article to get the information that will be used in the video; uses IBM's Watson artificial intelligence to “break” text into sentences; the Google API to fetch images to illustrate the video; ImageMagick to process the photos and create the thumbnail; Adobe After Effects to edit the video, and finally the Youtube API to upload.&lt;/p&gt;

&lt;p&gt;I followed the series and made this project. In the end, I added some extra functionality like generating audio for each sentence with the Text-to-Speech API, also from IBM's Watson, and adding them to the video.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the project
&lt;/h2&gt;

&lt;p&gt;The idea was to create a YouTube channel with replays of matches of a very popular game called “League of Legends”, fully automated.&lt;/p&gt;

&lt;p&gt;Some sites make matches of professional players available for download. Replays are executable files that run the game.&lt;/p&gt;

&lt;p&gt;To automate the entire creation process, a few steps were necessary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter the website, choose a match, get the match information and download the replay&lt;/li&gt;
&lt;li&gt;Run replay and record screen&lt;/li&gt;
&lt;li&gt;Edit the video&lt;/li&gt;
&lt;li&gt;Create the thumbnail&lt;/li&gt;
&lt;li&gt;Upload the video and thumbnail to Youtube and fill in information like title, description, and keywords&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Python?
&lt;/h2&gt;

&lt;p&gt;As I was more familiar with Javascript having already used it in other projects, it would be the obvious choice, but I had a problem, I needed to run the game and configure some things when the game started. For that, I needed to control the mouse and keyboard programmatically.&lt;/p&gt;

&lt;p&gt;I looked for some Javascript library that would help me to do this, but I was not successful. That's when I remembered one in Python, which is called PyAutoGUI. So, I decided to do everything in Python! In addition to having everything I needed, it was a chance to perfect myself in another language.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it was implemented
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Web scrapping
&lt;/h3&gt;

&lt;p&gt;Web scraping is a method of accessing any website and getting information.&lt;/p&gt;

&lt;p&gt;What I used to search for matches was &lt;a href="https://www.leagueofgraphs.com/" rel="noopener noreferrer"&gt;League of Graphs&lt;/a&gt; and, through &lt;a href="https://www.leagueofgraphs.com/replays/with-high-%20kda/grandmaster/sr-ranked" rel="noopener noreferrer"&gt;this link&lt;/a&gt;, I can access a page with replays and filter my search, to get only matches with good players.&lt;/p&gt;

&lt;p&gt;The idea here was to take the first game and extract the information from this table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjaynmn2q931t3et0aolq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjaynmn2q931t3et0aolq.png" alt="https://raw.githubusercontent.com/joaomaranhao/video-maker/main/docs/images/match.png" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Among the many Python options to accomplish this task, I chose Selenium because it has the functionality to interact with the site. The library lets you click to download the game.&lt;/p&gt;

&lt;p&gt;I created a Python dictionary with all the information I needed and saved it in a JSON file, in a folder called “assets”, at the root of the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thumbnail
&lt;/h3&gt;

&lt;p&gt;To create the thumbnail, I developed a template with HTML and CSS. With the JSON information, the data is dynamically filled and an HTML file is saved in the “assets” folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;assets&lt;/span&gt;
&lt;span class="n"&gt;match_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;thumbnail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, I use Selenium again to access that HTML and take a screenshot of the page. The image is saved in png in a folder in my local directory.&lt;/p&gt;

&lt;p&gt;The result is this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuhn5u21o8fv006s272yq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuhn5u21o8fv006s272yq.png" alt="https://raw.githubusercontent.com/joaomaranhao/video-maker/main/docs/images/thumb.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Recording
&lt;/h3&gt;

&lt;p&gt;To simplify the creation of the video, I decided to record the game with OBS Studio. So I can add on-screen elements, which are superimposed at the start, without the need to edit or post-produce the video.&lt;/p&gt;

&lt;p&gt;With Python's &lt;em&gt;subprocess&lt;/em&gt; module, I run the &lt;em&gt;.bat&lt;/em&gt; file that opens the replay of the match.&lt;/p&gt;

&lt;p&gt;PyAutoGUI is used to open OBS Studio and put the match to record.&lt;/p&gt;

&lt;p&gt;When the game is over, recording stops, and a &lt;em&gt;.mp4&lt;/em&gt; video file is saved to my local disk, ready to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Upload to Youtube
&lt;/h3&gt;

&lt;p&gt;I created a project on &lt;a href="https://cloud.google.com/" rel="noopener noreferrer"&gt;Google Cloud Platform&lt;/a&gt;, to be able to use the &lt;a href="https://developers.google.com/youtube/v3/quickstart/python" rel="noopener noreferrer"&gt;Youtube API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With the JSON information, I make a request with the title, description, keywords, and the video file.&lt;/p&gt;

&lt;p&gt;When the video upload finishes, I make another request to add the thumbnail to the video.&lt;/p&gt;

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

&lt;p&gt;This project allowed me to use different technologies and methods to programmatically create content. With all the automated processes, just run a line of code to populate this channel with a new, updated video with thumbnail and custom information.&lt;/p&gt;

&lt;p&gt;You can check the channel &lt;a href="https://www.youtube.com/channel/UC-C_dsVX2-G2UYA9IoD5i3Q" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can check the code on my &lt;a href="https://github.com/joaomaranhao/video-maker" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://twitter.com/joaofmaranhao" rel="noopener noreferrer"&gt;Twitter!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to ask questions, make suggestions and contribute to the project.&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
    </item>
    <item>
      <title>Como usei Python para automatizar um canal do Youtube</title>
      <dc:creator>João Maranhão</dc:creator>
      <pubDate>Wed, 13 Jul 2022 23:10:29 +0000</pubDate>
      <link>https://dev.to/joaomaranhao/como-usei-python-para-automatizar-um-canal-do-youtube-4k04</link>
      <guid>https://dev.to/joaomaranhao/como-usei-python-para-automatizar-um-canal-do-youtube-4k04</guid>
      <description>&lt;p&gt;Quando comecei a programar, a primeira coisa que fiz para por em prática meus novos conhecimentos foi automatizar um processo que era feito todos os dias no meu emprego.&lt;/p&gt;

&lt;p&gt;Trabalhava com edição de vídeos e, no mínimo uma vez por dia, tinha que descarregar uma mídia com as gravações para um servidor de backup e depois puxá-las para a minha máquina para começar a editar. Então, resolvi criar um script que fizesse isso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que automatizar?
&lt;/h2&gt;

&lt;p&gt;Ao automatizar os processos corriqueiros, era como se estivesse “ganhando” tempo. Se uma tarefa diária que demora 5 minutos para ser feita é automatizada, em 5 dias úteis, você terá 25 minutos a mais para fazer qualquer outra coisa. Em um mês, 1 hora e 40 minutos; em um ano, 20 horas…Multiplique isso por mais tarefas ou usuários e você terá números realmente consideráveis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como surgiu a inspiração
&lt;/h2&gt;

&lt;p&gt;Estudando JavaScript, assisti uma série de vídeos do &lt;a href="https://www.youtube.com/watch?v=kjhu1LEmRpY&amp;amp;list=PLMdYygf53DP4YTVeu0JxVnWq01uXrLwHi&amp;amp;ab_channel=FilipeDeschamps" rel="noopener noreferrer"&gt;Fillipe Deschamps&lt;/a&gt;, onde ele ensina a criar um canal no Youtube que gera conteúdo de forma programática.&lt;/p&gt;

&lt;p&gt;Em resumo, ele acessa um artigo do Wikipedia para pegar as informações que serão usadas no vídeo; usa a inteligência artificial Watson da IBM para “quebrar” o texto em sentenças; a API do Google para buscar imagens para ilustrar o vídeo; ImageMagick para tratar as fotos e criar a thumbnail; Adobe After Effects para editar o vídeo; e por fim a API do Youtube para fazer o upload.&lt;/p&gt;

&lt;p&gt;Acompanhei a série e fiz esse projeto. No fim, adicionei algumas funcionalidades extras como gerar áudio para cada sentença com a API Text-to-Speech, também do Watson da IBM, e adicioná-los ao vídeo.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é o projeto
&lt;/h2&gt;

&lt;p&gt;A ideia era criar um canal no Youtube de replays de partidas de um jogo bem popular chamado “League of Legends”, totalmente automatizado.&lt;/p&gt;

&lt;p&gt;Alguns sites disponibilizam para download partidas de jogadores profissionais. Os replays são arquivos executáveis que rodam o jogo.&lt;/p&gt;

&lt;p&gt;Para automatizar todo o processo de criação, alguns passos eram necessários:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entrar no site, escolher uma partida, pegar as informações da partida e fazer o download do replay&lt;/li&gt;
&lt;li&gt;Executar o replay e gravar a tela&lt;/li&gt;
&lt;li&gt;Editar o vídeo&lt;/li&gt;
&lt;li&gt;Criar a thumbnail&lt;/li&gt;
&lt;li&gt;Subir o vídeo e a thumbnail para o Youtube e preencher informações como título, descrição e palavras-chave&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Por que Python?
&lt;/h2&gt;

&lt;p&gt;Como tinha mais familiaridade com Javascript por já ter usado em outros projetos, seria a escolha óbvia, mas tinha um problema, eu precisava executar o jogo e configurar algumas coisas quando a partida começasse. Para isso, precisava controlar mouse e teclado de forma programática.&lt;/p&gt;

&lt;p&gt;Busquei alguma biblioteca Javascript que me ajudasse a fazer isso, mas não tive sucesso. Foi quando lembrei de uma em Python, que se chama PyAutoGUI. Então, resolvi fazer tudo em Python! Além de ter tudo o que precisava, era uma chance de me aperfeiçoar em uma outra linguagem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como foi implementado
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Web scrapping
&lt;/h3&gt;

&lt;p&gt;Web scrapping é um método para acessar qualquer site e pegar informações.&lt;/p&gt;

&lt;p&gt;O que utilizei para buscar as partidas foi o &lt;a href="https://www.leagueofgraphs.com/" rel="noopener noreferrer"&gt;League of Graphs&lt;/a&gt; e, através &lt;a href="https://www.leagueofgraphs.com/replays/with-high-kda/grandmaster/sr-ranked" rel="noopener noreferrer"&gt;desse link&lt;/a&gt;, consigo acessar uma página com replays e filtrar a minha busca, para pegar apenas partidas com bons jogadores.&lt;/p&gt;

&lt;p&gt;A ideia aqui foi pegar a primeira partida e extrair as informações dessa tabela.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fjoaomaranhao%2Fvideo-maker%2Fmain%2Fdocs%2Fimages%2Fmatch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fjoaomaranhao%2Fvideo-maker%2Fmain%2Fdocs%2Fimages%2Fmatch.png" alt="https://raw.githubusercontent.com/joaomaranhao/video-maker/main/docs/images/match.png" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dentre as muitas opções do Python para realizar essa tarefa, escolhi o Selenium por ter a funcionalidade de interagir com o site. A biblioteca permite clicar para fazer o download da partida.&lt;/p&gt;

&lt;p&gt;Criei um dicionário Python com todas as informações que precisava e salvei em um arquivo JSON, em uma pasta chamada “assets”, na raiz do projeto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thumbnail
&lt;/h3&gt;

&lt;p&gt;Para criar a thumbnail, desenvolvi um template com HTML e CSS. Já com as informações do JSON, os dados são preenchidos dinamicamente e um arquivo HTML é salvo na pasta “assets”:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;assets&lt;/span&gt;
    &lt;span class="n"&gt;match_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;thumbnail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois disso, utilizo novamente o Selenium para acessar esse HTML e tirar uma screenshot da página. A imagem é salva em png em uma pasta no meu diretório local.&lt;/p&gt;

&lt;p&gt;O resultado é esse:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fjoaomaranhao%2Fvideo-maker%2Fmain%2Fdocs%2Fimages%2Fthumb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fjoaomaranhao%2Fvideo-maker%2Fmain%2Fdocs%2Fimages%2Fthumb.png" alt="https://raw.githubusercontent.com/joaomaranhao/video-maker/main/docs/images/thumb.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Gravação
&lt;/h3&gt;

&lt;p&gt;Para simplificar a criação do vídeo, decidi gravar o jogo com o OBS Studio. Assim posso adicionar elementos em tela, que ficam sobrepostos à partida, sem a necessidade de editar ou pós-produzir o vídeo.&lt;/p&gt;

&lt;p&gt;Com o módulo &lt;em&gt;subprocess&lt;/em&gt; do Python, executo o arquivo &lt;em&gt;.bat&lt;/em&gt; que abre o replay da partida.&lt;/p&gt;

&lt;p&gt;O PyAutoGUI é usado para abrir o OBS Studio e colocar a partida para gravar.&lt;/p&gt;

&lt;p&gt;Já as informações do JSON, são passadas para o script com comandos de teclado para selecionar o jogador certo, do time certo.&lt;/p&gt;

&lt;p&gt;Para rodar as hotkeys no jogo, usei uma biblioteca chamada PyDirectInput, já que o PyAutoGUI utiliza uma espécie de teclado virtual e não funcionava dentro do jogo.&lt;/p&gt;

&lt;p&gt;Quando a partida acaba, a gravação para e um arquivo de vídeo &lt;em&gt;.mp4&lt;/em&gt; é salvo no meu disco local, pronto para ser usado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Upload para o Youtube
&lt;/h3&gt;

&lt;p&gt;Criei um projeto no &lt;a href="https://cloud.google.com/" rel="noopener noreferrer"&gt;Google Cloud Platform&lt;/a&gt;, para conseguir utilizar a &lt;a href="https://developers.google.com/youtube/v3/quickstart/python" rel="noopener noreferrer"&gt;API do Youtube&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Com as informações do JSON, faço uma requisição com título, descrição, palavras-chave e o arquivo em vídeo.&lt;/p&gt;

&lt;p&gt;Quando o upload do vídeo termina, faço outra requisição para adicionar a thumbnail ao vídeo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Esse projeto me permitiu usar diferentes tecnologias e métodos para criar conteúdo de forma programática. Com todos os processos automatizados, é só rodar uma linha de código para popular esse canal com um vídeo novo, atualizado, com thumbnail e informações personalizadas.&lt;/p&gt;

&lt;p&gt;Você pode conferir o canal &lt;a href="https://www.youtube.com/channel/UC-C_dsVX2-G2UYA9IoD5i3Q" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Você pode conferir o código no meu &lt;a href="https://github.com/joaomaranhao/video-maker" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Fique à vontade para tirar dúvidas, dar sugestões e contribuir com o projeto.&lt;/p&gt;

</description>
      <category>python</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
