<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Marcos Stefani Rosa on Medium]]></title>
        <description><![CDATA[Stories by Marcos Stefani Rosa on Medium]]></description>
        <link>https://medium.com/@marcosstefani?source=rss-f1aee1c7747f------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*Jt2GUOe64xKXnQJW-ds-ng.png</url>
            <title>Stories by Marcos Stefani Rosa on Medium</title>
            <link>https://medium.com/@marcosstefani?source=rss-f1aee1c7747f------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 10:56:14 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@marcosstefani/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[GitTool — Git made simple]]></title>
            <link>https://blog.devgenius.io/gittool-git-made-simple-223c6002aca3?source=rss-f1aee1c7747f------2</link>
            <guid isPermaLink="false">https://medium.com/p/223c6002aca3</guid>
            <category><![CDATA[github]]></category>
            <category><![CDATA[ssh]]></category>
            <category><![CDATA[bitbucket]]></category>
            <category><![CDATA[git]]></category>
            <category><![CDATA[ssh-keys]]></category>
            <dc:creator><![CDATA[Marcos Stefani Rosa]]></dc:creator>
            <pubDate>Tue, 18 Nov 2025 12:25:32 GMT</pubDate>
            <atom:updated>2025-11-27T10:56:36.571Z</atom:updated>
            <content:encoded><![CDATA[<h3>GitTool — Git made simple</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/970/1*Ogby4BW0_gI8rIh99WwaGw.jpeg" /></figure><p>Portuguese version: <a href="https://marcosstefani.medium.com/gittool-o-git-de-maneira-simples-988244af3fdf">https://marcosstefani.medium.com/gittool-o-git-de-maneira-simples-988244af3fdf</a></p><p>Hello! My name is <strong>Marcos Rosa</strong>, and I’ve been working in software development for more than <strong>20 years</strong>. Throughout this journey, I’ve worked with Git on a daily basis, along with a variety of tools that help streamline versioning and workflow management. However, despite all this experience, I kept facing a recurring obstacle: <strong>managing multiple identities and SSH keys</strong>.</p><p>Anyone who works with multiple GitHub accounts or different repository platforms knows how inconvenient it can be to switch configurations, adjust keys, and remember specific details that — after some time without touching them — require that inevitable quick search just to make sure everything is being done correctly. On top of that, for security reasons, I’ve always had the habit of <strong>periodically renewing my SSH keys</strong>, even when using only one. Although this practice increases security, it also brings headaches, as the process has never been as intuitive as I would like.</p><p>After years dealing with these small but persistent frustrations, I realized I could turn this recurring pain into a solution. And that’s how <strong>GitToll</strong> was born — an open-source tool designed to make using Git — especially when it comes to SSH and multi-user configurations — <strong>much simpler, more intuitive, and more seamless</strong>.</p><p>In this article, you’ll get to know this tool, understand why it was created, and learn how it can make your daily Git workflow much easier. Let’s dive in!</p><h3>Installing GitTool</h3><p>The tool can be installed in a few different ways. The first is through <a href="https://brew.sh/"><strong>Homebrew</strong></a>, which can be used on macOS or Linux:</p><pre>brew tap ElaraDevSolutions/tools<br>brew install gt</pre><p>You can also download it through the release files available in the Git tags: <a href="https://github.com/ElaraDevSolutions/gittool/tags">https://github.com/ElaraDevSolutions/gittool/tags</a></p><h3><strong>Features (so far)</strong></h3><h4>Add a new SSH key</h4><p>Adding a new key is simple. Just run:</p><pre>gt ssh add</pre><p>This command will create a new SSH key and ensure it is added to ssh-add and properly configured in ~/.ssh/config.</p><h4>Add an existing SSH key (created outside of gt)</h4><p>To add a key while ensuring it is correctly configured with GitTool, run:</p><pre># command: gt ssh add &lt;name or part of the key name&gt;<br>gt ssh add personal</pre><p>You can provide only part of the key name. GitTool will search your keys in ~/.ssh, and if it finds more than one match, it will show a list so you can choose. If there’s only one match, it will select it automatically.</p><h4>Delete a key</h4><p>To remove an unnecessary key, simply run:</p><pre># command: gt ssh remove &lt;name or part of the key name&gt;<br>gt ssh remove personal-ssh</pre><p>When adding a key, you specify a <em>HostAlias</em>. This alias is required to delete it.<br> To list all registered HostAliases, run:</p><pre>gt ssh list</pre><h4>Rotate SSH keys</h4><p>One of the problems I wanted to solve was key rotation. As I mentioned, I like to periodically rotate my keys for security reasons, so I created a dedicated command for that:</p><pre># command: gt ssh rotate &lt;HostAlias&gt;<br>gt ssh rotate personal-ssh</pre><p>The command will rotate the key, and you can update it in your Git settings. It also creates a backup in case you need a rollback.</p><p>If you want to update the email during rotation, use:</p><pre># command: gt ssh rotate --email &lt;new email&gt; &lt;HostAlias&gt;<br>gt ssh rotate --email new.email@example.com personal-ssh</pre><h4>Select a key for the repository</h4><p>If you already cloned a repository but the SSH key is outdated, go to the repository folder and run:</p><pre>gt ssh select</pre><p>This command lists all configured SSH keys so you can choose which one to apply. It then updates the Git configuration for the current repository.</p><h4>Smart Clone</h4><p>Finally, one of my favorite and most-used commands. If you work with more than one SSH key, use the clone command to clone your repository:</p><pre># command: gt clone &lt;ssh link of your git&gt;<br>gt clone git@github.com:your_user/your_repo.git</pre><p>The tool will clone the repository on your machine and ask which SSH key you want to use. This is extremely convenient!</p><h3>Final Considerations</h3><p>GitToll was born from a real, everyday need: simplifying Git usage in scenarios where multiple accounts, SSH keys, and parallel configurations can become more complicated than they should be. It streamlines the process, reduces errors, and makes the workflow more intuitive — especially for those who manage multiple identities or periodically renew their keys.</p><p>However, it’s important to emphasize: <strong>GitToll is not a silver bullet</strong>. It doesn’t aim to replace everything that already exists in the Git ecosystem, nor to eliminate the need to understand how Git works under the hood. That was never the goal. What GitToll does is transform repetitive, error-prone tasks into something simple, accessible, and fast — and that alone already boosts daily productivity significantly.</p><p>As an <strong>open-source project</strong>, GitToll is constantly evolving. This means you are more than welcome to be part of this journey.<br> Found a bug? Have an improvement idea? Want to add a new feature?<br> <strong>Pull Requests, discussions, and issues are always welcome.</strong></p><p>GitToll is a tool made <em>by the community and for the community</em> — and together we can make it even more useful and powerful.<br> Thank you for reading, and I hope GitToll makes your daily workflow as smooth as it made mine.</p><p>Repo: <a href="https://github.com/ElaraDevSolutions/gittool">https://github.com/ElaraDevSolutions/gittool</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=223c6002aca3" width="1" height="1" alt=""><hr><p><a href="https://blog.devgenius.io/gittool-git-made-simple-223c6002aca3">GitTool — Git made simple</a> was originally published in <a href="https://blog.devgenius.io/">Dev Genius</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GitTool — O git de maneira simples]]></title>
            <link>https://marcosstefani.medium.com/gittool-o-git-de-maneira-simples-988244af3fdf?source=rss-f1aee1c7747f------2</link>
            <guid isPermaLink="false">https://medium.com/p/988244af3fdf</guid>
            <category><![CDATA[github]]></category>
            <category><![CDATA[ssh-keys]]></category>
            <category><![CDATA[git]]></category>
            <category><![CDATA[bitbucket]]></category>
            <category><![CDATA[ssh]]></category>
            <dc:creator><![CDATA[Marcos Stefani Rosa]]></dc:creator>
            <pubDate>Tue, 18 Nov 2025 12:15:32 GMT</pubDate>
            <atom:updated>2025-11-18T12:26:25.988Z</atom:updated>
            <content:encoded><![CDATA[<h3>GitTool — O git de maneira simples</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/970/1*Ogby4BW0_gI8rIh99WwaGw.jpeg" /></figure><p>English Version: <a href="https://marcosstefani.medium.com/gittool-git-made-simple-223c6002aca3">https://marcosstefani.medium.com/gittool-git-made-simple-223c6002aca3</a></p><p>Olá! Meu nome é <strong>Marcos Rosa</strong> e venho atuando há mais de <strong>20 anos no desenvolvimento de software</strong>. Ao longo dessa jornada, trabalhei diariamente com Git e com uma série de ferramentas que facilitam o versionamento e o fluxo de trabalho. Porém, mesmo com tanta experiência, sempre enfrentei um obstáculo que insistia em reaparecer: <strong>a gestão de múltiplas identidades e chaves SSH</strong>.</p><p>Quem, como eu, trabalha com múltiplas contas do GitHub ou diferentes plataformas de repositórios sabe o quanto pode ser incômodo alternar configurações, ajustar chaves e lembrar detalhes específicos que, depois de algum tempo sem mexer, exigem aquela inevitável pesquisa rápida para evitar erros. Além disso, por uma questão de segurança, sempre tive o hábito de <strong>renovar periódicamente minhas chaves SSH</strong> — mesmo quando utilizava apenas uma. Essa prática aumentava a segurança, mas também aumentava a dor de cabeça, já que o processo nunca foi tão intuitivo quanto eu gostaria.</p><p>Depois de anos convivendo com essas pequenas frustrações, percebi que poderia transformar essa dor recorrente em uma solução. E foi assim que nasceu o <strong>GitToll</strong>, uma ferramenta open source pensada para tornar o uso do Git — especialmente no que diz respeito a SSH e configurações multiusuário — <strong>muito mais simples, intuitivo e fluido</strong>.</p><p>Neste artigo, você vai conhecer melhor essa ferramenta, entender por que ela foi criada e como ela pode facilitar (e muito) o seu dia a dia com Git. Vamos lá?</p><h3>Instalando o GitTool</h3><p>A ferramenta pode ser instalada de algumas formas, a primeira delas é pelo <a href="https://brew.sh/">homebrew</a> (ferramenta que pode ser utilizada em MacOS ou Linux).</p><pre>brew tap ElaraDevSolutions/tools<br>brew install gt</pre><p>Ou, por meio dos arquivos disponibilizados nas Tags do Git:<br><a href="https://github.com/ElaraDevSolutions/gittool/tags">https://github.com/ElaraDevSolutions/gittool/tags</a></p><h3>Funcionalidades (até o momento)</h3><h4>Adicionar nova chave ssh</h4><p>Adicionar uma nova chave fica simples, basta executar o comando:</p><pre>gt ssh add</pre><p>Esse comando criará uma nova chave tendo a certeza que essa nova chave estará adicionada ao ssh-add e configurada em <em>~/.ssh/config</em></p><h4>Adicionar uma chave ja existente (criada sem o gt)</h4><p>Para adicionar uma nova chave de maneira a garantir que ela está configurada corretamente com o gt, basta executar:</p><pre># comando: gt ssh add &lt;nome ou parte do nome da chave&gt;<br>gt ssh add pessoal</pre><p>Note que você pode iformar apenas parte do nome da chave. O gt vai buscar entre as suas chaves que estão em <em>~/.ssh</em> e se achar mais de uma chave com aquele nome vai te mostrar uma lista de chaves para que você possa selecionar. Se tiver apenas uma, ja a seleciona sem necessidade de seleção.</p><h4>Deleção de uma chave</h4><p>Para excluir uma chave desnecessaria, basta executar o comando abaixo.</p><pre># gt ssh add &lt;nome ou parte do nome da chave&gt;<br>gt ssh remove pessoal-ssh</pre><p>Toda vez que adicionamos uma chave, informamos o HostAlias, este HostAlias é necessário para deleção. Se você quiser listar os HostAlias cadastrados, execute:</p><pre>gt ssh list</pre><h4>Rotacionar chaves</h4><p>Um dos problemas solucionados foi a rotação de uma chave, como eu disse, gosto de rotaciona-la de tempos em tempos para manter a segurança, por isso eu criei esse comando. Para executa-lo:</p><pre># gt ssh rotate &lt;HostAlias&gt;<br>gt ssh rotate pessoal-ssh</pre><p>O comando irá rotacionar a chave e vc pode atualiza-la no teu git. O comando cria um backup da chave caso queira fazer o rollback.</p><p>Se quiser atualizar o email rotacionando execute o parametro de email, veja:</p><pre># gt ssh rotate --email &lt;novo email&gt; &lt;HostAlias&gt;<br>gt ssh rotate --email novo.email@exemplo.com pessoal-ssh</pre><h4>Selecionar uma chave para o repositorio</h4><p>Se você ja tiver um repositorio clonado mas a chave ssh estiver desatualizada, basta executar o comando abaixo dentro do repositorio que deseja atualizar:</p><pre>gt ssh select</pre><p>Esse comando lhe dará a lista de sshs configuradas para seleção. Ao selecionar a configuração do git estará correta no repositorio corrente.</p><h4>Clone inteligente</h4><p>E por fim, o comando que mais gosto e uso, se você trabalhar com mais de uma ssh execute o comando clone para clonar seu repositorio, veja um exemplo:</p><pre># gt clone &lt;ssh link do seu git&gt;<br>gt clone git@github.com:seu_user/seu_repo.git</pre><p>O comando vai clonar seu repositorio na sua máquina mas vai lhe perguntar qual chave ssh deseja usar. Isso facilita muito!!</p><h3>Considerações Finais</h3><p>O GitToll nasceu de uma necessidade real e cotidiana: simplificar o uso do Git em um cenário onde múltiplas contas, chaves SSH e configurações paralelas acabam se tornando mais complexas do que deveriam. Ele facilita o processo, reduz erros e torna o fluxo de trabalho mais intuitivo — especialmente para quem gerencia várias identidades ou renova suas chaves periodicamente.</p><p>Mas é importante reforçar: <strong>o GitToll não é uma bala de prata</strong>. Ele não pretende substituir tudo o que já existe no ecossistema Git, nem eliminar por completo a necessidade de entender como o Git funciona por baixo dos panos. O objetivo nunca foi esse. O que ele faz é tornar tarefas recorrentes e cansativas em algo mais simples, acessível e rápido — e isso, por si só, já melhora muito a produtividade diária.</p><p>Como projeto <strong>open source</strong>, o GitToll está em constante evolução. E isso significa que você é mais do que bem-vindo para participar dessa jornada. Encontrou um bug? Tem uma ideia de melhoria? Quer adicionar uma nova funcionalidade?<br> <strong>Pull Requests, discussions e issues são sempre bem-vindos.</strong></p><p>O GitToll é uma ferramenta feita pela comunidade e para a comunidade — e juntos podemos transformá-la em algo ainda mais útil e poderosa. Obrigado por chegar até aqui, e espero que o GitToll facilite o seu dia a dia tanto quanto facilitou o meu.</p><p>Repo: <a href="https://github.com/ElaraDevSolutions/gittool">https://github.com/ElaraDevSolutions/gittool</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=988244af3fdf" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pytterns: Making Design Patterns in Python Simple and Intuitive]]></title>
            <link>https://blog.devgenius.io/pytterns-making-design-patterns-in-python-simple-and-intuitive-548e464417ef?source=rss-f1aee1c7747f------2</link>
            <guid isPermaLink="false">https://medium.com/p/548e464417ef</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[best-practices]]></category>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[python-programming]]></category>
            <category><![CDATA[python3]]></category>
            <dc:creator><![CDATA[Marcos Stefani Rosa]]></dc:creator>
            <pubDate>Sat, 06 Sep 2025 20:17:00 GMT</pubDate>
            <atom:updated>2025-09-09T17:03:43.194Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*T5uusT0XKOHlW2Kk0ludtA.png" /></figure><p>Over the past <strong>20 years working with Python</strong>, I’ve noticed something very characteristic in the community: the tendency to solve problems quickly, often with <strong>straightforward scripts</strong>, without much concern for architectural patterns. This pragmatism is, without a doubt, one of Python’s greatest strengths — but it can also become a weakness in larger projects, where the lack of structure eventually takes its toll.</p><p>At the same time, working with <strong>Java</strong>, I’ve always seen how the consistent use of <strong>design patterns</strong> makes systems clearer, more extensible, and easier to maintain. In Python, I feel those benefits are often overlooked — not because they’re unnecessary, but because implementing design patterns in the language can seem cumbersome or even “overkill” for the context.</p><p>That realization led me to create <strong>Pytterns </strong>an effort to bring the best of both worlds. The simplicity and elegance of Python combined with the robustness that design patterns provide.</p><h4>Why Care About Design Patterns?</h4><p>Design patterns aren’t just academic concepts; they are battle-tested solutions to recurring problems in software design. Using them in your projects brings several benefits:</p><ul><li>Organization: your code gains a clear and predictable structure.</li><li>Reusability: you avoid reinventing the wheel.</li><li>Communication: patterns serve as a “common language” between developers.</li><li>Maintainability: systems become easier to understand and evolve.</li></ul><p>The challenge is: how do you leverage these patterns without the overhead of writing repetitive boilerplate? That’s exactly where Pytterns comes in.</p><h4>Installation</h4><pre>pip install pytterns</pre><h3>The Patterns Implemented in Pytterns</h3><h4>Strategy — choosing behavior at runtime</h4><p>The <strong>Strategy</strong> pattern allows you to define a family of algorithms and switch between them dynamically.</p><p><strong>Benefit</strong>: separates decision logic from implementation, making the code more flexible and extensible.</p><pre>from pytterns import strategy, load<br><br>@strategy(&quot;payment&quot;)<br>class CreditCardPayment:<br>    def check(self, method):<br>        return method == &quot;credit_card&quot;<br>    <br>    def execute(self):<br>        return &quot;Processing payment via Credit Card&quot;<br><br>@strategy(&quot;payment&quot;)<br>class PayPalPayment:<br>    def check(self, method):<br>        return method == &quot;paypal&quot;<br>    <br>    def execute(self):<br>        return &quot;Processing payment via PayPal&quot;<br><br>payment_strategy = load.strategy(&quot;payment&quot;).check(&quot;paypal&quot;).execute()<br>print(payment_strategy)  # Processing payment via PayPal</pre><p>Imagine being able to switch payment methods without ever touching the core business logic — that’s the power of Strategy.</p><h4>Chain of Responsibility — processing requests in sequence</h4><p>This pattern allows a request to pass through a chain of handlers, each responsible for a specific step in the process.</p><p>Benefit: reduces coupling and makes it easy to add, remove, or reorder steps in the flow.</p><pre>from pytterns import chain, load<br><br>@chain(&quot;auth_chain&quot;, order=1)<br>class Authenticator:<br>    def handle(self, request):<br>        if not request.get(&quot;authenticated&quot;, False):<br>            print(&quot;Authentication failed!&quot;)<br>            return<br>        print(&quot;User authenticated&quot;)<br><br>@chain(&quot;auth_chain&quot;, order=2)<br>class Authorizer:<br>    def handle(self, request):<br>        if request.get(&quot;role&quot;) != &quot;admin&quot;:<br>            print(&quot;Authorization failed!&quot;)<br>            return<br>        print(&quot;User authorized&quot;)<br><br>@chain(&quot;auth_chain&quot;, order=3)<br>class Logger:<br>    def handle(self, request):<br>        print(f&quot;Logging request: {request}&quot;)<br><br>auth_chain = load.chain(&quot;auth_chain&quot;)<br>auth_chain.handle({&quot;authenticated&quot;: True, &quot;role&quot;: &quot;admin&quot;})</pre><p>In practice, this makes it easy to build pipelines that evolve as your system grows.</p><h4>Observer — reacting to events</h4><p>The Observer pattern lets you register listeners for an event and notify them later.</p><p>Benefit: promotes decoupling — the event emitter doesn’t need to know who’s listening.</p><pre>from pytterns import observer, load<br><br>@observer(&#39;user.created&#39;)<br>def send_welcome_email(user_id):<br>    print(f&quot;send welcome to {user_id}&quot;)<br>    return &#39;email_sent&#39;<br><br>@observer(&#39;user.created&#39;)<br>class AuditListener:<br>    def update(self, user_id):<br>        print(f&quot;audit: created {user_id}&quot;)<br>        return &#39;audited&#39;<br><br>results = load.observer(&#39;user.created&#39;).notify(42)<br>print(results)  # [(True, &#39;email_sent&#39;), (True, &#39;audited&#39;)]</pre><p>When a user is created, you can send a welcome email, log an audit, trigger metrics — all independently and without tight coupling.</p><h4>Factory — creating objects dynamically</h4><p>The <strong>Factory</strong> pattern centralizes the creation of objects without exposing instantiation details.</p><p><strong>Benefit</strong>: organizes object creation logic and allows you to easily swap implementations at runtime.</p><pre>from pytterns import factory, load<br><br>@factory(&#39;db&#39;)<br>class MyDB:<br>    def __init__(self, dsn):<br>        self.dsn = dsn<br><br>inst = load.factory(&#39;db&#39;).create(&#39;sqlite:///:memory:&#39;)<br>print(inst.dsn)</pre><p>You can register multiple database engines and switch between them without changing business logic.</p><h4>Command — encapsulating actions as objects</h4><p>The <strong>Command</strong> pattern maps commands to handlers (functions or classes) that can be executed on demand.</p><p><strong>Benefit</strong>: decouples the caller from the executor and enables features like undo/redo, queuing, or scheduling commands.</p><pre>from pytterns import command, load<br><br>@command(&#39;say&#39;)<br>def say(msg):<br>    print(msg)<br><br>@command(&#39;say&#39;)<br>class Loud:<br>    def execute(self, msg):<br>        print(msg.upper())<br><br>load.command(&#39;say&#39;).execute(&#39;hello&#39;)</pre><p>Perfect for CLIs, task queues, or bots that need flexible command execution.</p><h4>Conclusion</h4><p><strong>Pytterns</strong> was born from the desire to <strong>lower the friction</strong> of using design patterns in Python.<br> Why waste time reimplementing well-known structures when we could focus on solving real business problems?</p><p>If you already use patterns, this library will give you <strong>productivity</strong>.<br> If you’re learning, it provides <strong>clear, practical examples</strong> to study and apply.</p><p>And because it’s <strong>open source</strong>, the project grows with community contributions.<br> If you’d like to add new patterns, suggest improvements, or open PRs, your help is more than welcome.</p><h4>Useful links</h4><p>👉 Check out the repository on GitHub: <a href="https://github.com/marcosstefani/pytterns">github.com/marcosstefani/pytterns</a><br>👉 Check Pypi project: <a href="https://pypi.org/project/pytterns/">https://pypi.org/project/pytterns</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=548e464417ef" width="1" height="1" alt=""><hr><p><a href="https://blog.devgenius.io/pytterns-making-design-patterns-in-python-simple-and-intuitive-548e464417ef">Pytterns: Making Design Patterns in Python Simple and Intuitive</a> was originally published in <a href="https://blog.devgenius.io/">Dev Genius</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Python’s Future: A Journey of Passion and Uncertainty]]></title>
            <link>https://marcosstefani.medium.com/pythons-future-a-journey-of-passion-and-uncertainty-e412c98b9570?source=rss-f1aee1c7747f------2</link>
            <guid isPermaLink="false">https://medium.com/p/e412c98b9570</guid>
            <category><![CDATA[development]]></category>
            <category><![CDATA[programming-languages]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[python3]]></category>
            <category><![CDATA[python-programming]]></category>
            <dc:creator><![CDATA[Marcos Stefani Rosa]]></dc:creator>
            <pubDate>Sun, 31 Dec 2023 00:05:14 GMT</pubDate>
            <atom:updated>2023-12-31T00:05:14.154Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*knmxSLarqInJjjDo1fOdgA.png" /></figure><p>Ah, Python! A language that captured my heart from the first “Hello, World!” Its captivating simplicity and boundless flexibility have been reliable guides on my programming journey. With each line of code, I was enchanted by the clarity of the syntax and the ease of expressing complex ideas. Python, for me, represented more than just a programming language; it was a companion that simplified challenges and transformed intricate concepts into something accessible.</p><p>The inherent flexibility of Python has always been an ally, allowing me to adapt solutions to a variety of problems. Whether developing small projects or tackling more ambitious challenges, the versatility of this language seemed boundless, as if each line of code were an extension of my thoughts.</p><p>The speed at which Python solves problems is truly remarkable; it accelerated my development process and unlocked doors to innovation. Reaching the peak of my language experience, I utilized in cloud lambda functions and Flask microservices for mathematical solutions.</p><p>However, as my passion for Python continues to burn, I can’t help but wonder: What lies ahead for Python’s future? In my view, the initial charm seems to be at a crossroads. Amid the pursuit of increasingly elegant solutions, questions linger. Are we, in our quest for sophistication, losing the essence of the simplicity that made Python so special? With so many new programming languages and concepts emerging, is Python falling behind? Does it tend towards obsolescence by not keeping up with the latest trends?</p><p>All these questions have crossed my mind, and I would like to share some of my thoughts and the conclusions I have reached. I may come to the conclusion in the future that I was completely mistaken, but it is always interesting to raise questions, and as a lover of the language, I feel compelled to do so. Join me as we delve deeper into the challenges and uncertainties that may shape the future of this beloved language.</p><p>As we immerse ourselves in the dynamic realm of the Python programming language, we find a complex interplay that not only defines the language’s functionality but also charts its course into the future. Python, renowned for its simplicity and efficiency, transcends syntax to become an ecosystem where community influence is pivotal for ongoing development.</p><p>The Python community, a diverse tapestry of programmers, reveals nuanced facets. Among its members are individuals with solid mathematical knowledge, occasionally lacking in modern programming practices. Data analysts, deeply engaged in Python’s expansive possibilities, constitute a significant contingent. There are also those adopting Python as a second language from object-oriented backgrounds, introducing unique challenges and sometimes facing resistance when proposing substantial syntax changes.</p><p>Resistance to change, a recurring challenge in any programming language’s evolution, emerges as an intrinsic dilemma within the Python community. While some advocate for the stability of the current syntax, others recognize the urgent need to evolve in order to stay relevant in a rapidly shifting technological landscape.</p><p>A personal narrative underscores the conflict between tradition rooted in the efficiency of C, Python’s development language, and the imperative to transcend these constraints to embrace modern standards. The diversity of the Python community lies not just in a range of knowledge but also in the ability to surmount challenges and embrace change when necessary.</p><p>A comparative analysis between Python, Java, and .Net offers a deeper understanding of the underlying philosophies of each language. Java, with its rigorous approach to object-oriented programming, stands out for its robust, class-oriented structure. In contrast, .Net, with its modular and open nature, provides a flexible platform tailored to the specific needs of each project.</p><p>Python, with its simplicity and efficiency inherited from C, maintains a clean and minimalist syntax. While this appeals to both novices and veterans, it challenges those seeking to expand the language beyond its C roots.</p><p>The future of Python rests in the hands of the community, which must skillfully navigate the delicate balance between deeply entrenched tradition and the constant need for innovation. Resistance to change is understandable, yet stagnation could impede progress. Integrating modern standards, acknowledging the diverse experiences within the community, is crucial to ensure that Python not only holds its ground but thrives in a dynamic and ever-evolving landscape.</p><p>In this panorama, Python’s journey transcends mere code and transforms into a human narrative — a saga reflecting the intricate relationships among programmers, programming languages, and the unyielding quest for equilibrium between the past and the future. As the Python community confronts challenges and shapes the language’s destiny, the story is far from concluded. This marks the commencement of a journey toward sustainable improvement and continuous adaptation.</p><p>An illustrative example of this dynamic can be seen in the trajectory of the PHP language. In the early years of the 21st century, when many professionals, myself included, were beginning their careers in the job market in Brazil around the 2000s, PHP emerged as a promising and exciting technology for web developers. Its simplicity and ease of learning made it an attractive choice.</p><p>However, over time, I witnessed the evolution of the experience with PHP, a journey that, at certain points, negatively impacted its upward trajectory. Resistance to adopting best practices, lack of standardization, and fragmentation in the PHP ecosystem were factors that, at a certain point, threatened to compromise its position and reputation in the web development landscape.</p><p>This experience with PHP prompted deep reflection on the influence of the community in shaping the fate of a programming language. This example serves as a warning about the dangers of resisting beneficial changes, a lesson I carry when considering the future of other languages, including Python.</p><p>The fear that similar resistances to implementing improvements may manifest in the Python universe, especially regarding innovative concepts like decorators, is a realistic concern. The experience of what happened with PHP provides valuable insight into how reluctance to embrace evolution can negatively impact the development of a language over time.</p><p>On the other hand, it is crucial to recognize that PHP, after years of challenges, has been reinventing itself and regaining its foothold in the market. However, it cannot be ignored that the long journey of recovery often results in significant losses. The PHP language lost ground over the years in its quest to recover its reputation and relevance. This highlights an important reality: a quick and certain recovery is not always possible.</p><p>This scenario serves as a warning to the Python community, emphasizing the importance of learning from past experiences. Reinvention may be possible, but it is a delicate process that requires time and effort. The fear is not just of change but also of facing a prolonged and uncertain recovery curve, illustrated by PHP’s trajectory over the years.</p><p>In conclusion, I reinforce that the considerations presented reflect my opinion as a professional with over two decades of experience in the field and a genuine love for programming. Over the years, cultivating knowledge of various languages has become a passion — a constant learning process in which I seek to understand not only syntax but also the specific purposes and nuances of each tool. The wise words of <a href="https://medium.com/u/ea8c9980342b">Léo Hackin</a> resonate deeply in my daily practice: “<em>We don’t need to know how to program in every language, but we need to know what each one is for and what its advantages and disadvantages are.</em>” In this spirit, I persist in exploration and in-depth understanding, believing that this approach enriches not only my professional repertoire but also contributes to the constant advancement and evolution in the programming universe.</p><p>Additionally, I express the hope that these reflections will be received warmly by the Python community. My intention in sharing these ideas was not to offend but to promote constructive discussion. I firmly believe that dialogue around programming languages is essential for collective progress, and it is with the intention of positively contributing to this discourse that I share my perspectives. May this article be regarded as a contribution to reflection with the respect and affection I dedicate to the community to which I have belonged for so many years.</p><p>If you want to know a little more about me, follow my contacts:<br>GitHub: <a href="https://github.com/marcosstefani">https://github.com/marcosstefani</a><br>Linkedin: <a href="https://www.linkedin.com/in/marcosstefani">https://www.linkedin.com/in/marcosstefani</a></p><p>Thank you.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e412c98b9570" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Unlocking the Power of Python Decorator]]></title>
            <link>https://blog.devgenius.io/unlocking-the-power-of-python-decorator-ebabb5fcf9?source=rss-f1aee1c7747f------2</link>
            <guid isPermaLink="false">https://medium.com/p/ebabb5fcf9</guid>
            <category><![CDATA[development]]></category>
            <category><![CDATA[python-programming]]></category>
            <category><![CDATA[annotations]]></category>
            <category><![CDATA[decorators]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Marcos Stefani Rosa]]></dc:creator>
            <pubDate>Wed, 13 Sep 2023 00:02:46 GMT</pubDate>
            <atom:updated>2023-10-11T15:00:26.210Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*i7g73NYxCCneBtDU.png" /></figure><p>Python decorators are a powerful feature that many developers underestimate or are unaware of. They offer a flexible and elegant way to modify code behavior, making it more dynamic and adaptable. In this article, we will delve deep into Python decorators, from the basics to advanced scenarios. You will discover how to create custom decorators, use them to preprocess code, and even generate code dynamically based on information contained in the decorators. Get ready to unlock the full potential of Python decorators and enhance your ability to write more efficient and versatile code.</p><p>Throughout this article, we will explore practical examples that illustrate the power of Python decorators. The best way to understand how decorators can be used is through concrete examples, which is why we will present sample code that demonstrates how to create and apply custom decorators in Python.</p><h3>Simple Example</h3><p>The code we will present is a simple yet illustrative example of how you can use decorators to preprocess code and generate additional code based on the information contained in these decorators. This example serves as a starting point for you to further explore the possibilities of Python decorators in your own projects.</p><p>Let’s dive into the code and discover how decorators can enhance the flexibility and functionality of your Python code.</p><pre># Define a custom decorator that takes arguments<br>def my_annotation(arg1, arg2):<br>    def decorator(func):<br>        def wrapper(*args, **kwargs):<br>            # Perform preprocessing based on the decorator arguments<br>            result = func(*args, **kwargs)<br>            # Generate additional code based on the decorator arguments<br>            generated_code = f&quot;Arg1: {arg1}, Arg2: {arg2}&quot;<br>            return result, generated_code<br>        return wrapper<br>    return decorator<br><br># Use the custom decorator<br>@my_annotation(&quot;foo&quot;, &quot;bar&quot;)<br>def my_function():<br>    # Your code here<br>    return &quot;Function result&quot;<br><br>result, generated_code = my_function()<br>print(&quot;Result:&quot;, result)<br>print(&quot;Generated code:&quot;, generated_code)</pre><p>The code demonstrates the use of custom decorators in Python to preprocess code and generate additional information based on decorators. Let’s examine the result of this example code.</p><ol><li>First, we define a custom decorator called my_annotation that accepts two arguments, arg1 and arg2. This decorator is used to wrap a function called my_function.</li><li>Inside the my_function function, there&#39;s nothing exceptional going on. It simply returns the string &quot;Function result.&quot;</li><li>However, when we apply the @my_annotation(&quot;foo&quot;, &quot;bar&quot;) decorator to the my_function function, something interesting happens. The custom decorator is executed and wraps the function. It performs preprocessing based on the provided arguments, which are &quot;foo&quot; and &quot;bar&quot; in this case.</li><li>The result of the my_function function is retained, but the decorator also generates an additional string that incorporates the decorator&#39;s arguments. In this example, the generated code is &quot;Arg1: foo, Arg2: bar.&quot;</li><li>Finally, when we call my_function, it returns both the result of the function (&quot;Function result&quot;) and the code generated by the decorator (&quot;Arg1: foo, Arg2: bar&quot;).</li></ol><h3>Generating Methods</h3><p>In the code below, we will explore a powerful technique in Python that demonstrates how it is possible to use decorators for code generation. We will create a custom decorator called @Json, which will add a special method to a class. This method will allow objects of that class to automatically generate JSON-format representations of their properties, simplifying the serialization process. This is just a glimpse of the possibilities that decorators offer for customizing the behavior of classes in Python. Let&#39;s dive into this example and discover how the @Json decorator can facilitate code generation in your own implementations.</p><pre>import json<br><br># Define a @Json decorator<br>def Json(cls):<br>    &quot;&quot;&quot;<br>    Decorator to add a toJSON method to a class that returns a JSON representation<br>    of all object properties.<br>    &quot;&quot;&quot;<br>    def toJSON(self):<br>        return json.dumps({key: getattr(self, key) for key in self.__dict__})<br>    <br>    setattr(cls, &quot;toJSON&quot;, toJSON)<br>    return cls<br><br># Use the @Json decorator<br>@Json<br>class Person:<br>    def __init__(self, name, age):<br>        self.name = name<br>        self.age = age<br><br># Create an instance of the Person class<br>person = Person(&quot;Alice&quot;, 30)<br><br># Call the toJSON method to get a JSON representation of object properties<br>json_result = person.toJSON()<br>print(json_result)</pre><h3>Complex Example</h3><p>Imagine having a Python environment rich in configurations, where you can effortlessly load properties from a YAML file into your classes, similar to the functionality provided by `<a href="http://twitter.com/ConfigurationPropert">@ConfigurationPropert</a>ies` in Java’s Spring Boot. In this article, we will explore the creation of a custom decorator called `<a href="http://twitter.com/Property">@Property</a>`, which allows you to automatically load properties from a YAML file into your Python classes. This decorator will streamline configuration and customization of objects in your code, making it more flexible and reusable.</p><p>Let’s dive into the example and understand how the `<a href="http://twitter.com/Property">@Property</a>` decorator can be applied to load YAML configurations into Python classes, enabling you to focus your energy on developing features rather than worrying about configuration details.</p><h4>Define the @Property Decorator</h4><p>Start by defining the @Property decorator with a prefix parameter to specify the prefix for properties in the YAML file. For example:</p><pre>from dataclasses import dataclass<br><br>@dataclass<br>class Property:<br>    prefix: str</pre><h4>Create a Decorator for Classes</h4><p>Create a decorator that accepts a class decorated with the @Property decorator and loads values from the YAML file. Use a Python library like PyYAML to parse the YAML file. Here is a general outline of how this can be done:</p><pre>import yaml<br>import os<br><br>def load_yaml_properties(cls):<br>    yaml_path = f&quot;config/{cls.__name__.lower()}.yml&quot;  # Define the path to the YAML file<br>    if os.path.exists(yaml_path):<br>        with open(yaml_path, &quot;r&quot;) as yaml_file:<br>            yaml_data = yaml.safe_load(yaml_file)<br>            for key, value in yaml_data.items():<br>                setattr(cls, key, value)<br><br>    return cls<br><br>def Property(prefix):<br>    def decorator(cls):<br>        cls = load_yaml_properties(cls)<br>        return cls<br><br>    return decorator</pre><h4>Using the @Property Decorator</h4><p>Now you can use the @Property decorator on a class, specifying the prefix to load properties from the corresponding YAML file:</p><pre>@Property(&quot;app.config&quot;)<br>class AppConfig:<br>    pass</pre><h4>Configuration YAML File</h4><p>Make sure to create a corresponding YAML file with the desired properties and the specified prefix. For example, for the above code, you would have a “config/appconfig.yml” file with the desired properties:</p><pre>app:<br>  config:<br>    property1: value1<br>    property2: value2</pre><h4>Using the Properties</h4><p>Now, when you create an instance of the AppConfig class, the properties will be automatically loaded from the corresponding YAML file:</p><pre>config = AppConfig()<br>print(config.property1)  # This will print &quot;value1&quot;</pre><h4>Conclusion</h4><p>In the realm of Python development, custom decorators represent a powerful tool for enhancing code flexibility and maintainability. Our journey through this article has unveiled the potential of decorators, with a focus on the creation of the @Property decorator, which streamlines configuration management by loading properties from YAML files into Python classes.</p><p>However, it’s important to recognize that decorators in Python go far beyond this single use case. They serve as a versatile mechanism for adding metadata, behavior, and customization to classes, methods, and functions. Decorators empower developers to shape the behavior of their code, enhancing its readability, reusability, and adaptability.</p><p>Whether you’re creating custom decorators to simplify configuration, documenting code, or implementing design patterns, understanding the power of decorators is a valuable asset in your Python development toolbox. They provide an elegant means of conveying your intentions to other developers and even to the Python interpreter itself.</p><p>As we conclude our exploration of decorators, remember that Python’s flexibility allows you to tailor decorators to suit your specific needs and design goals. By harnessing the potential of decorators, you can create more expressive, maintainable, and powerful Python code. Embrace the versatility of decorators as you embark on your coding journey, and you’ll find that they are a valuable asset for building exceptional Python applications.</p><p>If you want to know a little more about me, follow my contacts:<br>GitHub: <a href="https://github.com/marcosstefani">https://github.com/marcosstefani</a><br>Linkedin: <a href="https://www.linkedin.com/in/marcosstefani">https://www.linkedin.com/in/marcosstefani</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ebabb5fcf9" width="1" height="1" alt=""><hr><p><a href="https://blog.devgenius.io/unlocking-the-power-of-python-decorator-ebabb5fcf9">Unlocking the Power of Python Decorator</a> was originally published in <a href="https://blog.devgenius.io/">Dev Genius</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Demystifying Functional Interfaces]]></title>
            <link>https://blog.devgenius.io/demystifying-functional-interfaces-8c9139460246?source=rss-f1aee1c7747f------2</link>
            <guid isPermaLink="false">https://medium.com/p/8c9139460246</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[how-to]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[interface-design]]></category>
            <dc:creator><![CDATA[Marcos Stefani Rosa]]></dc:creator>
            <pubDate>Wed, 06 Sep 2023 14:58:15 GMT</pubDate>
            <atom:updated>2023-10-11T10:53:03.827Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*mNg5R1UcSumjE5ut.jpg" /></figure><p>The Java programming language has long enjoyed a prominent place in the world of software development, thanks to its portability, robustness, and extensive developer community. However, over the years, the language has undergone a series of transformations to remain relevant and embrace emerging trends in the programming paradigm. One of the most significant of these transformations occurred with the introduction of “Functional Interfaces” in Java 8, which revolutionized how developers approach software development in Java.</p><p>Functional Interfaces represent a paradigm shift in Java, allowing for the adoption of functional programming in a more elegant and efficient manner. With the addition of features like lambda expressions and default methods in functional interfaces, Java opened the doors to a more concise, readable, and flexible programming style. This article delves deep into the world of Functional Interfaces in Java, exploring what they are, why they are important, and how they can be applied to enhance software development in Java.</p><p>In this article, we will explore Functional Interfaces in Java and how they can be used to improve code efficiency and readability. We will also discuss the benefits of embracing functional programming in Java and provide practical examples to illustrate their usage.</p><h4>Enhancing Code Efficiency and Readability with Functional Interfaces in Java</h4><p>One of the most notable features of Functional Interfaces in Java is the ability to utilize lambda expressions. These expressions allow developers to declare anonymous functions in a concise and straightforward manner, reducing the need to write an entire class just to implement a single functional interface. This results in more efficient code, as it eliminates the overhead of creating additional classes.</p><p>For example, prior to Java 8, if you wanted to sort a list of strings alphabetically, you would need to create a class that implemented the Comparator interface and then create an instance of that class to use it for sorting. With Functional Interfaces and lambda expressions, you can do this more efficiently:</p><pre>List&lt;String&gt; nameList = Arrays.asList(&quot;Alice&quot;, &quot;Bob&quot;, &quot;Charlie&quot;);<br><br>// Pre-Java 8<br>Collections.sort(nameList, new Comparator&lt;String&gt;() {<br>    public int compare(String a, String b) {<br>        return a.compareTo(b);<br>    }<br>});<br><br>// With lambda expressions<br>Collections.sort(nameList, (a, b) -&gt; a.compareTo(b));</pre><h4>Improving Readability with Functional Interfaces</h4><p>Another way in which Functional Interfaces enhance code quality in Java is through improved readability. With descriptive names for standard Functional Interfaces such as Predicate, Consumer, Function, and others, the code becomes more self-documenting. Developers can immediately understand the purpose of a lambda expression based on the context in which it is used.</p><p>Consider the following example where we want to filter a list of integers to find only the even numbers:</p><pre>List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5, 6);<br><br>// Without Functional Interfaces<br>List&lt;Integer&gt; evenNumbers = new ArrayList&lt;&gt;();<br>for (Integer number : numbers) {<br>    if (number % 2 == 0) {<br>        evenNumbers.add(number);<br>    }<br>}<br><br>// With Functional Interfaces<br>List&lt;Integer&gt; evenNumbers = numbers.stream()<br>                                    .filter(number -&gt; number % 2 == 0)<br>                                    .collect(Collectors.toList());</pre><p>The version that uses Functional Interfaces is more readable and closer to natural language. The expression number -&gt; number % 2 == 0 clearly describes the intention to filter even numbers.</p><p>In summary, Functional Interfaces in Java not only make the code more efficient by reducing class overhead but also significantly improve readability, making the code easier to understand and maintain. They empower developers to embrace a more expressive functional programming style, which can result in more robust and high-quality systems.</p><h4>Benefits of Functional Programming in Java</h4><ol><li><strong>Code Conciseness:</strong> Functional programming encourages the writing of short and reusable functions, resulting in more concise and readable code. By adopting lambda expressions and higher-order functions, developers can eliminate much of the boilerplate, making the code clearer and focused on essential logic. This not only speeds up development but also simplifies maintenance.</li><li><strong>Improved Readability:</strong> Functional programming emphasizes descriptive variable and function names, making the code easier to understand. This clarity is crucial in development teams as it allows members to quickly grasp the purpose of a function or expression. In contrast to imperative programming, where complex loops can obscure the code’s intent, functional programming promotes a more declarative and self-documenting style.</li><li><strong>Immutability:</strong> Immutability is a central principle in functional programming. In Java, you can create immutable objects using the final keyword. This ensures that once an object is created, it cannot be modified, avoiding undesirable side effects. Immutability makes the code more predictable and secure, as there are no unexpected changes in object state.</li><li><strong>Parallelism and Concurrency:</strong> Functional programming lends itself well to parallelism and concurrency. With the absence of mutable state and side effects, it becomes easier to write concurrent code without the risk of data races and deadlocks. Java offers libraries like the java.util.concurrent package, which work seamlessly with functional programming constructs to manage concurrent tasks efficiently.</li><li><strong>Testability:</strong> Functional programming promotes pure functions, which have no dependencies on mutable state or external factors. This purity makes it easier to write unit tests because you can predict the behavior of functions without worrying about hidden side effects. Test-driven development (TDD) and unit testing are more natural in a functional codebase.</li><li><strong>Code Reusability:</strong> Functional programming encourages the creation of small, reusable functions that can be composed to solve complex problems. Libraries and functions can be shared and reused across different parts of the codebase, reducing redundancy and making maintenance and updates more straightforward.</li><li><strong>Safety and Reliability:</strong> Functional programming minimizes the potential for errors and bugs by reducing mutable state and side effects. This leads to more predictable and reliable code, making it easier to identify and fix issues.</li><li><strong>Expressiveness:</strong> Functional programming allows for expressive and concise code. It focuses on “what” needs to be done rather than “how” it should be done, making the codebase more declarative and readable.</li></ol><h4>Practical Examples</h4><p><strong>Immutability:</strong> Creating immutable objects is a key practice in functional programming. Below is an example of an immutable class in Java:</p><pre>public final class ImmutablePerson {<br>    private final String name;<br>    private final int age;<br><br>    public ImmutablePerson(String name, int age) {<br>        this.name = name;<br>        this.age = age;<br>    }<br><br>    public String getName() {<br>        return name;<br>    }<br><br>    public int getAge() {<br>        return age;<br>    }<br>}</pre><p><strong>Recursion:</strong> Recursion is commonly used in functional programming to elegantly solve problems. Here’s an example of a recursive function that calculates the factorial of a number in Java:</p><pre>public static int factorial(int n) {<br>    if (n == 0) {<br>        return 1;<br>    } else {<br>        return n * factorial(n - 1);<br>    }<br>}</pre><p><strong>Higher-Order Functions:</strong> Higher-order functions can take other functions as arguments or return them as results. Below is an example that uses the map function to apply a function to each element of a list:</p><pre>List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);<br><br>List&lt;Integer&gt; squaredNumbers = numbers.stream()<br>                                       .map(x -&gt; x * x)<br>                                       .collect(Collectors.toList());</pre><p><strong>Parallelism and Concurrency:</strong> Here’s an example demonstrating how Java’s parallelStream can be used with functional programming to parallelize a computation:</p><pre>List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5, 6);<br><br>int sum = numbers.parallelStream()<br>                 .mapToInt(Integer::intValue)<br>                 .sum();</pre><p>This code parallelizes the summation of a list of integers, taking advantage of multi-core processors for improved performance.</p><p><strong>Testability:</strong> Consider a pure function that calculates the square of a number:</p><pre>public int square(int x) {<br>    return x * x;<br>}</pre><p>Testing this function is straightforward since it relies only on its input and produces a deterministic output. You can write unit tests to validate its behavior easily.</p><p><strong>Code Reusability:</strong> Functional programming encourages the use of higher-order functions like map, filter, and reduce. These functions can be reused across different data structures and scenarios. For example, you can use the same map function to transform elements in various collections.</p><p><strong>Safety and Reliability:</strong> By minimizing mutable state and side effects, functional programming helps avoid unexpected behavior. It reduces the chances of null pointer exceptions, unintended state changes, and hard-to-debug issues.</p><p><strong>Expressiveness:</strong> Functional code often reads like natural language, making it easier to understand the intent of the code. For instance, consider a Java stream pipeline that sums the squares of even numbers:</p><pre>int sumOfSquares = numbers.stream()<br>                         .filter(number -&gt; number % 2 == 0)<br>                         .mapToInt(x -&gt; x * x)<br>                         .sum();</pre><p>This code clearly expresses the intention to sum the squares of even numbers in the collection.</p><p>These examples demonstrate how functional programming in Java can lead to more efficient, readable, and reusable code. Adopting these principles and techniques can result in more robust and easily maintainable systems, aligning with modern trends in software development.</p><h4>Conclusion</h4><p>Throughout this article, we have explored the substantial benefits of adopting functional programming in Java, a language that has evolved considerably by incorporating the principles and practices of functional programming. In doing so, Java has become an even more powerful tool for developers seeking to write more efficient, readable, and secure code.</p><p>Code conciseness, improved readability, and an emphasis on immutability are just a few of the gains that functional programming brings to Java development. Lambda expressions, higher-order functions, and the stream library provide robust tools for creating more effective and scalable systems.</p><p>Furthermore, functional programming aligns perfectly with modern software development needs, such as parallelism, concurrency, and testability. It promotes the creation of safe, side-effect-free code, making it more predictable and reliable.</p><p>As illustrated through practical examples, functional programming in Java is not just a theoretical approach but a solid practice that can revolutionize how developers design, implement, and maintain their systems. Incorporating these principles into your development arsenal not only elevates code quality but also boosts productivity and responsiveness to the ever-changing demands of the software development world.</p><p>So, as you continue your journey as a Java developer, consider functional programming not just as an option but as a path that can open doors to new possibilities, significant improvements in software quality, and a more elegant approach to solving complex challenges. Make the most of this powerful and transformative approach, and allow functional programming in Java to take your projects and skills to a new level of excellence.</p><p>If you want to know a little more about me, follow my contacts:<br>GitHub: <a href="https://github.com/marcosstefani">https://github.com/marcosstefani</a><br>Linkedin: <a href="https://www.linkedin.com/in/marcosstefani">https://www.linkedin.com/in/marcosstefani</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8c9139460246" width="1" height="1" alt=""><hr><p><a href="https://blog.devgenius.io/demystifying-functional-interfaces-8c9139460246">Demystifying Functional Interfaces</a> was originally published in <a href="https://blog.devgenius.io/">Dev Genius</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Example of Hexagonal Architecture using Spring Boot+ Postgres]]></title>
            <link>https://blog.devgenius.io/example-of-hexagonal-architecture-using-spring-boot-postgres-504f62a33298?source=rss-f1aee1c7747f------2</link>
            <guid isPermaLink="false">https://medium.com/p/504f62a33298</guid>
            <category><![CDATA[hexagonal-architecture]]></category>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[java]]></category>
            <dc:creator><![CDATA[Marcos Stefani Rosa]]></dc:creator>
            <pubDate>Sun, 09 Apr 2023 00:41:14 GMT</pubDate>
            <atom:updated>2023-10-11T15:00:17.114Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/593/0*mjxHjNqKvWXXTstj.png" /></figure><p>Hexagon Architecture, also known as Ports and Adapters Architecture created by <a href="https://medium.com/u/5d6cbce7e05e">Alistair Cockburn</a>, is a software architecture pattern that aims to separate the business logic of the software from technical concerns such as the user interface and data storage. The idea is that the business logic can be modified and tested independently of the external technologies that surround it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*auXgR-_lYGML64zg.png" /></figure><p>One of the great advantages of the Hexagonal Architecture is the flexibility it offers. Because the architecture’s layers are clearly defined, it’s easy to add or modify components without affecting business logic. This makes the code more modular and easier to maintain.</p><p>Another advantage is the ease of testing the business logic. Since this layer is isolated, tests can be written without worrying about external technologies. This makes tests easier to write, faster to run, and more accurate.</p><p>Additionally, the Hexagonal Architecture facilitates the adoption of agile development practices such as continuous integration and continuous delivery. With clearly defined layers, it’s easy to automate testing and code integration.</p><p>Because I like this Design Pattern so much, I decided to write this article in order to help anyone who needs an example of development using Spring Boot and the PostgreSQL database. Sample project’s Git Repository:<br><a href="https://github.com/marcosstefani/java-hexagonal-example">https://github.com/marcosstefani/java-hexagonal-example</a></p><p>First of all, let’s make our docker-compose. To have a PosgtgreSQL running as a database and a RabbitMQ to exemplify a small use of MQ within this context:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1016/1*2NPQ1FJTLoCM8FScHboP5Q.png" /></figure><h4>About the Example:</h4><p>In the example I developed, we basically have an application that provides information about weather forecasts. The data is held in a Postgres database, but the original data source is from a third party that provides us with information for a certain period. With that in hand, our application will fetch this information from the third-party API, store it in history and make the stored information available.</p><p>So, in summary, we will have a cron that will run from time to time and publish in a <em>RabbitMQ</em> queue a request to update data by city already registered in the database.</p><p>We will also have a <em>RabbitListener</em> listening to this message and updating the requested city data.</p><p>And finally, we will have a <em>RestController</em> to make the data available through an API to add a new city for monitoring.</p><p>Below is our structure:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/444/1*hN0CEdyJe3VQF8ZCUX0nnA.png" /></figure><p>Note that the structure was divided into two parts (adapter and core), where we will have the core of our application without any external components and the adapter that will contain all the content of components external to the application. The communication between these two layers will happen through the ports that are in <em>out</em>. What comes from the controller will be in <em>in</em>, this is due to the concept of inputs and outputs, in our example our only input is through a controller, RabitMQ is only being used in a task of the application itself. Access the full examplo on <a href="https://github.com/marcosstefani/java-hexagonal-example">https://github.com/marcosstefani/java-hexagonal-example</a></p><h4>Conclusion:</h4><p>Based on the past <a href="https://github.com/marcosstefani/java-hexagonal-example">example</a>, it is clear that the Hexagonal Architecture is a very useful design pattern approach for separating the business logic of the software from technical concerns such as the user interface and data storage. By implementing the Hexagonal Architecture, we were able to isolate our application’s business logic into an independent layer, making it more flexible and easier to maintain.</p><p>Furthermore, implementing the Hexagonal Architecture allowed our tests to be more accurate and easier to write, as the business logic was isolated and not dependent on external technologies. This sped up our development process and ensured that our application was more reliable and robust.</p><p>It is important to emphasize that the Hexagonal Architecture is an approach that can be applied in different types of projects, from small applications to large distributed systems. It is particularly useful in projects that require high flexibility and scalability, as it allows the business logic to be easily adapted to handle changes in business requirements or underlying technologies.</p><p>In short, the Hexagonal Architecture is a powerful and flexible design pattern approach that can be applied in many software development projects. Its use makes it possible to separate business logic from technical concerns, increasing the application’s flexibility, ease of maintenance and reliability. It’s an approach worth considering in any software development project that requires high flexibility and scalability.</p><p>If you want to know a little more about me, follow my contacts:<br>GitHub: <a href="https://github.com/marcosstefani">https://github.com/marcosstefani</a><br>Linkedin: <a href="https://www.linkedin.com/in/marcosstefani">https://www.linkedin.com/in/marcosstefani</a><br>Page: <a href="https://marcosstefani.github.io/">https://marcosstefani.github.io</a></p><p>Thank you.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=504f62a33298" width="1" height="1" alt=""><hr><p><a href="https://blog.devgenius.io/example-of-hexagonal-architecture-using-spring-boot-postgres-504f62a33298">Example of Hexagonal Architecture using Spring Boot+ Postgres</a> was originally published in <a href="https://blog.devgenius.io/">Dev Genius</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Como deixar a interface do Ubuntu 20.04 parecida com a do MacOS]]></title>
            <link>https://marcosstefani.medium.com/como-deixar-a-interface-do-ubuntu-20-04-parecida-com-a-do-macos-4fc0bd3eca8c?source=rss-f1aee1c7747f------2</link>
            <guid isPermaLink="false">https://medium.com/p/4fc0bd3eca8c</guid>
            <category><![CDATA[ubuntu]]></category>
            <category><![CDATA[themes]]></category>
            <dc:creator><![CDATA[Marcos Stefani Rosa]]></dc:creator>
            <pubDate>Tue, 29 Jun 2021 03:42:43 GMT</pubDate>
            <atom:updated>2021-06-29T03:42:43.297Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fY4GTOZP_0QjMAh0TIPlmQ.png" /></figure><p>Você, como eu, já usou aquele MacOS na sua vida, aprendeu a gostar da interface e depois por meio de força maior ($$) resolveu usar o Linux, mas sempre fica aquele gostinho da usabilidade do MacOS? Ou você quer fazer com que seu Linux tenha aquela carinha bonitinha do MacOS? Então leia esse artigo até o fim. Aqui vou mostrar o passo-a-passo para que isso se torne uma realidade.</p><p>Bem, antes de mais nada gostaria deixar meu muito obrigado a todos os leitores que vem me incentivando a escrever aqui. Estou muito feliz com os feedbacks, procuro responder sempre! Vou deixar meus contatos abaixo para quem quiser trocar uma ideia:<br><strong>Linkedin</strong>: <a href="https://www.linkedin.com/in/marcosstefani/">https://www.linkedin.com/in/marcosstefani</a><br><strong>GitHub</strong>: <a href="https://github.com/marcosstefani">https://github.com/marcosstefani</a></p><p>Gostaria deixar claro, antes que me crucifiquem que tudo é uma questão de gosto, e como cada um tem o seu não me crucifique por favor. Esse tutorial é para pessoas que, como eu, AMAM o Ubuntu mas gostariam que ele tivesse aquela carinha discolada do MacOS por escolha ou por ter acostumado (como eu). Então vamos ao que interessa!</p><h4>Instalação do Gnome Tweak:</h4><p>A ferramenta Gnome Tweak é usada para personalizar a aparência e o comportamento do Ubuntu e servirá como ferramenta para personalizarmos nossa aparência. Para instalar, você precisa:</p><p>Adicionar o repositório:</p><pre>sudo add-apt-repository universe</pre><p>Com o repositório instalado, agora precisamos instalar o pacote do Tweak:</p><pre>sudo apt install gnome-tweak-tool</pre><p>Agora, precisaremos habilitar todas as extensões para posterior utilização:</p><pre>sudo apt install $(apt search gnome-shell-extension | grep ^gnome | cut -d / -f1)</pre><h4>Download do Tema McMojave:</h4><p>Antes de aplicar o tema McMojave, precisaremos instalar os seus pré-requisitos. Segue comando:</p><pre>sudo apt install gtk2-engines-murrine gtk2-engines-pixbuf</pre><p>Agora acesse a página abaixo e abra o menu Files.<br><a href="https://www.gnome-look.org/p/1275087/">https://www.gnome-look.org/p/1275087/</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/353/1*0Imhgm1yDPCXtbPXgrIRUA.png" /></figure><p>No meu exemplo fiz o download desse primeiro arquivo (<em>Mojave-dark.tar.xz</em>). Abri o terminal na pasta Downloads onde o arquivo se encontrava e digitei os seguintes comandos para descompactação do arquivo e movimentação da pasta para dentro de uma pasta .<em>themes</em> que será reconhecida pelo Tweak.</p><pre>tar xf Mojave-dark.tar.xz<br>mkdir ~/.themes<br>mv Mojave-dark ~/.themes/</pre><h4>Download dos Ícones:</h4><p>Agora faremos o mesmo, mas para baixar os arquivos que farão a configuração dos ícones. Para ficar igualzinho ao MacOS. Para isso, acesse a página abaixo e abra o menu Files:<br><a href="https://www.gnome-look.org/p/1210856/">https://www.gnome-look.org/p/1210856/</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/469/1*KbWe5A-pB5vNFz9sD-HBMA.png" /></figure><p>No meu exemplo fiz o download do segundo arquivo (<em>Mojave-CT-Night.tar</em>). Como no anterior, abri o terminal na pasta Downloads onde o arquivo se encontrava e digitei os seguintes comandos para descompactação do arquivo e movimentação da pasta para dentro de uma pasta .<em>icons</em> que será reconhecida pelo Tweak.</p><pre>tar xf Mojave-CT-Night.tar.xz<br>mkdir ~/.icons<br>mv Mojave-CT-Night ~/.icons/</pre><h4>Download do Cursor:</h4><p>Agora vamos deixar o cursor igual ao do MacOS. Para isso, acesse a página abaixo e abra o menu Files:<br><a href="https://www.gnome-look.org/p/1148748/">https://www.gnome-look.org/p/1148748/</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/341/1*knQiT_HGmlZ47xEQcNaXGA.png" /></figure><p>No caso, fiz o download do único arquivo que havia disponível (<em>macOs Cursor Set.zip</em>). Mais uma vez abri o terminal na pasta Downloads onde o arquivo se encontrava e digitei os seguintes comandos para descompactação do arquivo e movimentação da pasta para dentro de uma pasta .<em>icons</em> que será reconhecida pelo Tweak.</p><pre>unzip -qq macOS\ Cursor\ Set.zip<br>mv macOS\ Cursor\ Set ~/.icons/</pre><h4>Aplicação dos conteúdos baixados:</h4><p>Agora, com os arquivos necessários em mãos, vamos aplicar o que temos até o momento. Para isso abra o Tweak, que se encontra no seu menu de aplicativos. Em seguida vá na opção <em>Appearance </em>e altere as três primeiras opções como no exemplo abaixo:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/949/1*_JAzYHKkcwHFTZmMpIAf5w.png" /></figure><p>Ainda não acabou. Continue o tutorial para ter uma aparência ainda mais parecida.</p><h4>Instalando o Dock igual ao do MacOS:</h4><p>Agora iremos instalar um novo aplicativo chamado Plank. Ele substituirá o Dock padrão do Linux. Segue comando:</p><pre>sudo apt install plank</pre><p>Após instalação, abra o Plank no menu de aplicações:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jgY4AmWQLwexh77YyD-pKg.png" /></figure><p>Essa opção abrirá o Dock na parte inferior igual ao do MacOS.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*C-wN93bUWoSoa6M_l02ScA.png" /></figure><p>Agora, precisamos alterar as propriedades. Para isso, com o CONTROL apertado clique com o botão direito sobre o novo Dock e selecione a opção Preferences. Esta opção abrirá a tela abaixo, onde você pode configurar seu novo Dock da maneira que achar melhor. Segue o exemplo que utilizei:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/636/1*t-BrivMPHeB-V_oPYq-2dA.png" /></figure><p>É importante colocarmos agora o novo Dock na inicialização dos programas. Para isso abriremos o Tweaks novamente e na opção Startup Applications incluiremos o Plank:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/948/1*j6Y1QPKfEBY12XPE5iI6SQ.png" /></figure><p>Porém, agora você estará com os dois Docks em execução (o original do Ubuntu e o novo que acabamos de instalar). Para evitar essa duplicidade, precisaremos desinstalar o antigo com o seguinte comando:</p><pre>sudo apt remove gnome-shell-extension-ubuntu-dock</pre><p>Após esta desinstalação, faça o logout e login que seu Dock antigo sumirá e permanecerá apenas o novo.</p><h4>Alteração do Terminal:</h4><p>Eu, particularmente, gosto de mudar o meu terminal para ficar mais limpo e que apresente a branch do Git quando existir. Para isso, abro o arquivo <em>~./bashrc</em> e incluo a seguinte linha de comando no final do arquivo:</p><pre>export PS1=&#39;\[\033[01;34m\]\w\[\033[0;93m\]$(__git_ps1 &quot; (%s)&quot;)\[\033[01;34m\]$\[\033[00m\] &#39;</pre><p>Após salvar o arquivo, faça o logout e login novamente para aplicar a alteração. Eu também gosto de ir nas preferencias do e aplicar um pouco de transparência:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/762/1*JizUNsQdhKUE4Y9IQPnG6Q.png" /></figure><p>Dessa forma, tenho o seguinte resultado:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/780/1*iURzNNrAz-RYVZ2VlrF-bg.png" /></figure><h4>Conclusão:</h4><p>Se quiser ainda pode alterar o plano de fundo. No meu caso, eu fui no Google Images mesmo, busquei por <em>purple mac os wallpaper 1920 x 1080 </em>e fiz o download do que mais me agradou.</p><p>Espero que tenham gostado desse resultado. Um forte abraço.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4fc0bd3eca8c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spring Boot: Usando Propriedades da Aplicação — Arquivos de Configuração]]></title>
            <link>https://marcosstefani.medium.com/spring-boot-usando-propriedades-da-aplica%C3%A7%C3%A3o-arquivos-de-configura%C3%A7%C3%A3o-3c2b79a5a031?source=rss-f1aee1c7747f------2</link>
            <guid isPermaLink="false">https://medium.com/p/3c2b79a5a031</guid>
            <category><![CDATA[spring-framework]]></category>
            <category><![CDATA[spring]]></category>
            <category><![CDATA[architecture]]></category>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[spring-boot-2]]></category>
            <dc:creator><![CDATA[Marcos Stefani Rosa]]></dc:creator>
            <pubDate>Fri, 04 Jun 2021 16:00:45 GMT</pubDate>
            <atom:updated>2021-06-04T16:00:45.810Z</atom:updated>
            <content:encoded><![CDATA[<h3>Spring Boot: Usando Propriedades da Aplicação — Arquivos de Configuração</h3><p>Depois do sucesso do artigo <a href="https://inside.contabilizei.com.br/spring-boot-usando-propriedades-da-aplica%C3%A7%C3%A3o-fdb515c0d786"><em>Spring Boot: Usando Propriedades da Aplicação</em></a> percebi que muitas pessoas me vieram diretamente com dúvidas quanto ao uso efetivamente da propriedade em sua aplicação. Na ocasião eu fiz uma breve explicação do uso utilizando a anotação <strong><em>@Value</em></strong> do Spring Boot, e nesse artigo pretendo falar sobre o uso da aplicação utilizando classes de configuração que serão instanciadas com os valores das propriedades.</p><blockquote>Diferente do artigo anterior, estarei utilizando Java e o padrão yml no lugar do properties apenas para fins de apresentação, porém são decisões que optei para apresentar nesse artigo e tudo isso pode ser feito por exemplo em Kotlin e/ou em arquivos yml.</blockquote><h4>Quando e Porquê usar as classes no lugar da anotação?</h4><p>Penso que tudo depende da sua necessidade. Para ser sincero, prefiro evitar a anotação <strong><em>@Value </em></strong>pois além da classe facilitar bastante a questão dos testes unitários também evitamos repetição de declaração de variáveis que retornem os mesmos valores. Mas, como eu disse inicialmente, depende da necessidade, eu particularmente estou em um momento que ando preferindo utilizar classes com configurações por sentir que tudo fica muito mais organizado dessa forma.</p><h3>Hands on:</h3><p>Para fins de exemplo para este artigo, criaremos um arquivo application.yml para colocarmos as variáveis com valores default das minhas variáveis:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/251/1*svLZJxp6knCj2XzF5nsosg.png" /></figure><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/248c567b57d341f1510765c3e2b0b477/href">https://medium.com/media/248c567b57d341f1510765c3e2b0b477/href</a></iframe><p>Note acima que temos duas propriedades, elas estão no ambiente default do Spring Boot, e caso executemos a aplicação sem definição de ambiente, será aplicado diretamente os valores contidos nesse arquivo.</p><p>Agora faremos um segundo arquivo que sobrescreverá o valor de apenas uma das variáveis quando o ambiente for definido, no caso escolhi o ambiente <em>dev</em>, para isso nomearemos nosso arquivo com o complemento “-dev”, vide exemplo abaixo.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/292/1*niVrJAMvJM2BFIlw21y4TQ.png" /></figure><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/23d429fbc18d77a6875e93e8a7a25c6f/href">https://medium.com/media/23d429fbc18d77a6875e93e8a7a25c6f/href</a></iframe><p>Agora, só precisaremos criar um arquivo de configuração que fará a leitura dessas propriedades. Para isso, criaremos um <em>@Bean</em> do tipo <em>@Configuration </em>e acrescentaremos a anotação <em>@ConfigurationProperties</em> que conterá o valor do prefixo. Esse prefixo definirá dentro do aao nome drquivo properties qual é a segmentação que será lida por este arquivo. No nosso exemplo acima a segmentação será <em>some.property</em>, essa forma de leitura nos permite ter vários arquivos separados para cada segmentação.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6d2a73711885a8ae3dc4d1a2e1de1f5a/href">https://medium.com/media/6d2a73711885a8ae3dc4d1a2e1de1f5a/href</a></iframe><p>No exemplo acima, temos duas variáveis string recebendo com o mesmo nome da nossa propriedade, não é impossível utilziar outros tipos como inteiro ou até mesmo uma lista.</p><p>Outra informação é importante é relacionada ao nome da variável. Ele deve ser o mesmo que está no arquivo. Porém, quando necessitar alguma variável com nome em camel case, ela pode ser definida no arquivo properties tanto com o próprio camel case ou separado por ífem. (meuExemplo ou meu-exemplo) e no caso, na variável do java definindo como meuExemplo receberá de uma forma ou de outra o conteúdo.</p><p>Agora vamos testar nosso código, eu apenas vou colocar um print do conteúdo para exemplificar.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/68a7917cb547c32842a1b512375a9a26/href">https://medium.com/media/68a7917cb547c32842a1b512375a9a26/href</a></iframe><p>Agora, ao iniciarmos sem definir o profile (ex. <em>mvn spring-boot:run</em>) teremos o seguinte resultado:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-s1H5v_Me3-jXRWeq1R-Hw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/271/1*5vtQK48clYKoBYur5HvvMQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/377/1*oKLzhH1jmvuSyTKSZKMR3A.png" /></figure><p>Note acima que o profile definido é o default e as informações são as que estão dentro do meu application.yml.</p><p>Agora, se rodarmos definindo definindo um profile (ex. <em>mvn spring-boot:run -Dspring-boot.run.arguments=” — spring.profiles.active=dev”</em>) teremos os valores que estão no arquivo application-dev.yml como prioridade na leitura da informação. Então, o que estiver dentro dele será considerado e o que não estiver pegará de application.yml.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iV92zyriVv3a16AA0TIwRw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/287/1*6DIqGZZwjWj2aCWLCM8dCA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/286/1*4Y-V1n5pFAh9sTdgieijEg.png" /></figure><p>Dessa forma, evitamos a utilização do <em>@Value</em> para ler a variável de ambiente e não necessitamos necessariamente carregar as dependencias do Spring para realização de testes.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3c2b79a5a031" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Como Solicitar Atestado de Residência Fiscal no Brasil?]]></title>
            <link>https://marcosstefani.medium.com/como-solicitar-atestado-de-resid%C3%AAncia-fiscal-no-brasil-99453e4dcea3?source=rss-f1aee1c7747f------2</link>
            <guid isPermaLink="false">https://medium.com/p/99453e4dcea3</guid>
            <category><![CDATA[atestado]]></category>
            <category><![CDATA[rfb]]></category>
            <category><![CDATA[documentação]]></category>
            <category><![CDATA[rif]]></category>
            <dc:creator><![CDATA[Marcos Stefani Rosa]]></dc:creator>
            <pubDate>Fri, 26 Mar 2021 00:38:09 GMT</pubDate>
            <atom:updated>2022-01-24T15:55:17.411Z</atom:updated>
            <content:encoded><![CDATA[<p>Depois de algum esforço e retrabalho, consegui solicitar meu atestado de residência fiscal no Brasil. Este documento é necessário para que, quando se tem uma empresa e é necessário prestar serviço para uma empresa de outro país você não seja taxado duas vezes. Para mais detalhes sobre esta solicitação, segue <a href="https://receita.economia.gov.br/sobre/acoes-e-programas/grandes-eventos/atestado-de-residencia-fiscal">link</a> da receita.</p><p>Antes de mais nada, essa explicação é para pessoas com o mesmo cenário que eu. Tive que abrir uma empresa para prestar serviço a uma empresa do exterior e receberei mensalmente sob demanda.</p><p>Eu decidi seguir a orientação de alguns colegas que já passaram por isso e fui muito feliz até que, precisei refazer o pedido mas a forma de solicitar tinha mudado. Então, para que você não perca tempo na fila de atendimento por mais de 4 horas (como eu), a receita disponibilizou uma página para isso a partir do dia 12/03/2021 alterando assim a forma que essa solicitação é realizada. Então, segue os passos que tive que seguir de maneira detalhada:</p><h3>Anexo I</h3><p>Para realizar essa solicitação você precisa preencher esse documento. Ele pode ser acessado, juntamente com algumas explicações da receita federal por este <a href="http://normas.receita.fazenda.gov.br/sijut2consulta/anexoOutros.action?idArquivoBinario=18459">link</a>.</p><p>Com o documento em mãos, perceberá que o mesmo é dividido em três partes.</p><h4>Parte 1- Identificação do Contribuinte:</h4><p>Essa primeira parte deve ser preenchida por você com os dados da sua empresa (PJ). Lembrando que o campo Ramo de Atividade é o mesmo que estiver no seu contrato social, razão social e o endereço devem ser os informados no cadastro da empresa (Cartão CNPJ).</p><h4>Parte 2- Rendimentos Auferidos no Exterior:</h4><p>Essa segunda parte também deve ser preenchida por você e deve contar com os dados do contrato e valores contratados. Sendo eles:</p><p><strong>Valor bruto</strong>: Valor (em moeda estrangeira. ex: “20.000 euros”) total que pretende receber durante o contrato. Por exemplo, se seu contrato for de 6 meses inteiros, você deve somar todos os valores que prevê receber nesses meses. Caso seu contrato não finalize no ano corrente, considere para cálculo o último dia do ano.</p><p><strong>Imposto sobre Renda</strong>: Como você está trabalhando com uma previsão e emitirá notas mensais para a empresa que tens vínculo, deve colocar “A definir” nesse campo.</p><p><strong>Período de referência</strong>: Aqui você deve preencher a data de início e término do contrato. Geralmente o contrato, mesmo que for um contrato a ser renovado tem uma data de término e é esta data que deve ser preenchida e considerada. Caso essa data vire de ano, considere o último dia do ano pois eles não aceitarão a virada de ano.</p><p><strong>Convenção para evitar dupla tributação</strong>: Aqui colocará o país da empresa para a qual você prestará serviço.</p><p><strong>Tipo de rendimento e artigo correspondente da convenção</strong>: Neste campo você terá que preencher de acordo com o tipo de rendimento. No meu caso, eu procurei saber com meu contador que me explicou que isso é uma convenção internacional. Procure se informar do seu, mas no meu caso preenchi com o valor “Serv. Prof. Indep. de Tecnologia da Informação Art.14”.</p><p><strong>Nome e endereço da fonte pagadora</strong>: Aqui deves preencher os dados (nome e endereço completo) da empresa do exterior que está a contratar o seu serviço.</p><p><strong>Número de identificação fiscal da fonte pagadora</strong>: Aqui deves preencher com o número de identificação fiscal que a empresa que está contratando seu serviço deve fornecer.</p><h4>Parte 3- Declaração do contribuinte:</h4><p>Esta parte deve ser preenchida e assinada por você. Nela você informará os dados da sua pessoa física juntamente com a data que está assinando o documento.</p><h4>Parte 4- Declaração de autoridade tributária:</h4><p>Deixar essa parte em branco para preenchimento da receita federal.</p><h3>Acesso ao e-Cac:</h3><p>Agora com o documento preenchido corretamente, você deve tê-lo em seu computador em formato PDF. Bem como o Contrato Social da sua empresa e o Contrato com a empresa do exterior assinado por ambas as partes.</p><p>obs. Todos os passos a seguir, fiz em um PC com Windows pois não consegui fazer com que o software da receita federal (Assinador) funcionasse no Linux.</p><h4>Certificado Digital</h4><p>Agora será possível enviar a documentação para assinatura da receita federal, porém você precisará adquirir (caso não tenha) um certificado digital. Recomendo adquirir o certificado digital A1 que é a versão instalada no computador, geralmente é o mais barato e foi a que eu fiz e posso garantir que dá certo. Lembrando que deve ser um certificado digital oficial (consulte seu contador e peça indicação pois deve ser emitido apenas por empresas autorizadas).</p><p>obs importante: O certificado digital tem que ser da sua empresa (PJ) e não da sua pessoa física.</p><h4>Acesso à página do e-Cac.</h4><p>Com o certificado em mãos e instalado na sua máquina com SO Windows, vá ao portal do e-Cac, segue link. Lá abrirá a seguinte janela. Clique em Entrar com gov.br em seguida em Certificado Digital. Se por acaso o navegador solicitar que você selecione o certificado digital, selecione o da sua empresa que você acabara de instalar no seu computador.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*wmTz7Q-PNC4BJO72.png" /></figure><p>A parte que mudou no processo foi exatamente essa, a partir de 12/03/2021 quem abre o processo é você mesmo, sem necessidade de entrar no chat com um atendente. Isso facilita muito a velocidade. Para abrir uma solicitação, você vai selecionar a opção “Processos Digitais (e-Processo)” no menu:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/225/1*jMEvRzeMz4f5xB2G9NWsWA.png" /></figure><p>Em seguida selecione a opção “Solicitar Serviço via Processo Digital”:</p><p>Esta ação abrirá um formulário para preenchimento de informações. Preencha os dados conforme a imagem abaixo, alterando o número para o seu número de contato:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Bqx1v3dZ6xzCY9NnhYmICw.png" /></figure><p>Em seguida clique em “Abrir Dociê de Atendimento”. Quando o fizer, vai criar um dociê de atendimento que ficará no menu “Meus Processos”</p><p>Será exibido seu processo com os dados. Agora, vc precisa clicar no “+” que tem na coluna ações na linha que está o seu processo.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/96/1*heQlQ1Bt-kv5Jbd0UbhGBg.png" /></figure><p>Isso expandirá as opções para seu processo. Para enviar os documentos clique em “Solicitar Juntada de Documento”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/751/1*tsH7rmrJOXj2J3m4hmDc_A.png" /></figure><p>Para cada um dos documentos, você deverá agora clicar em Adicionar Documento para Rascunho:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/716/1*RM8j4HxYtgJxpRvD3WqRpg.png" /></figure><p>Você irá adicionar:</p><ul><li>O Anexo I preenchido, selecionar na lista dos tipos de documento como ATESTADO.</li><li>O Contrato Social da sua empresa para comprovar vínculo da pessoa física e jurídica que estão no Anexo I. Incluir como CONTRATO SOCIAL E ALTERAÇÕES.</li><li>O Contrato com a empresa no exterior, comprovando vínculo com a empresa no exterior informado no Anexo I. Incluir como CONTRATO-OUTROS.</li></ul><p>Após verificação do antivirus, será liberado o botão enviar. Mas para explica-lo melhor, vou criar um novo tópico.</p><h4>Enviar documentos com Assinador Serpro.</h4><p>Ao clicar no botão enviar a página lhe apresentará uma mensagem informando que é necessário o Assinador da Serpro para que sejam enviados os documentos. Para isso você precisará instalar o assinador que pode ser baixado a partir da página da receita. Eu sugiro ir pelo link abaixo pois se vocẽ baixar pelo link da mensagem necessariamente baixará o exe da versão para Sistemas Operacionais 32 bits, mas se você estiver utilizando um 64 bits como eu, não entenderá porquê não está funcionando. Se você instalou o de 32, desinstale e instale o de 64. Segue link do assinador: <a href="https://www.serpro.gov.br/links-fixos-superiores/assinador-digital/assinador-serpro">https://www.serpro.gov.br/links-fixos-superiores/assinador-digital/assinador-serpro</a></p><p>Após fazer o download, instale o assinador e o inicialize. Ele ficará com um íconezinho azul perto do seu relógio do Windows.</p><p>Importante: Execute o Assinador como administrador.</p><p>Após inicializado o assinador, volte na tela de envio e clique em enviar novamente. A mensagem de orientação será exibida novamente, mas você verá que no final da mensagem você terá um <em>“clique aqui caso tenha inicializado”. </em>Eu só não fiz um print porquê eu já enviei os meus arquivos e para simular eu precisaria enviar novamente. Ao clicar no link que ele diz, você deverá autorizar a página a executar, após essa autorização você voltando na aba do navegador que estava enviando os arquivos verá que o envio foi realizado com sucesso.</p><p>Aguarde alguns dias (talvez vocẽ precisará limpar seus cookies para logar novamente), voltando em “Meus Processos” você vai na opção “Consultar Documentos”, veja:</p><figure><img alt="" src="https://cdn-images-1.medium.com/proxy/1*tsH7rmrJOXj2J3m4hmDc_A.png" /></figure><p>Essa opção lhe exibirá o decorrer do processo, inclusive as respostas. Quando tudo der certo, você deverá receber o item “Atestado Assinado”, conforme imagem abaixo:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/188/1*wLEo2wb_cyShktT5u0x7Ww.png" /></figure><p>Selecione o mesmo e clique em “Obter Cópia Íntegra do Processo”. Isso fará você realizar o download de todo o processo em um arquivo Zip. Um dos arquivos é o seu arquivo assinado. No meu caso, o arquivo foi assinado digitalmente e não veio bem uma assinatura de punho, mas sim uma página que comprova a assinatura digital.</p><p>Espero ter ajudado de alguma forma.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=99453e4dcea3" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>