<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Lewis Gentle</title>
    <description>The latest articles on Forem by Lewis Gentle (@illegalbyte).</description>
    <link>https://forem.com/illegalbyte</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F682320%2F60295d5e-54a4-42d7-be4c-1a65ea636309.png</url>
      <title>Forem: Lewis Gentle</title>
      <link>https://forem.com/illegalbyte</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/illegalbyte"/>
    <language>en</language>
    <item>
      <title>Why I started an API service</title>
      <dc:creator>Lewis Gentle</dc:creator>
      <pubDate>Mon, 25 Jul 2022 08:49:00 +0000</pubDate>
      <link>https://forem.com/illegalbyte/why-i-started-an-api-service-3og3</link>
      <guid>https://forem.com/illegalbyte/why-i-started-an-api-service-3og3</guid>
      <description>&lt;p&gt;I recently launched an API for sending SMS – &lt;a href="https://smsjet.net"&gt;SMSjet.net&lt;/a&gt;. It has been one of the most fulfilling projects I've embarked on in a long time, and I wanted to share my story to hopefully inspire my fellow builders out there to build something you are proud of. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qcdwY2pO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bggzvuycnfhglagqtohj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qcdwY2pO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bggzvuycnfhglagqtohj.png" alt="SMSjet Banner" width="880" height="721"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GTFOL
&lt;/h2&gt;

&lt;p&gt;"Get the f*** off localhost" was a mantra that I'd read on Twitter, and it stuck with me. Too often as developers, we start building something out of curiosity or to teach ourselves something. We tinker, we add features, and we explore new ways of doing something, but we always do it at 127.0.0.1 / localhost. Our work is cut off from the world, and this separation more often than not leads to our side projects dying from a lack of oxygen. &lt;/p&gt;

&lt;p&gt;In building SMSjet I wanted to do something other than building 80% of the service and keep it isolated on my machine. I wanted this new site to live and breathe. I wanted there to be something at stake – I wanted to get the f*** off localhost. &lt;br&gt;
So I did. I bought a domain, I bought a cheap Linux VPS from Hetzner, I linked the two, and I began using VS Code's built-in SSH features to write my code directly on my production server. After a few setup commands and Django boilerplate – there it was, my new site, naked and exposed to the world in all its incompleteness. &lt;/p&gt;

&lt;p&gt;After I got over the initial fear that someone would uncover the IP, load my incomplete site and laugh at how nothing worked – &lt;em&gt;I felt free&lt;/em&gt;. After every change and incremental improvement, I had the choice of sending a friend the link and asking what they think of it. It felt real, and it was real. &lt;/p&gt;

&lt;p&gt;Getting the f*** off localhost may expose your unfinished work to prying eyes, but nobody will likely find your site without your help. Just make sure you set up a somewhat secure server environment, and you can build out in the open. &lt;/p&gt;

&lt;h2&gt;
  
  
  Ok but why an SMS API?
&lt;/h2&gt;

&lt;p&gt;I'm a big fan of Python and wanted to learn how the FastAPI library works. Previously I had created APIs through Django-REST API, but I never quite felt like I was "doing it right". One thing I love about FastAPI is how well documented it is. FastAPI's documentation is great. I honestly felt like a child would be able to build a REST interface if they read through the docs a couple of times.  &lt;/p&gt;

&lt;p&gt;It was on the backbone of my interest in exploring FastAPI that I built out some physical infrastructure to launch an SMS Gateway. The phrase "when you have a hammer, everything looks like a nail", should be rewritten for programmers: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you have a new library, everything looks like a viable SaaS idea&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What I love about FastAPI is how it is self-documenting. If you've written robust API code, your documentation will be robust. The Swagger Docs that FastAPI generates are also fully interactive, and allow you to enter real values and send requests straight from the documentation – &lt;a href="https://smsjet.net/docs"&gt;check it out here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;If you're feeling bored with development, throw yourself into the deep end. Go and find a technology you know next to nothing about, and build a product with it. You'll find yourself invigorated and excited about programming because &lt;strong&gt;you're not programming, &lt;em&gt;you're building&lt;/em&gt;.&lt;/strong&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Key Lessons
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Shipping a product doesn't have to be scary, you can even do it on Day 0 of development if you're brave.
&lt;/li&gt;
&lt;li&gt;Give your projects the chance to succeed by GTFOL&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building something is the best way to learn something new &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SMSjet is an awesome way to send SMS cheaply. &lt;strong&gt;&lt;a href="https://smsjet.net/signup"&gt;Sign up here and get 100 free credits to use for your next project&lt;/a&gt;&lt;/strong&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you're a fellow builder and want help setting up SMS for your bootstrapped project, &lt;a href="https://smsjet.net/contact"&gt;reach out here&lt;/a&gt;, I'd be more than happy to throw some more free credits your way. &amp;lt;3&lt;/p&gt;

</description>
      <category>api</category>
      <category>startup</category>
      <category>webdev</category>
      <category>python</category>
    </item>
    <item>
      <title>Project: How To Build a Simple &amp; Extendable Blogging Platform with Django &amp; Python</title>
      <dc:creator>Lewis Gentle</dc:creator>
      <pubDate>Sun, 02 Jan 2022 07:41:52 +0000</pubDate>
      <link>https://forem.com/illegalbyte/project-how-to-build-a-simple-extendable-blogging-platform-with-django-python-5g93</link>
      <guid>https://forem.com/illegalbyte/project-how-to-build-a-simple-extendable-blogging-platform-with-django-python-5g93</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;Recently I felt like I wanted to branch out and learn something new. I've always been interested in the practical and creative side of programming, so being able to deploy a project that is public facing was an exciting departure from the myriad of bespoke and educational Python scripts I've written.&lt;/p&gt;

&lt;p&gt;Django was exciting to me for a few reasons: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Popular and Scalable (Instagram, Spotify, Dropbox)&lt;/li&gt;
&lt;li&gt;Excellent Documentation&lt;/li&gt;
&lt;li&gt;Embraces Test Based Development &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I started my journey by cozying up with the official &lt;a href="https://docs.djangoproject.com/en/4.0/intro/tutorial01/" rel="noopener noreferrer"&gt;Django tutorial&lt;/a&gt; which teaches you how to write a simple poll app. This was a good intro, and opened my eyes to the simplicity and beauty of writing unit tests in Django. However, I wanted something a bit friendlier – something in-between a drawn out 4 hour monetised Youtube video, and the official documentation. This lead me to (DjangoGirls)[&lt;a href="https://tutorial.djangogirls.org/en/" rel="noopener noreferrer"&gt;https://tutorial.djangogirls.org/en/&lt;/a&gt;], an excellent bottom-up intro to Django with a focus on promoting Women in STEM. &lt;/p&gt;

&lt;p&gt;DjangoGirls might not appeal to those who claim to have been grinding out leetcode problems since kindergarten, but for me, the mid-paragraph smiley faces and congratulatory and plainspoken tone of the tutorials was perfect. &lt;/p&gt;

&lt;p&gt;I won't try to rework the great tutorial DjangoGirls has already put together, but rather add some additional resources that I found interesting and useful when putting my blog together.&lt;/p&gt;

&lt;h3&gt;
  
  
  PythonAnywhere
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://PythonAnywhere.com" rel="noopener noreferrer"&gt;PythonAnywhere.com&lt;/a&gt; makes deploying your Python projects on the web extremely simple (and free). &lt;/p&gt;

&lt;h3&gt;
  
  
  Virtual Environments (venv)
&lt;/h3&gt;

&lt;p&gt;Using a virtual environment at the start of your journey is incredibly important, although it might not seem like it at first, but it's crucial for making sure your code not only works on your machine, but will work for others. &lt;a href="https://tutorial.djangogirls.org/en/django_installation/#virtual-environment" rel="noopener noreferrer"&gt;See the DjangoGirls tutorial on starting a venv for your project&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Actions
&lt;/h3&gt;

&lt;p&gt;Automating the testing of your projects is incredibly important, and gives you an inexplicable insight into how your application truly works. Writing tests with Django isn't covered in the DjangoGirls tutorial, so for this I highly recommend this &lt;a href="https://docs.djangoproject.com/en/4.0/intro/tutorial05/" rel="noopener noreferrer"&gt;article in the official Django documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's an example of a simple test I wrote for the DjangoBlog which can be run through &lt;code&gt;python manage.py test&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IndexPageTests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_request_index_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;'''&lt;/span&gt;&lt;span class="s"&gt;
        Make sure the homepage is reachable
        &lt;/span&gt;&lt;span class="sh"&gt;'''&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_post_creation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;'''&lt;/span&gt;&lt;span class="s"&gt;
        Make sure the post creation is working
        &lt;/span&gt;&lt;span class="sh"&gt;'''&lt;/span&gt;
        &lt;span class="nf"&gt;create_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Test title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Test text&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Test title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_posts_are_visible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;'''&lt;/span&gt;&lt;span class="s"&gt;
        Make sure the posts are visible on the index page
        &lt;/span&gt;&lt;span class="sh"&gt;'''&lt;/span&gt;
        &lt;span class="nf"&gt;create_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Test title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Test text&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertContains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Test title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you've written your tests, you can actually get GitHub to run these tests on their servers through the magic of GitHub Actions – this means every new commit you make to your repo will get tested, and quickly let you know if you've broken anything before you get a chance break anything else.&lt;/p&gt;

&lt;p&gt;This is where your virtual environment becomes really useful. You'll need to provide GitHub with a &lt;code&gt;requirements.txt&lt;/code&gt; file which contains all of your projects dependencies. &lt;code&gt;pip&lt;/code&gt; can quickly generate this for you by running &lt;code&gt;$ pip freeze &amp;gt; requirements.txt&lt;/code&gt; from inside your virtual environment. &lt;a href="https://boscacci.medium.com/why-and-how-to-make-a-requirements-txt-f329c685181e" rel="noopener noreferrer"&gt;For a better understanding of the beauty of a venv, this article is excellent&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;requirements.txt&lt;/code&gt; in your root directory, go to your GitHub repo, click GitHub actions and select Django. This will create a &lt;code&gt;.github/workflows/django.yml&lt;/code&gt; file which tells GitHub how to test your codebase. Due to some incompatibilities, I was unable to get my code to pass using python 3.7, so I limited the testing scope to versions 3.8 in the &lt;code&gt;django.yml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;---snip---&lt;/span&gt;
    &lt;span class="s"&gt;strategy&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;max-parallel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;3.8&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;3.9&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="s"&gt;---snip---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that everything's setup, &lt;a href="https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/adding-a-workflow-status-badge" rel="noopener noreferrer"&gt;you can add a badge to your &lt;code&gt;README.md&lt;/code&gt; which will show whether your tests are passing&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fi3sz18lx1hs64sqjgk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fi3sz18lx1hs64sqjgk.png" alt="GitHub Actions Badge"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
    </item>
    <item>
      <title>import sanity: Python Modules That Keep Me Sane 🐍</title>
      <dc:creator>Lewis Gentle</dc:creator>
      <pubDate>Fri, 13 Aug 2021 02:23:16 +0000</pubDate>
      <link>https://forem.com/illegalbyte/import-sanity-python-modules-that-keep-me-sane-gma</link>
      <guid>https://forem.com/illegalbyte/import-sanity-python-modules-that-keep-me-sane-gma</guid>
      <description>&lt;p&gt;One of the many great things about the snake language (read: Python) is that there's a huge number of modules and libraries that we can easily tap into to make building cool stuff a lot easier. &lt;/p&gt;

&lt;p&gt;Python is unlike PHP, where a travelling function salesman will arrive every 2 minutes offering you a new built-in function (i.e. functions which are always accessible). Seriously, &lt;a href="https://www.w3schools.com/php/php_functions.asp"&gt;there are over 1000 built-in functions in PHP&lt;/a&gt;... whereas mere mortal &lt;a href="https://docs.python.org/3/library/functions.html"&gt;Python 3 has a humble 68 built-in functions&lt;/a&gt;. Thus, becoming great at Python requires being able to effectively navigate the zoo of Python modules out there (and getting really fast at smashing &lt;code&gt;pip install&lt;/code&gt; into your terminal. Unless of course you demand having absolute control over your entire codebase – in which case, maybe C++ is more your thing. &lt;/p&gt;

&lt;p&gt;With all that said, I'm a complete noob at programming. I know next to nothing. But I thought it might help some other beginners (and myself in 2 days when I forget one of these modules) to compile a list of modules I've found to be really useful. A lot of these are either written by Al Sweigart or I learned about them in his excellent book [Automate The Boring Stuff] which you can read free online(&lt;a href="https://automatetheboringstuff.com/"&gt;https://automatetheboringstuff.com/&lt;/a&gt;). Let's begin: &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;pyinputplus&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;One of the most exciting things I first learnt to do in Python was to take input from the user. It was magical. Until I realised how easy it was for users (aka me) to obliterate decimate my script by entering the wrong data type. This is known as input validation or 'accelerated grey hair growth'. &lt;code&gt;pyinputplus&lt;/code&gt; is a module which contains a bunch of really useful functions which ensure the user enters the data type you want, and how you want it. For example, you can make sure they enter a &lt;em&gt;goddamn positive integer&lt;/em&gt;: &lt;br&gt;
&lt;code&gt;pyinputplus.inputNum('Enter a positive number: ', min=1)&lt;/code&gt;&lt;br&gt;
Or get their favourite McDonald's breakfast item by prompting them with a list of lettered options:&lt;br&gt;
&lt;code&gt;choices = ['McMuffin', 'Hashbrown', 'Pancakes']&lt;br&gt;
pyip.inputMenu(choices, lettered=True)&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Please select one of the following:&lt;br&gt;
A. McMuffin&lt;br&gt;
B. Hashbrown&lt;br&gt;
C. Pancakes&lt;/strong&gt;&lt;br&gt;
Now taking orders is literally as easy as A, B, or C.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;pprint&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Sometimes when you're testing your code you just want to print a list or a dictionary in a more human friendly way. That's where prettyprint (&lt;code&gt;pprint&lt;/code&gt;) comes in. Simply give it a list and your dictionary will go from a mountain of text, to a nicely printed outline... of text. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;colorama&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;While we're talking about making things pretty and human friendly, colorama is what you should use if you want your terminal output to be ✨colourful✨. Sure you could use the ASCII escape codes or whatever, but these often fail across multiple platforms, and sometimes its easier to just enter something like: &lt;br&gt;
&lt;code&gt;print("New largest chain " + Fore.GREEN + str(largestChain) + Style.RESET_ALL)&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;pyperclip&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This module makes it easy to interact with and manipulate the users clipboard. Execute &lt;code&gt;pyperclip.copy(x)&lt;/code&gt; and &lt;code&gt;x&lt;/code&gt; will be copied to the users clipboard, and use &lt;code&gt;x = paperclip.past()&lt;/code&gt; and you'll have the users clipboard saved to x. &lt;/p&gt;




&lt;p&gt;Of course there are some more fundamental modules and libraries such as os, CSV, and pathlib, but I thought I'd focus more on the niche modules which do one thing well and incite sanity. &lt;/p&gt;

&lt;p&gt;💬 If you want to share your favourite python modules in the comments I'd love to hear about them! &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>python</category>
      <category>programming</category>
    </item>
    <item>
      <title>First AWS Certificate! 🎓☁️</title>
      <dc:creator>Lewis Gentle</dc:creator>
      <pubDate>Sun, 08 Aug 2021 12:49:41 +0000</pubDate>
      <link>https://forem.com/illegalbyte/first-aws-certificate-6no</link>
      <guid>https://forem.com/illegalbyte/first-aws-certificate-6no</guid>
      <description>&lt;p&gt;I know it's not an actual certification, but it feels like an important milestone on my cloud journey. So here it is, one of many to come, my first AWS certificate 🥳:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jskjuykd86ynfl4lg4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jskjuykd86ynfl4lg4u.png" alt="AWS Introduction to Serverless Certificate"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I learnt a lot about AWS and the power and efficiency of Lambda. Really excited to try it out soon. Time to get back to &lt;a href="https://automatetheboringstuff.com/2e/" rel="noopener noreferrer"&gt;Automate the Boring Stuff&lt;/a&gt;, so I can take my favourite reptile programming language on this plane to the cloud 😎.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>beginners</category>
      <category>cloudskills</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
