<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Real Python</title>
  <link href="https://realpython.com/atom.xml" rel="self"/>
  <link href="https://realpython.com/"/>
  <updated>2020-03-04T14:00:00+00:00</updated>
  <id>https://realpython.com/</id>
  <author>
    <name>Real Python</name>
  </author>

  
    <entry>
      <title>Alexa Python Development: Build and Deploy an Alexa Skill</title>
      <id>https://realpython.com/alexa-python-skill/</id>
      <link href="https://realpython.com/alexa-python-skill/"/>
      <updated>2020-03-04T14:00:00+00:00</updated>
      <summary>In this tutorial, you&#39;ll become an Alexa Python developer by deploying your own Alexa skill. You&#39;ll build an application that users will interact with using voice commands to Amazon Alexa devices. Your skill will respond back with a random joke when invoked by the user!</summary>
      <content type="html">
        &lt;p&gt;Smart home speakers were a novel idea just a couple of years ago. Today, they&amp;rsquo;ve become a central part of many people&amp;rsquo;s homes and offices and their adoption is only expected to grow. Among the most popular of these devices are those controlled by Amazon Alexa. In this tutorial, you&amp;rsquo;ll become an &lt;strong&gt;Alexa Python developer&lt;/strong&gt; by deploying your own Alexa skill, an application that users will interact with using voice commands to Amazon Alexa devices.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this tutorial, you&amp;rsquo;ll learn:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What&lt;/strong&gt; the main components of an Alexa skill are&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How&lt;/strong&gt; to set up an Alexa skill and create Intents&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What&lt;/strong&gt; the &lt;code&gt;ask_sdk_core&lt;/code&gt; Alexa Python package is&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How&lt;/strong&gt; to use &lt;code&gt;ask_sdk_core&lt;/code&gt; to create the business logic of your Alexa Python skill&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How&lt;/strong&gt; to build, deploy, and test your Alexa Python skill using the online developer console&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;#&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-speech-recognition-code&quot; data-focus=&quot;false&quot;&gt;Click here to download a  Python speech recognition sample project  with full source code &lt;/a&gt; that you can use as a basis for your own speech recognition apps.&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;getting-started-with-alexa-python-development&quot;&gt;Getting Started With Alexa Python Development&lt;/h2&gt;
&lt;p&gt;To follow this tutorial, you&amp;rsquo;ll need to make a free Alexa &lt;a href=&quot;https://developer.amazon.com/alexa/alexa-skills-kit&quot;&gt;developer account&lt;/a&gt;. On that page, you&amp;rsquo;ll take the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Click the &lt;em&gt;Get Started&lt;/em&gt; button.&lt;/li&gt;
&lt;li&gt;Click the &lt;em&gt;Sign-Up&lt;/em&gt; button on the subsequent page.&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;Create your Amazon Account&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Fill out the form with the required details.&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;Submit&lt;/em&gt; to complete the sign-up process.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You&amp;rsquo;ll also need to be familiar with concepts such as &lt;a href=&quot;https://realpython.com/courses/lists-tuples-python/&quot;&gt;lists&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/courses/dictionaries-python/&quot;&gt;dictionaries&lt;/a&gt; in Python, as well as JavaScript Object Notation (JSON). If you&amp;rsquo;re new to JSON, then check out &lt;a href=&quot;https://realpython.com/python-json/&quot;&gt;Working With JSON Data in Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s get started!&lt;/p&gt;
&lt;h2 id=&quot;understanding-alexa-skills&quot;&gt;Understanding Alexa Skills&lt;/h2&gt;
&lt;p&gt;An Alexa Python developer must be familiar with a number of different Alexa skill components, but the two most important components are the &lt;strong&gt;interface&lt;/strong&gt; and the &lt;strong&gt;service&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The skill interface&lt;/strong&gt; processes the user&amp;rsquo;s speech inputs and maps it to an intent.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The skill service&lt;/strong&gt; contains all the business logic that determines the response for a given user input and returns it as a JSON object.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The skill interface will be the &lt;strong&gt;frontend&lt;/strong&gt; of your Alexa skill. This is where you&amp;rsquo;ll define the intents and the invocation phrases that will perform a certain function. Essentially, this is the part of the skill that&amp;rsquo;s responsible for interacting with the users.&lt;/p&gt;
&lt;p&gt;The skill service will be the &lt;strong&gt;backend&lt;/strong&gt; of your Alexa skill. When a specific intent is triggered by the user, it will send that information as a request to the skill service. This will contain the business logic to be returned along with valuable information to the frontend, which will finally be relayed back to the user.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-your-environment&quot;&gt;Setting Up Your Environment&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s time to start building your first Alexa Python skill! Sign in to the Alexa &lt;a href=&quot;https://developer.amazon.com/alexa/console/ask/&quot;&gt;developer console&lt;/a&gt; and click on the &lt;em&gt;Create Skill&lt;/em&gt; button to get started. On the next page, enter the &lt;em&gt;Skill name&lt;/em&gt;, which will be &lt;em&gt;Joke Bot&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/rsz_ss14d396ae0c62c.f577b34c2dab.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/rsz_ss14d396ae0c62c.f577b34c2dab.png&quot; width=&quot;1172&quot; height=&quot;543&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/rsz_ss14d396ae0c62c.f577b34c2dab.png&amp;amp;w=293&amp;amp;sig=c3bf227e21b32bcf267e254812c7c04c5a44ca5a 293w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/rsz_ss14d396ae0c62c.f577b34c2dab.png&amp;amp;w=586&amp;amp;sig=6cbc37ad8a57eaf675e64c12aca4316037d025ba 586w, https://files.realpython.com/media/rsz_ss14d396ae0c62c.f577b34c2dab.png 1172w&quot; sizes=&quot;75vw&quot; alt=&quot;Creating a new Alexa Skill&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This will be the &lt;strong&gt;invocation phrase&lt;/strong&gt; of your skill. It&amp;rsquo;s the phrase a user will speak to start using your Alexa skill. You can change this to something else later on if you&amp;rsquo;d like. Also, note that Alexa skills can interact in many languages, which you can see from the &lt;em&gt;Default Language&lt;/em&gt; dropdown menu. For now, just set it to &lt;em&gt;English (US)&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Next, you&amp;rsquo;ll need to choose a model to add to your skill. These &lt;strong&gt;models&lt;/strong&gt; are like templates that have been pre-designed by the Amazon team to help you get started with Alexa Python development, based on some common use cases. For this tutorial, you should select the &lt;em&gt;Custom&lt;/em&gt; model.&lt;/p&gt;
&lt;p&gt;Finally, you need to select a method to host the backend of your Alexa skill. This service will contain the business logic of your application.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you select the &lt;em&gt;Provision your own&lt;/em&gt; option, then you&amp;rsquo;ll have to host your own backend for your Alexa Python projects. This can be an API built and hosted on a platform of your choice. The other option is to create a separate AWS Lambda function and link it to your Alexa skill. You can learn more about AWS Lambda pricing on their &lt;a href=&quot;https://aws.amazon.com/lambda/pricing/&quot;&gt;pricing page&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;For now, select &lt;em&gt;Alexa-Hosted (Python)&lt;/em&gt; as the backend for your Alexa skill. This will automatically provide you with a hosted backend within the AWS free tier so you don&amp;rsquo;t have to pay anything upfront or set up a complicated backend right now.&lt;/p&gt;
&lt;p&gt;Finally, click the &lt;em&gt;Create Skill&lt;/em&gt; button to proceed. You might be asked to fill out a CAPTCHA here, so complete that as well. After a minute or so, you should be redirected to the &lt;em&gt;Build&lt;/em&gt; section of the developer console.&lt;/p&gt;
&lt;h2 id=&quot;understanding-the-alexa-skill-model&quot;&gt;Understanding the Alexa Skill Model&lt;/h2&gt;
&lt;p&gt;Once you&amp;rsquo;ve logged into the Alexa developer console and selected or created a skill, you&amp;rsquo;ll be greeted with the &lt;em&gt;Build&lt;/em&gt; section. This section provides you with a lot of options and controls to set up the &lt;strong&gt;interaction model&lt;/strong&gt; of the skill. The components of this interaction model allow you to define how the users will interact with your skill. These properties can be accessed through the left-side panel, which looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/components.442664358f41.442664358f41.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-33&quot; src=&quot;https://files.realpython.com/media/components.442664358f41.442664358f41.png&quot; width=&quot;774&quot; height=&quot;1356&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/components.442664358f41.442664358f41.png&amp;amp;w=193&amp;amp;sig=085789432760f1905b78258d8a8551b89a313259 193w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/components.442664358f41.442664358f41.png&amp;amp;w=387&amp;amp;sig=f3f4f538fdf5c36c25514b8801734555161bc33b 387w, https://files.realpython.com/media/components.442664358f41.442664358f41.png 774w&quot; sizes=&quot;75vw&quot; alt=&quot;Alexa Developer Console Walkthrough&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As an Alexa Python developer, there are a few components of an Alexa skill interaction model that you&amp;rsquo;ll need to know about. The first is the &lt;strong&gt;invocation&lt;/strong&gt;. This is what users will say to begin interacting with your Alexa skill. For example, the user will say, &amp;ldquo;Joke Bot,&amp;rdquo; to invoke the Alexa skill you&amp;rsquo;ll build in this tutorial. You can change this from the &lt;em&gt;Invocation&lt;/em&gt; section at any time.&lt;/p&gt;
&lt;p&gt;Another component is the &lt;strong&gt;intent&lt;/strong&gt;, which represents the core functionality of your application. Your app will have a set of intents that will represent what kinds of actions your skill can perform. To provide contextual information for a given intent, you&amp;rsquo;ll use a &lt;strong&gt;slot,&lt;/strong&gt; which is a variable in an utterance phrase.&lt;/p&gt;
&lt;p&gt;Consider the following example. A sample utterance to invoke the weather intent could be, &amp;ldquo;Tell me about the weather.&amp;rdquo; To make the skill more useful, you can set the intent to be, &amp;ldquo;Tell me about the weather in Chicago,&amp;rdquo; where the word &amp;ldquo;Chicago&amp;rdquo; will be passed as a slot variable, which improves the user experience.&lt;/p&gt;
&lt;p&gt;Lastly, there are &lt;strong&gt;slot types,&lt;/strong&gt; which define how data in a slot is handled and recognized. For example, the &lt;em&gt;AMAZON.DATE&lt;/em&gt; slot type easily converts words that indicate a date&amp;mdash;like &amp;ldquo;today, &amp;ldquo;tomorrow&amp;rdquo;, and others&amp;mdash;into a standard date format (such as &amp;ldquo;2019-07-05&amp;rdquo;). You can check out the official slot type &lt;a href=&quot;https://developer.amazon.com/docs/custom-skills/slot-type-reference.html&quot;&gt;reference page&lt;/a&gt; to learn more.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To learn more about the Alexa skill interaction model, check out the &lt;a href=&quot;https://developer.amazon.com/docs/alexa-voice-service/interaction-model.html&quot;&gt;official documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;At this point, the &lt;em&gt;Intents&lt;/em&gt; panel should be open. If it&amp;rsquo;s not, then you can open it by selecting &lt;em&gt;Intents&lt;/em&gt; from the sidebar on the left. You&amp;rsquo;ll notice that there are five intents already set up by default:  &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/rsz_ss26aa1e156bb49.7c6d5647d31a.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/rsz_ss26aa1e156bb49.7c6d5647d31a.png&quot; width=&quot;1382&quot; height=&quot;776&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/rsz_ss26aa1e156bb49.7c6d5647d31a.png&amp;amp;w=345&amp;amp;sig=5ef1cff5e747123d4520466b758af4539d3f6c6d 345w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/rsz_ss26aa1e156bb49.7c6d5647d31a.png&amp;amp;w=691&amp;amp;sig=102de02b68d6f8519ebe28424d4f1454b9b7eba6 691w, https://files.realpython.com/media/rsz_ss26aa1e156bb49.7c6d5647d31a.png 1382w&quot; sizes=&quot;75vw&quot; alt=&quot;Alexa Developer Console Intents Panel&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;Intents&lt;/em&gt; panel includes a &lt;em&gt;HelloWorldIntent&lt;/em&gt; and five &lt;em&gt;Built-in Intents&lt;/em&gt;. The built-in intents are there to remind you to account for some common cases that are important to making a user-friendly bot. Here&amp;rsquo;s a brief overview:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;AMAZON.CancelIntent&lt;/strong&gt; lets the user cancel a transaction or task. Examples include, &amp;ldquo;Never mind,&amp;rdquo; &amp;ldquo;Forget it,&amp;rdquo; &amp;ldquo;Exit,&amp;rdquo; and &amp;ldquo;Cancel,&amp;rdquo; though there are others.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AMAZON.HelpIntent&lt;/strong&gt; provides help about how to use the skill. This could be used to return a sentence that serves as a manual for the user on how to interact with your skill.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AMAZON.StopIntent&lt;/strong&gt; allows the user to exit the skill.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AMAZON.NavigateHomeIntent&lt;/strong&gt; navigates the user to the device home screen (if a screen is being used) and ends the skill session.  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By default, there are no sample utterances assigned to trigger these intents, so you&amp;rsquo;ll have to add those as well. Consider it part of your training as an Alexa Python developer. You can learn more about these built-in intents in the &lt;a href=&quot;https://developer.amazon.com/docs/custom-skills/standard-built-in-intents.html&quot;&gt;official documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;viewing-a-sample-intent&quot;&gt;Viewing a Sample Intent&lt;/h2&gt;
&lt;p&gt;Later in this tutorial, you&amp;rsquo;ll learn how to make a new intent, but for now, it&amp;rsquo;s a good idea to take a look at some existing intents that are part of every new skill you create. To start, click the &lt;em&gt;HelloWorldIntent&lt;/em&gt; to see its properties:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screen_Shot_2019-12-03_at_5.45.16_PM.8f3ef9cdb9e4.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screen_Shot_2019-12-03_at_5.45.16_PM.8f3ef9cdb9e4.png&quot; width=&quot;1444&quot; height=&quot;819&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screen_Shot_2019-12-03_at_5.45.16_PM.8f3ef9cdb9e4.png&amp;amp;w=361&amp;amp;sig=d0814ebfd12be6e74f93977c02de05120be0d48f 361w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screen_Shot_2019-12-03_at_5.45.16_PM.8f3ef9cdb9e4.png&amp;amp;w=722&amp;amp;sig=e2004316c907bb29e125f6487a6e708208e5a7e4 722w, https://files.realpython.com/media/Screen_Shot_2019-12-03_at_5.45.16_PM.8f3ef9cdb9e4.png 1444w&quot; sizes=&quot;75vw&quot; alt=&quot;Hello World Intent Properties&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can see the sample utterances that a user can speak to invoke this intent. When this intent is invoked, this information is sent to the backend service of your Alexa skill, which will then execute the required business logic and return a response. &lt;/p&gt;
&lt;p&gt;Below this, you have the option to set up the &lt;em&gt;Dialog Delegation Strategy&lt;/em&gt;, which allows you to delegate a specific &lt;strong&gt;dialog&lt;/strong&gt; that you define to a particular intent. While you won&amp;rsquo;t cover this in this tutorial, you can read more about it in the &lt;a href=&quot;https://developer.amazon.com/docs/custom-skills/delegate-dialog-to-alexa.html&quot;&gt;official documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, you have the option to define &lt;strong&gt;slots&lt;/strong&gt; for some particular data that your intent is supposed to collect. For example, if you were to create an intent that tells the weather for a given day, then you&amp;rsquo;d have a &lt;em&gt;Date&lt;/em&gt; slot here that would collect the date information and send it to your backend service.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In addition, the &lt;em&gt;Intent Confirmation&lt;/em&gt; option can be useful in a case when you&amp;rsquo;re collecting a number of different data points from your user in a single intent and you want to prompt the user before sending it on for further processing.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Whenever you make changes to an intent, you need to click the &lt;em&gt;Save Model&lt;/em&gt; button to save it. Then, you can click the &lt;em&gt;Build Model&lt;/em&gt; button to go ahead and test your Alexa Python skill.   &lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s helpful to know that the interaction model of a skill can be completely represented in a &lt;a href=&quot;https://realpython.com/python-json/&quot;&gt;JSON&lt;/a&gt; format. To see the current structure of your Alexa skill, click the &lt;em&gt;JSON Editor&lt;/em&gt; option from the left side panel of the console:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/rsz_ss3dde2441e6146.a5821b82c1e4.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/rsz_ss3dde2441e6146.a5821b82c1e4.png&quot; width=&quot;1197&quot; height=&quot;833&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/rsz_ss3dde2441e6146.a5821b82c1e4.png&amp;amp;w=299&amp;amp;sig=2c6cb86cb82f3b3450a2ff9f4b89c336cc788728 299w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/rsz_ss3dde2441e6146.a5821b82c1e4.png&amp;amp;w=598&amp;amp;sig=8836a07f1cc87c5e93ba1bed58bd7c0037725b2f 598w, https://files.realpython.com/media/rsz_ss3dde2441e6146.a5821b82c1e4.png 1197w&quot; sizes=&quot;75vw&quot; alt=&quot;Alexa Developer Console JSON Editor&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you make a change directly using the JSON editor, then the changes are also reflected in the developer console UI. To test this behavior, add a new intent and click &lt;em&gt;Save Model&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;ve made all the necessary changes to the interaction model of your skill, you can open the &lt;em&gt;Test&lt;/em&gt; section of the developer console to test out your skill. &lt;a href=&quot;https://realpython.com/tutorials/testing/&quot;&gt;Testing&lt;/a&gt; is an important part of becoming an Alexa Python developer, so be sure not to skip this step! Click the &lt;em&gt;Test&lt;/em&gt; button from the top navigation bar on the developer console. By default, testing will be disabled. From the drop-down menu, select &lt;em&gt;Development&lt;/em&gt; to start testing:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/test.c65ec189bf61.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/test.c65ec189bf61.png&quot; width=&quot;1067&quot; height=&quot;619&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/test.c65ec189bf61.png&amp;amp;w=266&amp;amp;sig=39bf9a197a434d561bb3ab8b3f5d6bdfe09acc7b 266w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/test.c65ec189bf61.png&amp;amp;w=533&amp;amp;sig=87c29e52ef854bb9ea5cc56d0312cf63745b306d 533w, https://files.realpython.com/media/test.c65ec189bf61.png 1067w&quot; sizes=&quot;75vw&quot; alt=&quot;Alexa Developer Console Test Section&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here, you have a number of ways that you can test out your Alexa Python skill. Let&amp;rsquo;s do a quick test so that you can get an idea of how your Alexa skill will respond to an utterance.&lt;/p&gt;
&lt;p&gt;Select the &lt;em&gt;Alexa Simulator&lt;/em&gt; option from the left side panel, then enter the phrase, &amp;ldquo;Hey Alexa, open Joke Bot.&amp;rdquo; You can do this either by typing it in the input box or by using the &lt;em&gt;Mic&lt;/em&gt; option. After a couple of seconds, a response will be returned back to you:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/test1.41e2a0b676ce.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/test1.41e2a0b676ce.png&quot; width=&quot;1061&quot; height=&quot;1085&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/test1.41e2a0b676ce.png&amp;amp;w=265&amp;amp;sig=7175dad78f92637d31a81d6abd0e42d93618a77e 265w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/test1.41e2a0b676ce.png&amp;amp;w=530&amp;amp;sig=58375582722b4b9e3f13d15fccc4c591661f9ee8 530w, https://files.realpython.com/media/test1.41e2a0b676ce.png 1061w&quot; sizes=&quot;75vw&quot; alt=&quot;Testing Alexa Simulator&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In addition to the voice response, you can also see the &lt;em&gt;JSON Input&lt;/em&gt; that was sent to the backend service of your Alexa skill, as well as the &lt;em&gt;JSON Output&lt;/em&gt; that was received back to the console:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/rsz_ss4aaaa59ee1211.05a43bc88bb8.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/rsz_ss4aaaa59ee1211.05a43bc88bb8.png&quot; width=&quot;1244&quot; height=&quot;518&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/rsz_ss4aaaa59ee1211.05a43bc88bb8.png&amp;amp;w=311&amp;amp;sig=a31c51b8c343d2a533c45dfe9cfad7bb52e8b494 311w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/rsz_ss4aaaa59ee1211.05a43bc88bb8.png&amp;amp;w=622&amp;amp;sig=bc6745dddf4576a37f61de1cdd9ca86b02f9b313 622w, https://files.realpython.com/media/rsz_ss4aaaa59ee1211.05a43bc88bb8.png 1244w&quot; sizes=&quot;75vw&quot; alt=&quot;Alexa Skill Test JSON Input/Output&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what&amp;rsquo;s happened so far:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The JSON input object&lt;/strong&gt; was constructed from input data that the user entered through voice or text.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Alexa simulator&lt;/strong&gt; packaged up the input along with other relevant metadata and sent it to the backend service. You can see this in the &lt;em&gt;JSON Input&lt;/em&gt; box.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The backend service&lt;/strong&gt; received the input JSON object and parsed it to check the type of the request. Then, it passed the JSON to the relevant intent handler function.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The intent handler function&lt;/strong&gt; processed the input and gathered the required response, which is sent back as a JSON response to the Alexa simulator. You can see this in the &lt;em&gt;JSON Output&lt;/em&gt; box.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Alexa simulator&lt;/strong&gt; parsed this JSON and read the speech response back to you.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can read about the JSON request-response mechanism for Alexa skills in the &lt;a href=&quot;https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html&quot;&gt;official docs&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now that you have an overview of the different components of an Alexa skill and how information flows from one part to the other, it&amp;rsquo;s time to start building your Joke Bot! In the next section, you&amp;rsquo;ll put your Alexa Python developer skills to the test by creating a new intent.&lt;/p&gt;
&lt;h2 id=&quot;creating-new-intents&quot;&gt;Creating New Intents&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start by creating the &lt;em&gt;JokeIntent&lt;/em&gt;, which will return a random joke from a list to the user. Open the &lt;em&gt;Build&lt;/em&gt; section of your Alexa developer console. Then, click the &lt;em&gt;Add&lt;/em&gt; button next to the &lt;em&gt;Intents&lt;/em&gt; option from the left side panel:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/add_intent.83b98dc3d444.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-33&quot; src=&quot;https://files.realpython.com/media/add_intent.83b98dc3d444.png&quot; width=&quot;772&quot; height=&quot;588&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/add_intent.83b98dc3d444.png&amp;amp;w=193&amp;amp;sig=d41b49c0564791485096c777593c9ca52f5c41fb 193w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/add_intent.83b98dc3d444.png&amp;amp;w=386&amp;amp;sig=68b9803e31a4cb9b4ecea5044c8cc864544c2092 386w, https://files.realpython.com/media/add_intent.83b98dc3d444.png 772w&quot; sizes=&quot;75vw&quot; alt=&quot;Add new Intent&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With the &lt;em&gt;Create custom intent&lt;/em&gt; option selected, set the name to &lt;em&gt;JokeIntent&lt;/em&gt; and then click the &lt;em&gt;Create custom intent&lt;/em&gt; button:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/create_intent_1.3a639ddecc35.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/create_intent_1.3a639ddecc35.png&quot; width=&quot;1762&quot; height=&quot;619&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/create_intent_1.3a639ddecc35.png&amp;amp;w=440&amp;amp;sig=fc302649af63536ecc995c48c924b87b5e44b4d6 440w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/create_intent_1.3a639ddecc35.png&amp;amp;w=881&amp;amp;sig=c8564d222e7e47b363e62ed1366db3a212ec5c61 881w, https://files.realpython.com/media/create_intent_1.3a639ddecc35.png 1762w&quot; sizes=&quot;75vw&quot; alt=&quot;Create new Intent&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Next, you need to add &lt;strong&gt;sample utterances&lt;/strong&gt; that the user will speak to invoke this intent. These can be phrases like &amp;ldquo;Tell me a joke&amp;rdquo; or &amp;ldquo;I want to hear a joke.&amp;rdquo; Type in a phrase and click the plus sign (&lt;code&gt;+&lt;/code&gt;) to add it as a sample utterance. Here&amp;rsquo;s what that should look like:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/added_sample_utterances.68d9b9902807.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/added_sample_utterances.68d9b9902807.png&quot; width=&quot;1832&quot; height=&quot;889&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/added_sample_utterances.68d9b9902807.png&amp;amp;w=458&amp;amp;sig=ddcc7ba178f5343b5068c4d334f75a7bed4e3fd3 458w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/added_sample_utterances.68d9b9902807.png&amp;amp;w=916&amp;amp;sig=52988a801ab2e2275f3c784d8162efb4f8e0b52e 916w, https://files.realpython.com/media/added_sample_utterances.68d9b9902807.png 1832w&quot; sizes=&quot;75vw&quot; alt=&quot;Add sample utterances for Intent&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can add more sample utterances, but for now, these will do just fine. Lastly, click the &lt;em&gt;Save Model&lt;/em&gt; button in the top-left corner of the window to save these changes.&lt;/p&gt;
&lt;p&gt;Remember, you&amp;rsquo;ll need to &lt;strong&gt;build your model&lt;/strong&gt; before you can test it out. Click the &lt;em&gt;Build Model&lt;/em&gt; button to re-build the interaction model of your Alexa Python skill. You&amp;rsquo;ll see a progress notification on the bottom-right of your browser window. Once the build process is successful, you should see another pop-up notification indicating the status of the build process.&lt;/p&gt;
&lt;p&gt;You can check to see if the &lt;em&gt;JokeIntent&lt;/em&gt; is successfully triggered or not. Click the &lt;em&gt;Evaluate Model&lt;/em&gt; button in the top-right corner of the developer console. A small window will pop in from the side allowing you to check what intent will be triggered by a given input utterance. Type in any of the sample utterances to make sure that the &lt;em&gt;JokeIntent&lt;/em&gt; is being invoked successfully.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/gg_.2c0f35cf46a8.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/gg_.2c0f35cf46a8.png&quot; width=&quot;1553&quot; height=&quot;1388&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/gg_.2c0f35cf46a8.png&amp;amp;w=388&amp;amp;sig=a65871841e658f13a62dd1f1d68c19c9d393fa15 388w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/gg_.2c0f35cf46a8.png&amp;amp;w=776&amp;amp;sig=8b4bf36c44ef6bd89e2434b69fa177b7030278cd 776w, https://files.realpython.com/media/gg_.2c0f35cf46a8.png 1553w&quot; sizes=&quot;75vw&quot; alt=&quot;Evaluate Interaction Model&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To get rid of the evaluate pop-up window, click the &lt;em&gt;Evaluate Model&lt;/em&gt; button again.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A key thing to remember here is that the model is very flexible in terms of the keywords that are part of the sample utterance phrases. For example, take the phrase, &amp;ldquo;Is this some kind of a joke?&amp;rdquo; Even this phrase will trigger the &lt;em&gt;JokeIntent&lt;/em&gt;. As an Alexa Python developer, it&amp;rsquo;s important to select utterances that have a low probability of executing other intents in your skill.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now that you&amp;rsquo;ve successfully created an intent, it&amp;rsquo;s time to write the Python code that will handle this intent and return back a joke as a response.&lt;/p&gt;
&lt;h2 id=&quot;building-the-skill-backend&quot;&gt;Building the Skill Backend&lt;/h2&gt;
&lt;p&gt;Now that you have an intent created that can be triggered by the user, you need to add &lt;strong&gt;functionality&lt;/strong&gt; in the skill backend to handle this intent and return useful information. Open the &lt;em&gt;Code&lt;/em&gt; section of the Alexa developer console to get started.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Since you selected the Alexa-Hosted Python option during the setup process, you&amp;rsquo;re provided with a complete online code editor where you can write, test, build, and deploy the backend of your Alexa skill, all within the developer console.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;When you open the &lt;em&gt;Code&lt;/em&gt; section of the developer console, you can see an online code editor with some files already set up for you to get started. In particular, you&amp;rsquo;ll see the following three files in the &lt;em&gt;lambda&lt;/em&gt; sub-directory:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;lambda_function.py:&lt;/strong&gt; This is the main entry point of the backend service. All the request data from the Alexa intent is received here and is supposed to be returned from this file only.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;requirements.txt:&lt;/strong&gt; This file contains the list of Python packages that are being used in this project. This is especially useful if you&amp;rsquo;re choosing to set up your own backend service instead of using what&amp;rsquo;s provided by Amazon.  To learn more about requirements files, check out &lt;a href=&quot;https://realpython.com/what-is-pip/#using-requirement-files&quot;&gt;Using Requirements Files&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;utils.py:&lt;/strong&gt; This file contains some utility functions required for the lambda function to interact with the &lt;a href=&quot;https://realpython.com/courses/python-boto3-aws-s3/&quot;&gt;Amazon S3&lt;/a&gt; service. It contains some sample code on how to fetch data from an Amazon S3 bucket, which you might find useful later on. Right now, this file is not being used in &lt;code&gt;lambda_function.py&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For now, you&amp;rsquo;ll only be making changes in &lt;code&gt;lambda_function.py&lt;/code&gt;, so let&amp;rsquo;s take a closer look at the structure of the file:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;logging&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ask_sdk_core.utils&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ask_utils&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ask_sdk_core.skill_builder&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SkillBuilder&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ask_sdk_core.dispatch_components&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AbstractRequestHandler&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ask_sdk_core.dispatch_components&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AbstractExceptionHandler&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ask_sdk_core.handler_input&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HandlerInput&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ask_sdk_model&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Response&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setLevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INFO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LaunchRequestHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AbstractRequestHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22 &lt;/span&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Handler for Skill Launch.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;23 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;can_handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;24 &lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# type: (HandlerInput) -&amp;gt; bool&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;25 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;26 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ask_utils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_request_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;LaunchRequest&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;27 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;28 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;29 &lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# type: (HandlerInput) -&amp;gt; Response&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;30 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Welcome, you can say Hello or Help. &amp;quot;&lt;/span&gt; \
&lt;span class=&quot;lineno&quot;&gt;31 &lt;/span&gt;                       &lt;span class=&quot;s2&quot;&gt;&amp;quot;Which would you like to try?&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;32 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;33 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;34 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response_builder&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;35 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;36 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;37 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;38 &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;39 &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;First, you import the necessary utilities that were provided in the &lt;code&gt;ask_sdk_core&lt;/code&gt; Alexa Python package. Then, there are three main tasks you need to perform in &lt;code&gt;lambda_function.py&lt;/code&gt; to handle a request from an intent received from the front-end of the Alexa skill:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create an intent handler class,&lt;/strong&gt; which inherits from the &lt;code&gt;AbstractRequestHandler&lt;/code&gt; class, with functions &lt;code&gt;can_handle()&lt;/code&gt; and &lt;code&gt;handle()&lt;/code&gt;. There are already a couple of handler classes defined in &lt;code&gt;lambda_function.py&lt;/code&gt;, such as &lt;code&gt;LaunchRequestHandler&lt;/code&gt;, &lt;code&gt;HelpIntentHandler&lt;/code&gt;, and so on. These handle the fundamental intents of an Alexa skill. An important point to note here is that you need to create a new intent handler class for each of the intents you define.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create a &lt;code&gt;SkillBuilder&lt;/code&gt; object,&lt;/strong&gt; which acts as the entry point for your Alexa Python skill. This routes all the incoming request and response payloads to the intent handlers that you define.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pass the intent handler class&lt;/strong&gt; as an argument to &lt;code&gt;.add_request_handler()&lt;/code&gt; so that they&amp;rsquo;re called in order whenever a new request is received. The &lt;code&gt;SkillBuilder&lt;/code&gt; is a &lt;a href=&quot;https://www.tutorialspoint.com/python_design_patterns/python_design_patterns_singleton.htm&quot;&gt;singleton&lt;/a&gt;, so only one instance of it is needed to handle the routing of all incoming requests.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is a good time for you to go through &lt;code&gt;lambda_function.py&lt;/code&gt;. You&amp;rsquo;ll notice that the same pattern is followed over and over again to handle different intents that can be triggered by your Alexa Python skill.&lt;/p&gt;
&lt;p&gt;Now that you have a broad overview of all the different things you need to do to handle an intent in your backend, it&amp;rsquo;s time to write the code that will handle the &lt;em&gt;JokeIntent&lt;/em&gt; that you built in the previous section.&lt;/p&gt;
&lt;h2 id=&quot;creating-the-jokeintent-handler&quot;&gt;Creating the JokeIntent Handler&lt;/h2&gt;
&lt;p&gt;Since the important utilities from the &lt;code&gt;ask_sdk_core&lt;/code&gt; Alexa Python package have already been imported, you don&amp;rsquo;t need to import them again. If you want to learn more about these in-depth, then you can check out the &lt;a href=&quot;https://alexa-skills-kit-python-sdk.readthedocs.io/en/latest/api/core.html&quot;&gt;official documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, you&amp;rsquo;ll create a new &lt;strong&gt;intent handler&lt;/strong&gt; that will handle the request received from the &lt;em&gt;JokeIntent&lt;/em&gt;. In the code snippet below, the intent handler will simply return with a sample phrase. This indicates that the response to the &lt;em&gt;JokeIntent&lt;/em&gt; was received from the backend. Add the following code to &lt;code&gt;lambda_function.py&lt;/code&gt; above the class definition of &lt;code&gt;LaunchRequestHandler()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JokeIntentHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AbstractRequestHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;can_handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ask_utils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_intent_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;JokeIntent&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;23 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;24 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;25 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Here&amp;#39;s a sample joke for you.&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;26 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;27 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;28 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response_builder&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;29 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;30 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;31 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;32 &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let&amp;rsquo;s take a look at what each section does. In &lt;strong&gt;line 20&lt;/strong&gt; you create a new intent handler class for the &lt;em&gt;JokeIntent&lt;/em&gt;, which is a child class of the &lt;code&gt;AbstractRequestHandler&lt;/code&gt; class. When you create an intent in the frontend, you need to create an intent handler class in the backend that can handle requests from Alexa. The code you write for this needs to do two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;JokeIntentHandler.can_handle()&lt;/code&gt;&lt;/strong&gt; recognizes each incoming request that Alexa sends.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;JokeIntentHandler.handle()&lt;/code&gt;&lt;/strong&gt; returns an appropriate response.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In &lt;strong&gt;line 21&lt;/strong&gt; you define &lt;strong&gt;&lt;code&gt;.can_handle()&lt;/code&gt;&lt;/strong&gt;. It takes in &lt;code&gt;handler_input&lt;/code&gt; as a parameter, which is an object of type &lt;code&gt;dict()&lt;/code&gt; that contains all the input request information. Then, it uses &lt;code&gt;ask_utils.is_intent_name()&lt;/code&gt; or &lt;code&gt;ask_utils.is_request_type()&lt;/code&gt; to check whether the JSON input it received can be handled by this intent handler function or not.&lt;/p&gt;
&lt;p&gt;You use &lt;code&gt;.is_intent_name()&lt;/code&gt; and pass in the name of the intent. This returns a &lt;strong&gt;predicate&lt;/strong&gt;, which is a function object that returns &lt;code&gt;True&lt;/code&gt; if the given &lt;code&gt;handler_input&lt;/code&gt; originates from the indicated intent. If this is true, then the &lt;code&gt;SkillBuilder&lt;/code&gt; object will call &lt;code&gt;JokeIntentHandler.handle()&lt;/code&gt;. &lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If the &lt;em&gt;JokeIntent&lt;/em&gt; is triggered from the Alexa skill frontend, then it will send a JSON object containing a key &lt;code&gt;type&lt;/code&gt; in the body of &lt;code&gt;request&lt;/code&gt; that indicates that the intent named &lt;code&gt;JokeIntent&lt;/code&gt; was received as input.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This statement subsequently calls &lt;strong&gt;&lt;code&gt;.handle()&lt;/code&gt;&lt;/strong&gt;, which you define in &lt;strong&gt;line 24&lt;/strong&gt;. This method receives the input request along with any other important information that might be needed. It contains the business logic that&amp;rsquo;s required to successfully handle a particular intent. In the case of the &lt;em&gt;JokeIntent&lt;/em&gt;, this method is required to send a response containing a joke back to the Alexa frontend.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;speak_ouput&lt;/code&gt; variable contains the sentence which will be spoken back to the user by the Alexa skill frontend. &lt;code&gt;speak(speak_output)&lt;/code&gt; indicates what the Alexa frontend will play to the user as speech. &lt;code&gt;ask(&quot;Question to ask...&quot;)&lt;/code&gt; can be used to ask a follow-up question. In this method, an object of class &lt;code&gt;response_builder&lt;/code&gt; returns the response back to the Alexa skill.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A default response message (&lt;code&gt;Sorry, I had trouble doing what you asked. Please try again.&lt;/code&gt;) will be sent back if &lt;code&gt;.handle()&lt;/code&gt; does not exist.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Notice that the value of &lt;code&gt;speak_output&lt;/code&gt; is set to a fixed response right now. You&amp;rsquo;ll change this later on to return a random joke from a list of jokes.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what your code looks like in an editor:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screen_Shot_2020-01-23_at_7.15.37_PM.3245e6a68894.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screen_Shot_2020-01-23_at_7.15.37_PM.3245e6a68894.png&quot; width=&quot;1030&quot; height=&quot;432&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screen_Shot_2020-01-23_at_7.15.37_PM.3245e6a68894.png&amp;amp;w=257&amp;amp;sig=6946a3da6828564a2a932336fd90d1d4eba2aa4d 257w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screen_Shot_2020-01-23_at_7.15.37_PM.3245e6a68894.png&amp;amp;w=515&amp;amp;sig=f040a2c69cef229ff0bc496e4ededc9c0c1abeb4 515w, https://files.realpython.com/media/Screen_Shot_2020-01-23_at_7.15.37_PM.3245e6a68894.png 1030w&quot; sizes=&quot;75vw&quot; alt=&quot;Creating new Intent Handler&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;ve created an intent handler class, you need to pass it as an argument to &lt;code&gt;SkillBuilder.add_request_handler&lt;/code&gt;. Scroll to the bottom of &lt;code&gt;lambda_function.py&lt;/code&gt; and add the following line:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_request_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JokeIntentHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;An important thing to note here is that the placement of this line is important, as the code is processed from top to bottom. So, make sure that the call for your custom intent handler is above the call for the &lt;code&gt;InstantReflectHandler()&lt;/code&gt; class. This is how it should look:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt;171 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SkillBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;172 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;173 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_request_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LaunchRequestHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;174 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;n&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_request_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JokeIntentHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;175 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_request_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HelloWorldIntentHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;176 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_request_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HelpIntentHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;177 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_request_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CancelOrStopIntentHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;178 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_request_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SessionEndedRequestHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;179 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;180 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Make sure IntentReflectorHandler is last so it&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;181 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Doesn&amp;#39;t override your custom intent handlers&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;182 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_request_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IntentReflectorHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;183 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;184 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_exception_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CatchAllExceptionHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;185 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;186 &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Alright, it&amp;rsquo;s time to test your code! Click the &lt;em&gt;Deploy&lt;/em&gt; button to save the changes and deploy the backend service. You&amp;rsquo;ll be checking whether it&amp;rsquo;s going to work as expected from the Alexa skill frontend.&lt;/p&gt;
&lt;p&gt;Once the Deploy process is successful, head back to the &lt;em&gt;Test&lt;/em&gt; section of the developer console and invoke the &lt;em&gt;JokeIntent&lt;/em&gt;. Remember, enter the utterance phrase to invoke your Alexa Python skill, then input a phrase to execute an intent:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/test3.10a420d82586.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-33&quot; src=&quot;https://files.realpython.com/media/test3.10a420d82586.png&quot; width=&quot;967&quot; height=&quot;1168&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/test3.10a420d82586.png&amp;amp;w=241&amp;amp;sig=4598e66225ed0f6757f177526ae5c05752bd85b5 241w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/test3.10a420d82586.png&amp;amp;w=483&amp;amp;sig=c781017f8f96da1ab9ea5ed6285ebbf084428c7a 483w, https://files.realpython.com/media/test3.10a420d82586.png 967w&quot; sizes=&quot;75vw&quot; alt=&quot;Testing the Joke Intent&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you get a response similar to the one in the image above, then it means you&amp;rsquo;ve successfully created an intent handler for the &lt;em&gt;JokeIntent&lt;/em&gt; in your skill&amp;rsquo;s backend service. Congratulations! Now, all that&amp;rsquo;s left to do is to return a random joke from a list back to the skill frontend.&lt;/p&gt;
&lt;h2 id=&quot;adding-jokes&quot;&gt;Adding Jokes&lt;/h2&gt;
&lt;p&gt;Open the &lt;em&gt;Code&lt;/em&gt; section of the developer console. Then, add the &lt;code&gt;jokes&lt;/code&gt; variable in &lt;code&gt;lambda_function.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ask_sdk_model&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Response&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setLevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INFO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;n&quot;&gt;jokes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;21 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;Did you hear about the semi-colon that broke the law? He was given two consecutive sentences.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;22 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;I ate a clock yesterday, it was very time-consuming.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;23 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;I&amp;#39;ve just written a song about tortillas; actually, it&amp;#39;s more of a rap.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;24 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;I woke up this morning and forgot which side the sun rises from, then it dawned on me.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;25 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;I recently decided to sell my vacuum cleaner as all it was doing was gathering dust.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;26 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;If you shouldn&amp;#39;t eat at night, why do they put a light in the fridge?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;27 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;28 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;29 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JokeIntentHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AbstractRequestHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;30 &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, &lt;code&gt;jokes&lt;/code&gt; is a variable of type &lt;code&gt;list&lt;/code&gt; containing some one-liner jokes. Make sure to add this outside of a function or class definition so that it has &lt;strong&gt;global scope&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Since this list will only be referenced by the &lt;code&gt;JokeIntentHandler()&lt;/code&gt; class, it doesn&amp;rsquo;t really matter if you declare this in the body of a function or not. However, doing it this way does help the function body to be free of clutter.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Next, you&amp;rsquo;ll add the functionality that &lt;code&gt;.handle()&lt;/code&gt; needs to randomly pick one joke from the list of jokes and return it to the user. Modify the body of &lt;code&gt;JokeIntentHandler.handle()&lt;/code&gt; with the following code:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt;29 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JokeIntentHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AbstractRequestHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;30 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;can_handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;31 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ask_utils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_intent_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;JokeIntent&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;32 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;33 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;34 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;jokes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;35 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;36 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;37 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response_builder&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;38 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;39 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;40 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;41 &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the body of &lt;code&gt;.handle()&lt;/code&gt;, you select a random joke from the list &lt;code&gt;jokes&lt;/code&gt; using &lt;code&gt;random.choice()&lt;/code&gt; and return it back as a response to the Alexa skill frontend.&lt;/p&gt;
&lt;p&gt;Finally, import the &lt;code&gt;random&lt;/code&gt; package by adding an import statement to the top of &lt;code&gt;lambda_function.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ask_sdk_model&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Response&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setLevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INFO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22 &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is how the editor should look at this point:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screen_Shot_2020-01-23_at_7.26.33_PM.fcd241e73deb.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screen_Shot_2020-01-23_at_7.26.33_PM.fcd241e73deb.png&quot; width=&quot;1300&quot; height=&quot;638&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screen_Shot_2020-01-23_at_7.26.33_PM.fcd241e73deb.png&amp;amp;w=325&amp;amp;sig=4396d3bc9594ea3d35ea9b876f6ee6bf0c698af5 325w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screen_Shot_2020-01-23_at_7.26.33_PM.fcd241e73deb.png&amp;amp;w=650&amp;amp;sig=a6527c598c3f05df49a701775f302ca8c1238fbc 650w, https://files.realpython.com/media/Screen_Shot_2020-01-23_at_7.26.33_PM.fcd241e73deb.png 1300w&quot; sizes=&quot;75vw&quot; alt=&quot;Updating the Joke Intent Handler&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s one final change to make before testing. You need to allow Alexa to give an &lt;strong&gt;acknowledgment&lt;/strong&gt; that the skill has been triggered. To do this, look inside &lt;code&gt;LaunchRequestHandler.handle()&lt;/code&gt; for the &lt;code&gt;speak_output&lt;/code&gt; variable and set its value to the text in the highlighted line below:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt;45 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LaunchRequestHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AbstractRequestHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;46 &lt;/span&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Handler for Skill Launch.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;47 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;can_handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;48 &lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# type: (HandlerInput) -&amp;gt; bool&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;49 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;50 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ask_utils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_request_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;LaunchRequest&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;51 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;52 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;53 &lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# type: (HandlerInput) -&amp;gt; Response&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;54 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Hey there! I am a Joke Bot. You can ask me to tell you a random Joke that might just make your day better!&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;55 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;56 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;57 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;handler_input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response_builder&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;58 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;59 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speak_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;60 &lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;61 &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;62 &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Your Joke Bot is ready for final testing! Click the &lt;em&gt;Deploy&lt;/em&gt; button to save the changes and head back to the &lt;em&gt;Test&lt;/em&gt; section of the developer console. This time, you should see a new greeting message when your skill is first invoked. Then, when you ask the bot to tell you a joke, it should give you a different joke every time:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/code5.0160230a975a.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-33&quot; src=&quot;https://files.realpython.com/media/code5.0160230a975a.png&quot; width=&quot;969&quot; height=&quot;1577&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/code5.0160230a975a.png&amp;amp;w=242&amp;amp;sig=22f07130d456c11d19fb2190d482950a94c7adaa 242w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/code5.0160230a975a.png&amp;amp;w=484&amp;amp;sig=ee78718e64219a1241cfcae0a540343e5300d041 484w, https://files.realpython.com/media/code5.0160230a975a.png 969w&quot; sizes=&quot;75vw&quot; alt=&quot;Final Testing of Python Alexa Skill&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s it! You&amp;rsquo;ve successfully created your first skill as an Alexa Python developer!&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Congratulations on taking your first steps into Alexa Python development! You&amp;rsquo;ve now successfully built your very own Alexa Python skill. You now know how to create a new skill, create intents, write Python code to handle those intents, and return valuable information back to the user.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Level-up your skills by trying some of the following:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Increase&lt;/strong&gt; the list of jokes in the backend.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create&lt;/strong&gt; a new Intent named &lt;em&gt;Trivia&lt;/em&gt; which will respond with a fun trivia fact.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Publish&lt;/strong&gt; your skill to the Amazon Marketplace.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The possibilities are endless, so go ahead and dive right in! To learn more about Alexa Python development, check out the &lt;a href=&quot;https://alexa-skills-kit-python-sdk.readthedocs.io/en/latest/api/core.html&quot;&gt;official docs&lt;/a&gt;. You can also check out &lt;a href=&quot;https://realpython.com/twitter-bot-python-tweepy/&quot;&gt;How to Make a Twitter Bot in Python With Tweepy&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/how-to-make-a-discord-bot-python/&quot;&gt;How to Make a Discord Bot in Python&lt;/a&gt; to learn more about how you can make bots for different platforms using Python.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>How to Implement a Python Stack</title>
      <id>https://realpython.com/courses/python-stack/</id>
      <link href="https://realpython.com/courses/python-stack/"/>
      <updated>2020-03-03T14:00:00+00:00</updated>
      <summary>In this course, you&#39;ll learn how to implement a Python stack. You&#39;ll see how to recognize when a stack is a good choice for data structures, how to decide which implementation is best for a program, and what extra considerations to make about stacks in a threading or multiprocessing environment.</summary>
      <content type="html">
        &lt;p&gt;Have you heard of &lt;strong&gt;stacks&lt;/strong&gt; and wondered what they are? Do you have a general idea but are wondering how to implement a Python stack? You&amp;rsquo;ve come to the right place!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this course, you&amp;rsquo;ll learn:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to recognize when a stack is a good choice for a &lt;strong&gt;data structure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;How to decide which &lt;strong&gt;implementation&lt;/strong&gt; is best for your program&lt;/li&gt;
&lt;li&gt;What extra considerations to make about stacks in a &lt;strong&gt;threading or multiprocessing&lt;/strong&gt; environment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This course is for Pythonistas who are comfortable &lt;a href=&quot;https://realpython.com/quizzes/run-python-scripts/&quot;&gt;running scripts&lt;/a&gt;, know what a &lt;a href=&quot;https://realpython.com/python-lists-tuples/&quot;&gt;&lt;code&gt;list&lt;/code&gt;&lt;/a&gt; is and how to use it, and are wondering how to implement Python stacks.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python Bindings: Calling C or C++ From Python</title>
      <id>https://realpython.com/python-bindings-overview/</id>
      <link href="https://realpython.com/python-bindings-overview/"/>
      <updated>2020-03-02T14:00:00+00:00</updated>
      <summary>What are Python bindings? Should you use ctypes, CFFI, or a different tool? In this step-by-step tutorial, you&#39;ll get an overview of some of the options you can use to call C or C++ code from Python.</summary>
      <content type="html">
        &lt;p&gt;Are you a Python developer with a &lt;a href=&quot;https://realpython.com/build-python-c-extension-module/&quot;&gt;C&lt;/a&gt; or C++ library you&amp;rsquo;d like to use from Python? If so, then &lt;strong&gt;Python bindings&lt;/strong&gt; allow you to call functions and pass data from Python to C or C++, letting you take advantage of the strengths of both languages. Throughout this tutorial, you&amp;rsquo;ll see an overview of some of the tools you can use to create Python bindings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this tutorial, you&amp;rsquo;ll learn about:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Why you want to &lt;strong&gt;call C or C++&lt;/strong&gt; from Python&lt;/li&gt;
&lt;li&gt;How to &lt;strong&gt;pass data&lt;/strong&gt; between C and Python&lt;/li&gt;
&lt;li&gt;What &lt;strong&gt;tools and methods&lt;/strong&gt; can help you create Python bindings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tutorial is aimed at intermediate Python developers. It assumes &lt;a href=&quot;https://realpython.com/learning-paths/python3-introduction/&quot;&gt;basic knowledge of Python&lt;/a&gt; and some understanding of functions and data types in C or C++. You can get all of the example code you&amp;rsquo;ll see in this tutorial by clicking on the link below:&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Get Sample Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-bindings-code/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-bindings-code&quot; data-focus=&quot;false&quot;&gt;Click here to get the sample code you&#39;ll use&lt;/a&gt; to learn about Python Bindings in this tutorial.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;Let&amp;rsquo;s dive into looking at Python bindings!&lt;/p&gt;
&lt;h2 id=&quot;python-bindings-overview&quot;&gt;Python Bindings Overview&lt;/h2&gt;
&lt;p&gt;Before you dive into &lt;em&gt;how&lt;/em&gt; to call C from Python, it&amp;rsquo;s good to spend some time on &lt;em&gt;why&lt;/em&gt;. There are several situations where creating Python bindings to call a C library is a great idea:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;You already have a large, tested, stable library written in C++&lt;/strong&gt; that you&amp;rsquo;d like to take advantage of in Python. This may be a communication library or a library to talk to a specific piece of hardware. What it does is unimportant.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;You want to speed up a particular section of your Python code&lt;/strong&gt; by converting a critical section to C. Not only does C have faster execution speed, but it also allows you to break free from the limitations of the &lt;a href=&quot;https://realpython.com/python-gil/&quot;&gt;GIL&lt;/a&gt;, provided you&amp;rsquo;re careful.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;You want to use Python test tools&lt;/strong&gt; to do large-scale testing of their systems.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All of the above are great reasons to learn to create Python bindings to interface with your C library.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Throughout this tutorial, you&amp;rsquo;ll be creating Python bindings to both C &lt;em&gt;and&lt;/em&gt; C++. Most of the general concepts apply to both languages, and so C will be used unless there&amp;rsquo;s a specific difference between the two languages. In general, each of the tools will support either C &lt;em&gt;or&lt;/em&gt; C++, but not both.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Let&amp;rsquo;s get started!&lt;/p&gt;
&lt;h3 id=&quot;marshalling-data-types&quot;&gt;Marshalling Data Types&lt;/h3&gt;
&lt;p&gt;Wait! Before you start writing Python bindings, take a look at how Python and C store data and what types of issues this will cause. First, let&amp;rsquo;s define &lt;strong&gt;marshalling&lt;/strong&gt;. This concept is defined by Wikipedia as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The process of transforming the memory representation of an object to a data format suitable for storage or transmission. (&lt;a href=&quot;https://en.wikipedia.org/wiki/Marshalling_(computer_science)&quot;&gt;Source&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For your purposes, marshalling is what the Python bindings are doing when they prepare data to move it from Python to C or vice versa. Python bindings need to do marshalling because Python and C store data in different ways. C stores data in the most compact form in memory possible. If you use an &lt;code&gt;uint8_t&lt;/code&gt;, then it will only use 8 bits of memory total.&lt;/p&gt;
&lt;p&gt;In Python, on the other hand, everything is an &lt;a href=&quot;https://realpython.com/python-data-types/&quot;&gt;&lt;strong&gt;object&lt;/strong&gt;&lt;/a&gt;. This means that each integer uses several bytes in memory. How many will depend on which version of Python you&amp;rsquo;re running, your operating system, and other factors. This means that your Python bindings will need to convert a &lt;strong&gt;C integer&lt;/strong&gt; to a &lt;strong&gt;Python integer&lt;/strong&gt; for each integer passed across the boundary.&lt;/p&gt;
&lt;p&gt;Other data types have similar relationships between the two languages. Let&amp;rsquo;s look at each in turn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://realpython.com/python-data-types/#integers&quot;&gt;&lt;strong&gt;Integers&lt;/strong&gt;&lt;/a&gt; store counting numbers. Python stores integers with &lt;a href=&quot;https://mortada.net/can-integer-operations-overflow-in-python.html&quot;&gt;arbitrary precision&lt;/a&gt;, meaning that you can store very, very, large numbers. C specifies the exact sizes of integers. You need to be aware of data sizes when you&amp;rsquo;re moving between languages to prevent Python integer values from overflowing C integer variables.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://realpython.com/python-data-types/#floating-point-numbers&quot;&gt;&lt;strong&gt;Floating-point numbers&lt;/strong&gt;&lt;/a&gt; are numbers with a decimal place. Python can store much larger (and much smaller) floating-point numbers than C. This means that you&amp;rsquo;ll also have to pay attention to those values to ensure they stay in range.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://realpython.com/python-data-types/#complex-numbers&quot;&gt;&lt;strong&gt;Complex numbers&lt;/strong&gt;&lt;/a&gt; are numbers with an imaginary part. While Python has built-in complex numbers, and C has complex numbers, there&amp;rsquo;s no built-in method for marshalling between them. To marshal complex numbers, you&amp;rsquo;ll need to build a &lt;code&gt;struct&lt;/code&gt; or &lt;code&gt;class&lt;/code&gt; in the C code to manage them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://realpython.com/python-data-types/#strings&quot;&gt;&lt;strong&gt;Strings&lt;/strong&gt;&lt;/a&gt; are sequences of characters. For being such a common data type, strings will prove to be rather tricky when you&amp;rsquo;re creating Python bindings. As with other data types, Python and C store strings in quite different formats. (Unlike the other data types, this is an area where C and C++ differ as well, which adds to the fun!) Each of the solutions you&amp;rsquo;ll examine have slightly different methods for dealing with strings.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://realpython.com/python-data-types/#boolean-type-boolean-context-and-truthiness&quot;&gt;&lt;strong&gt;Boolean variables&lt;/strong&gt;&lt;/a&gt; can have only two values. Since they&amp;rsquo;re supported in C, marshalling them will prove to be fairly straightforward.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Besides data type conversions, there are other issues you&amp;rsquo;ll need to think about as you build your Python bindings. Let&amp;rsquo;s keep exploring them.&lt;/p&gt;
&lt;h3 id=&quot;understanding-mutable-and-immutable-values&quot;&gt;Understanding Mutable and Immutable Values&lt;/h3&gt;
&lt;p&gt;In addition to all of these data types, you&amp;rsquo;ll also have to be aware of how Python objects can be &lt;a href=&quot;https://realpython.com/courses/immutability-python/&quot;&gt;&lt;strong&gt;mutable&lt;/strong&gt; or &lt;strong&gt;immutable&lt;/strong&gt;&lt;/a&gt;. C has a similar concept with function parameters when talking about &lt;strong&gt;pass-by-value&lt;/strong&gt; or &lt;strong&gt;pass-by-reference&lt;/strong&gt;. In C, &lt;em&gt;all&lt;/em&gt; parameters are pass-by-value. If you want to allow a function to change a variable in the caller, then you need to pass a pointer to that variable.&lt;/p&gt;
&lt;p&gt;You might be wondering if you can get around the &lt;strong&gt;immutable restriction&lt;/strong&gt; by simply passing an immutable object to C using a pointer. Unless you go to ugly and non-portable extremes, Python won&amp;rsquo;t give you a pointer to an object, so this just doesn&amp;rsquo;t work. If you want to modify a Python object in C, then you&amp;rsquo;ll need to take extra steps to achieve this. These steps will be dependent on which tools you use, as you&amp;rsquo;ll see below.&lt;/p&gt;
&lt;p&gt;So, you can add immutability to your checklist of items to consider as you create Python bindings. Your final stop on the grand tour of creating this checklist is how to handle the different ways in which Python and C deal with memory management.&lt;/p&gt;
&lt;h3 id=&quot;managing-memory&quot;&gt;Managing Memory&lt;/h3&gt;
&lt;p&gt;C and Python &lt;strong&gt;manage memory&lt;/strong&gt; differently. In C, the developer must manage all memory allocations and ensure they&amp;rsquo;re freed once and only once. Python takes care of this for you using a &lt;a href=&quot;https://realpython.com/python-memory-management/&quot;&gt;garbage collector&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While each of these approaches has its advantages, it does add an extra wrinkle into creating Python bindings. You&amp;rsquo;ll need to be aware of &lt;strong&gt;where the memory for each object was allocated&lt;/strong&gt; and ensure that it&amp;rsquo;s only freed on the same side of the language barrier.&lt;/p&gt;
&lt;p&gt;For example, a Python object is created when you set &lt;code&gt;x = 3&lt;/code&gt;. The memory for this is allocated on the Python side and needs to be garbage collected. Fortunately, with Python objects, it&amp;rsquo;s quite difficult to do anything else. Take a look at the converse in C, where you directly allocate a block of memory:&lt;/p&gt;
&lt;div class=&quot;highlight cpp&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPtr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you do this, you need to ensure that this pointer is freed in C. This may mean manually adding code to your Python bindings to do this.&lt;/p&gt;
&lt;p&gt;That rounds out your checklist of general topics. Let&amp;rsquo;s start setting up your system so you can write some code!&lt;/p&gt;
&lt;h3 id=&quot;setting-up-your-environment&quot;&gt;Setting Up Your Environment&lt;/h3&gt;
&lt;p&gt;For this tutorial, you&amp;rsquo;re going to be using &lt;a href=&quot;https://github.com/realpython/materials/tree/master/python-bindings/overview_article&quot;&gt;pre-existing C and C++ libraries&lt;/a&gt; from the Real Python GitHub repo to show a test of each tool. The intent is that you&amp;rsquo;ll be able to use these ideas for any C library. To follow along with all of the examples here, you&amp;rsquo;ll need to have the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;C++ library&lt;/strong&gt; installed and knowledge of the path for command-line invocation&lt;/li&gt;
&lt;li&gt;Python &lt;strong&gt;development tools&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;For Linux, this is the &lt;code&gt;python3-dev&lt;/code&gt; or &lt;code&gt;python3-devel&lt;/code&gt; package, depending on your distro.&lt;/li&gt;
&lt;li&gt;For Windows, there are &lt;a href=&quot;https://wiki.python.org/moin/WindowsCompilers#Microsoft_Visual_C.2B-.2B-_10.0_standalone:_Windows_SDK_7.1_.28x86.2C_x64.2C_ia64.29&quot;&gt;multiple options&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python 3.6&lt;/strong&gt; or greater&lt;/li&gt;
&lt;li&gt;A &lt;a href=&quot;https://realpython.com/courses/working-python-virtual-environments/&quot;&gt;&lt;strong&gt;virtual environment&lt;/strong&gt;&lt;/a&gt; (recommended, but not required)&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;&lt;code&gt;invoke&lt;/code&gt;&lt;/strong&gt; tool&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The last one might be new to you, so let&amp;rsquo;s take a closer look at it.&lt;/p&gt;
&lt;h3 id=&quot;using-the-invoke-tool&quot;&gt;Using the &lt;code&gt;invoke&lt;/code&gt; Tool&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://www.pyinvoke.org/&quot;&gt;&lt;code&gt;invoke&lt;/code&gt;&lt;/a&gt; is the tool you&amp;rsquo;ll be using to build and test your Python bindings in this tutorial. It has a similar purpose to &lt;code&gt;make&lt;/code&gt; but uses Python instead of Makefiles. You&amp;rsquo;ll need to install &lt;code&gt;invoke&lt;/code&gt; in your virtual environment using &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3 -m pip install invoke
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To run it, you type &lt;code&gt;invoke&lt;/code&gt; followed by the task you wish to execute:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke build-cmult
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Building C Library&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;* Complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To see which tasks are available, you use the &lt;code&gt;--list&lt;/code&gt; option:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke --list
&lt;span class=&quot;go&quot;&gt;Available tasks:&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;  all              Build and run all tests&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  build-cffi       Build the CFFI Python bindings&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  build-cmult      Build the shared library for the sample C code&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  build-cppmult    Build the shared library for the sample C++ code&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  build-cython     Build the cython extension module&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  build-pybind11   Build the pybind11 wrapper library&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  clean            Remove any built objects&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  test-cffi        Run the script to test CFFI&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  test-ctypes      Run the script to test ctypes&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  test-cython      Run the script to test Cython&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  test-pybind11    Run the script to test PyBind11&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that when you look in the &lt;code&gt;tasks.py&lt;/code&gt; file where the &lt;code&gt;invoke&lt;/code&gt; tasks are defined, you&amp;rsquo;ll see that the name of the second task listed is &lt;code&gt;build_cffi&lt;/code&gt;. However, the output from &lt;code&gt;--list&lt;/code&gt; shows it as &lt;code&gt;build-cffi&lt;/code&gt;. The minus sign (&lt;code&gt;-&lt;/code&gt;) can&amp;rsquo;t be used as part of a Python name, so the file uses an underscore (&lt;code&gt;_&lt;/code&gt;) instead.&lt;/p&gt;
&lt;p&gt;For each of the tools you&amp;rsquo;ll examine, there will be a &lt;code&gt;build-&lt;/code&gt; and a &lt;code&gt;test-&lt;/code&gt; task defined. For example, to run the code for &lt;code&gt;CFFI&lt;/code&gt;, you could type &lt;code&gt;invoke build-cffi test-cffi&lt;/code&gt;. An exception is &lt;code&gt;ctypes&lt;/code&gt;, as there&amp;rsquo;s no build phase for &lt;code&gt;ctypes&lt;/code&gt;. In addition, there are two special tasks added for convenience:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;invoke all&lt;/code&gt;&lt;/strong&gt; runs the build and test tasks for all tools.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;invoke clean&lt;/code&gt;&lt;/strong&gt; removes any generated files.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that you&amp;rsquo;ve got a feeling for how to run the code, let&amp;rsquo;s take a peek at the C code you&amp;rsquo;ll be wrapping before hitting the tools overview.&lt;/p&gt;
&lt;h3 id=&quot;c-or-c-source&quot;&gt;C or C++ Source&lt;/h3&gt;
&lt;p&gt;In each of the example sections below, you&amp;rsquo;ll be &lt;strong&gt;creating Python bindings&lt;/strong&gt; for the same function in either C or C++. These sections are intended to give you a taste of what each method looks like, rather than an in-depth tutorial on that tool, so the function you&amp;rsquo;ll wrap is small. The function you&amp;rsquo;ll create Python bindings for takes an &lt;code&gt;int&lt;/code&gt; and a &lt;code&gt;float&lt;/code&gt; as input parameters and returns a &lt;code&gt;float&lt;/code&gt; that&amp;rsquo;s the product of the two numbers:&lt;/p&gt;
&lt;div class=&quot;highlight cpp&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// cmult.c&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cmult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;float_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int_param&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;float_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;    In cmult : int: %d float %.1f returning  %.1f&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;float_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The C and C++ functions are almost identical, with minor name and &lt;a href=&quot;https://realpython.com/python-strings/&quot;&gt;string&lt;/a&gt; differences between them. You can get a copy of all of the code by clicking on the link below:&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Get Sample Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-bindings-code/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-bindings-code&quot; data-focus=&quot;false&quot;&gt;Click here to get the sample code you&#39;ll use&lt;/a&gt; to learn about Python Bindings in this tutorial.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;Now you&amp;rsquo;ve got the repo cloned and your tools installed, you can build and test the tools. So let&amp;rsquo;s dive into each section below!&lt;/p&gt;
&lt;h2 id=&quot;ctypes&quot;&gt;&lt;code&gt;ctypes&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ll start with &lt;a href=&quot;https://docs.python.org/3.8/library/ctypes.html&quot;&gt;&lt;code&gt;ctypes&lt;/code&gt;&lt;/a&gt;, which is a tool in the standard library for creating Python bindings. It provides a low-level toolset for loading shared libraries and marshalling data between Python and C.&lt;/p&gt;
&lt;h3 id=&quot;how-its-installed&quot;&gt;How It&amp;rsquo;s Installed&lt;/h3&gt;
&lt;p&gt;One of the big advantages of &lt;code&gt;ctypes&lt;/code&gt; is that it&amp;rsquo;s part of the Python standard library. It was added in Python version 2.5, so it&amp;rsquo;s quite likely you already have it. You can &lt;code&gt;import&lt;/code&gt; it just like you do with the &lt;code&gt;sys&lt;/code&gt; or &lt;a href=&quot;https://realpython.com/python-time-module/&quot;&gt;&lt;code&gt;time&lt;/code&gt;&lt;/a&gt; modules.&lt;/p&gt;
&lt;h3 id=&quot;calling-the-function&quot;&gt;Calling the Function&lt;/h3&gt;
&lt;p&gt;All of the code to load your C library and call the function will be in your Python program. This is great since there are no extra steps in your process. You just run your program, and everything is taken care of. To create your Python bindings in &lt;code&gt;ctypes&lt;/code&gt;, you need to do these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Load&lt;/strong&gt; your library.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wrap&lt;/strong&gt; some of your input parameters.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tell&lt;/strong&gt; &lt;code&gt;ctypes&lt;/code&gt; the return type of your function.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You&amp;rsquo;ll look at each of these in turn.&lt;/p&gt;
&lt;h4 id=&quot;library-loading&quot;&gt;Library Loading&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;ctypes&lt;/code&gt; provides several ways for you to &lt;a href=&quot;https://docs.python.org/3.5/library/ctypes.html#loading-shared-libraries&quot;&gt;load a shared library&lt;/a&gt;, some of which are platform-specific. For your example, you&amp;rsquo;ll create a &lt;code&gt;ctypes.CDLL&lt;/code&gt; object directly by passing in the full path to the shared library you want:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# ctypes_test.py&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ctypes&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pathlib&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Load the shared library into ctypes&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;libname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pathlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absolute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;libcmult.so&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;c_lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CDLL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;libname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will work for cases when the shared library is in the same directory as your Python script, but be careful when you attempt to load libraries that are from packages other than your Python bindings. There are many details for loading libraries and finding paths in the &lt;code&gt;ctypes&lt;/code&gt; documentation that are platform and situation-specific.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Many platform-specific issues can arise during library loading. It&amp;rsquo;s best to make incremental changes once you get an example working.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now that you have the library loaded into Python, you can try calling it!&lt;/p&gt;
&lt;h4 id=&quot;calling-your-function&quot;&gt;Calling Your Function&lt;/h4&gt;
&lt;p&gt;Remember that the function prototype for your C function is as follows:&lt;/p&gt;
&lt;div class=&quot;highlight cpp&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// cmult.h&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cmult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;float_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You need to pass in an integer and a float and can expect to get a float returned. Integers and floats have native support in both Python and in C, so you expect this case will work for reasonable values.&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;ve loaded the library into your Python bindings, the function will be an attribute of &lt;code&gt;c_lib&lt;/code&gt;, which is the &lt;code&gt;CDLL&lt;/code&gt; object you created earlier. You can try to call it just like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.3&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c_lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Oops! This doesn&amp;rsquo;t work. This line is commented out in the example repo because it fails. If you attempt to run with that call, then Python will complain with an error:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke test-ctypes
&lt;span class=&quot;go&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  File &amp;quot;ctypes_test.py&amp;quot;, line 16, in &amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    answer = c_lib.cmult(x, y)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;ctypes.ArgumentError: argument 2: &amp;lt;class &amp;#39;TypeError&amp;#39;&amp;gt;: Don&amp;#39;t know how to convert parameter 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It looks like you need to tell &lt;code&gt;ctypes&lt;/code&gt; about any parameters that aren&amp;rsquo;t integers. &lt;code&gt;ctypes&lt;/code&gt; doesn&amp;rsquo;t have any knowledge of the function unless you tell it explicitly. Any parameter that&amp;rsquo;s not marked otherwise is assumed to be an integer. &lt;code&gt;ctypes&lt;/code&gt; doesn&amp;rsquo;t know how to convert the value &lt;code&gt;2.3&lt;/code&gt; that&amp;rsquo;s stored in &lt;code&gt;y&lt;/code&gt; to an integer, so it fails.&lt;/p&gt;
&lt;p&gt;To fix this, you&amp;rsquo;ll need to create a &lt;code&gt;c_float&lt;/code&gt; from the number. You can do that in the line where you&amp;rsquo;re calling the function:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# ctypes_test.py&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c_lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c_float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;    In Python: int: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{x}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; float &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{y:.1f}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; return val &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{answer:.1f}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, when you run this code, it returns the product of the two numbers you passed in:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke test-ctypes
&lt;span class=&quot;go&quot;&gt;    In cmult : int: 6 float 2.3 returning  13.8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    In Python: int: 6 float 2.3 return val 48.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Wait a minute&amp;hellip; &lt;code&gt;6&lt;/code&gt; multiplied by &lt;code&gt;2.3&lt;/code&gt; is not &lt;code&gt;48.0&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;It turns out that, much like the input parameters, &lt;code&gt;ctypes&lt;/code&gt; &lt;strong&gt;assumes&lt;/strong&gt; your function returns an &lt;code&gt;int&lt;/code&gt;. In actuality, your function returns a &lt;code&gt;float&lt;/code&gt;, which is getting marshalled incorrectly. Just like the input parameter, you need to tell &lt;code&gt;ctypes&lt;/code&gt; to use a different type. The syntax here is slightly different:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# ctypes_test.py&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;c_lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;restype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c_float&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c_lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c_float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;    In Python: int: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{x}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; float &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{y:.1f}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; return val &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{answer:.1f}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That should do the trick. Let&amp;rsquo;s run the entire &lt;code&gt;test-ctypes&lt;/code&gt; target and see what you&amp;rsquo;ve got. Remember, the first section of output is &lt;strong&gt;before&lt;/strong&gt; you fixed the &lt;code&gt;restype&lt;/code&gt; of the function to be a float:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke test-ctypes
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Building C Library&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;* Complete&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Testing ctypes Module&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    In cmult : int: 6 float 2.3 returning  13.8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    In Python: int: 6 float 2.3 return val 48.0&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;    In cmult : int: 6 float 2.3 returning  13.8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    In Python: int: 6 float 2.3 return val 13.8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That&amp;rsquo;s better! While the first, uncorrected version is returning the wrong value, your fixed version agrees with the C function. Both C and Python get the same result! Now that it&amp;rsquo;s working, take a look at why you may or may not want to use &lt;code&gt;ctypes&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;strengths-and-weaknesses&quot;&gt;Strengths and Weaknesses&lt;/h3&gt;
&lt;p&gt;The biggest advantage &lt;code&gt;ctypes&lt;/code&gt; has over the other tools you&amp;rsquo;ll examine here is that it&amp;rsquo;s &lt;strong&gt;built into the standard library&lt;/strong&gt;. It also requires no extra steps, as all of the work is done as part of your Python program.&lt;/p&gt;
&lt;p&gt;In addition, the concepts used are low-level, which makes exercises like the one you just did manageable. However, more complex tasks grow cumbersome with the lack of automation. In the next section, you&amp;rsquo;ll see a tool that adds some automation to the process.&lt;/p&gt;
&lt;h2 id=&quot;cffi&quot;&gt;&lt;code&gt;CFFI&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cffi.readthedocs.io/en/latest/&quot;&gt;&lt;code&gt;CFFI&lt;/code&gt;&lt;/a&gt; is the &lt;strong&gt;C Foreign Function Interface&lt;/strong&gt; for Python. It takes a more automated approach to generate Python bindings. &lt;code&gt;CFFI&lt;/code&gt; has multiple ways in which you can build and use your Python bindings. There are two different options to select from, which gives you four possible modes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ABI vs API:&lt;/strong&gt; API mode uses a C compiler to generate a full Python module, whereas ABI mode loads the shared library and interacts with it directly. Without running the compiler, getting the structures and parameters correct is error-prone. The documentation heavily recommends using the API mode.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;in-line vs out-of-line:&lt;/strong&gt; The difference between these two modes is a trade-off between speed and convenience:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;In-line mode&lt;/strong&gt; compiles the Python bindings every time your script runs. This is convenient, as you don&amp;rsquo;t need an extra build step. It does, however, slow down your program.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Out-of-line mode&lt;/strong&gt; requires an extra step to generate the Python bindings a single time and then uses them each time the program is run. This is much faster, but that may not matter for your application.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For this example, you&amp;rsquo;ll use the API out-of-line mode, which produces the fastest code and, in general, looks similar to other Python bindings you&amp;rsquo;ll create later in this tutorial.&lt;/p&gt;
&lt;h3 id=&quot;how-its-installed_1&quot;&gt;How It&amp;rsquo;s Installed&lt;/h3&gt;
&lt;p&gt;Since &lt;code&gt;CFFI&lt;/code&gt; is not a part of the standard library, you&amp;rsquo;ll need to install it on your machine. It&amp;rsquo;s recommended that you create a virtual environment for this. Fortunately, &lt;code&gt;CFFI&lt;/code&gt; installs with &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3 -m pip install cffi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will install the package into your virtual environment. If you&amp;rsquo;ve already installed from the &lt;code&gt;requirements.txt&lt;/code&gt;, then this should be taken care of. You can take a look at &lt;code&gt;requirements.txt&lt;/code&gt; by accessing the repo at the link below:&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Get Sample Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-bindings-code/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-bindings-code&quot; data-focus=&quot;false&quot;&gt;Click here to get the sample code you&#39;ll use&lt;/a&gt; to learn about Python Bindings in this tutorial.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;Now that you have &lt;code&gt;CFFI&lt;/code&gt; installed, it&amp;rsquo;s time to take it for a spin!&lt;/p&gt;
&lt;h3 id=&quot;calling-the-function_1&quot;&gt;Calling the Function&lt;/h3&gt;
&lt;p&gt;Unlike &lt;code&gt;ctypes&lt;/code&gt;, with &lt;code&gt;CFFI&lt;/code&gt; you&amp;rsquo;re creating a full Python module. You&amp;rsquo;ll be able to &lt;code&gt;import&lt;/code&gt; the module like any other module in the standard library. There is some extra work you&amp;rsquo;ll have to do to build your Python module. To use your &lt;code&gt;CFFI&lt;/code&gt; Python bindings, you&amp;rsquo;ll need to take the following steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Write&lt;/strong&gt; some Python code describing the bindings.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Run&lt;/strong&gt; that code to generate a loadable module.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Modify&lt;/strong&gt; the calling code to import and use your newly created module.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That might seem like a lot of work, but you&amp;rsquo;ll walk through each of these steps and see how it works.&lt;/p&gt;
&lt;h4 id=&quot;write-the-bindings&quot;&gt;Write the Bindings&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;CFFI&lt;/code&gt; provides methods to read a &lt;strong&gt;C header file&lt;/strong&gt; to do most of the work when generating Python bindings. In the documentation for &lt;code&gt;CFFI&lt;/code&gt;, the code to do this is placed in a separate Python file. For this example, you&amp;rsquo;ll place that code directly into the build tool &lt;code&gt;invoke&lt;/code&gt;, which uses Python files as input. To use &lt;code&gt;CFFI&lt;/code&gt;, you start by creating a &lt;code&gt;cffi.FFI&lt;/code&gt; object, which provides the three methods you need:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# tasks.py&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;cffi&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot; Build the CFFI Python bindings &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;print_banner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Building CFFI Module&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ffi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cffi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FFI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once you have the FFI, you&amp;rsquo;ll use &lt;code&gt;.cdef()&lt;/code&gt; to process the contents of the header file automatically. This creates wrapper functions for you to marshal data from Python:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# tasks.py&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;this_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pathlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absolute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;h_file_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;this_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cmult.h&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h_file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ffi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cdef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h_file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Reading and processing the header file is the first step. After that, you need to use &lt;code&gt;.set_source()&lt;/code&gt; to describe the source file that &lt;code&gt;CFFI&lt;/code&gt; will generate:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# tasks.py&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ffi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;cffi_example&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Since you&amp;#39;re calling a fully-built library directly, no custom source&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# is necessary. You need to include the .h files, though, because behind&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# the scenes cffi generates a .c file that contains a Python-friendly&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# wrapper around each of the functions.&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&amp;#39;#include &amp;quot;cmult.h&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# The important thing is to include the pre-built lib in the list of&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# libraries you&amp;#39;re linking against:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;libraries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;cmult&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;library_dirs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this_dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_posix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()],&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;extra_link_args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-Wl,-rpath,.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here&amp;rsquo;s a breakdown of the parameters you&amp;rsquo;re passing in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;&quot;cffi_example&quot;&lt;/code&gt;&lt;/strong&gt; is the base name for the source file that will be created on your file system. &lt;code&gt;CFFI&lt;/code&gt; will generate a &lt;code&gt;.c&lt;/code&gt; file, compile it to a &lt;code&gt;.o&lt;/code&gt; file, and link it to a &lt;code&gt;.&amp;lt;system-description&amp;gt;.so&lt;/code&gt; or &lt;code&gt;.&amp;lt;system-description&amp;gt;.dll&lt;/code&gt; file.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;&#39;#include &quot;cmult.h&quot;&#39;&lt;/code&gt;&lt;/strong&gt; is the custom C source code that will be included in the generated source before it&amp;rsquo;s compiled. Here, you just include the &lt;code&gt;.h&lt;/code&gt; file for which you&amp;rsquo;re generating bindings, but this can be used for some interesting customizations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;libraries=[&quot;cmult&quot;]&lt;/code&gt;&lt;/strong&gt; tells the linker the name of your pre-existing C library. This is a &lt;a href=&quot;https://realpython.com/courses/using-list-comprehensions-effectively/&quot;&gt;list&lt;/a&gt;, so you can specify several libraries if required.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;library_dirs=[this_dir.as_posix(),]&lt;/code&gt;&lt;/strong&gt; is a list of directories that tells the linker where to look for the above list of libraries.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;extra_link_args=[&#39;-Wl,-rpath,.&#39;]&lt;/code&gt;&lt;/strong&gt; is a set of options that generate a shared object, which will look in the current path (&lt;code&gt;.&lt;/code&gt;) for other libraries it needs to load.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;build-the-python-bindings&quot;&gt;Build the Python Bindings&lt;/h4&gt;
&lt;p&gt;Calling &lt;code&gt;.set_source()&lt;/code&gt; doesn&amp;rsquo;t build the Python bindings. It only sets up the metadata to describe what will be generated. To build the Python bindings, you need to call &lt;code&gt;.compile()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# tasks.py&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ffi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This wraps things up by generating the &lt;code&gt;.c&lt;/code&gt; file, &lt;code&gt;.o&lt;/code&gt; file, and the shared library. The &lt;code&gt;invoke&lt;/code&gt; task you just walked through can be run on the command line to build the Python bindings:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke build-cffi
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Building C Library&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;* Complete&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Building CFFI Module&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;* Complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You have your &lt;code&gt;CFFI&lt;/code&gt; Python bindings, so it&amp;rsquo;s time to run this code!&lt;/p&gt;
&lt;h4 id=&quot;calling-your-function_1&quot;&gt;Calling Your Function&lt;/h4&gt;
&lt;p&gt;After all of the work you did to configure and run the &lt;code&gt;CFFI&lt;/code&gt; compiler, using the generated Python bindings looks just like using any other Python module:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# cffi_test.py&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;cffi_example&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Sample data for your call&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.3&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cffi_example&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;    In Python: int: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{x}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; float &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{y:.1f}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; return val &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{answer:.1f}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You import the new module, and then you can call &lt;code&gt;cmult()&lt;/code&gt; directly. To test it out, use the &lt;code&gt;test-cffi&lt;/code&gt; task:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke test-cffi
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Testing CFFI Module&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    In cmult : int: 6 float 2.3 returning  13.8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    In Python: int: 6 float 2.3 return val 13.8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This runs your &lt;code&gt;cffi_test.py&lt;/code&gt; program, which tests out the new Python bindings you&amp;rsquo;ve created with &lt;code&gt;CFFI&lt;/code&gt;. That completes the section on writing and using your &lt;code&gt;CFFI&lt;/code&gt; Python bindings.&lt;/p&gt;
&lt;h3 id=&quot;strengths-and-weaknesses_1&quot;&gt;Strengths and Weaknesses&lt;/h3&gt;
&lt;p&gt;It might seem that &lt;code&gt;ctypes&lt;/code&gt; requires less work than the &lt;code&gt;CFFI&lt;/code&gt; example you just saw. While this is true for this use case, &lt;code&gt;CFFI&lt;/code&gt; scales to larger projects much better than &lt;code&gt;ctypes&lt;/code&gt; due to &lt;strong&gt;automation&lt;/strong&gt; of much of the function wrapping.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CFFI&lt;/code&gt; also produces quite a different user experience. &lt;code&gt;ctypes&lt;/code&gt; allows you to load a pre-existing C library directly into your Python program. &lt;code&gt;CFFI&lt;/code&gt;, on the other hand, creates a new Python module that can be loaded like other Python modules.&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s more, with the &lt;strong&gt;out-of-line-API&lt;/strong&gt; method you used above, the time penalty for creating the Python bindings is done once when you build it and doesn&amp;rsquo;t happen each time you run your code. For small programs, this might not be a big deal, but &lt;code&gt;CFFI&lt;/code&gt; scales better to larger projects in this way, as well.&lt;/p&gt;
&lt;p&gt;Like &lt;code&gt;ctypes&lt;/code&gt;, using &lt;code&gt;CFFI&lt;/code&gt; only allows you to interface with C libraries directly. C++ libraries require a good deal of work to use. In the next section, you&amp;rsquo;ll see a Python bindings tool that focuses on C++.&lt;/p&gt;
&lt;h2 id=&quot;pybind11&quot;&gt;&lt;code&gt;PyBind11&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pybind11.readthedocs.io/en/master/&quot;&gt;&lt;code&gt;PyBind11&lt;/code&gt;&lt;/a&gt; takes a quite different approach to create Python bindings. In addition to shifting the focus from C to C++, it also &lt;strong&gt;uses C++ to specify and build the module&lt;/strong&gt;, allowing it to take advantage of the metaprogramming tools in C++. Like &lt;code&gt;CFFI&lt;/code&gt;, the Python bindings generated from &lt;code&gt;PyBind11&lt;/code&gt; are a full Python module that can be imported and used directly.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PyBind11&lt;/code&gt; is modeled after the &lt;code&gt;Boost::Python&lt;/code&gt; library and has a similar interface. It restricts its use to C++11 and newer, however, which allows it to simplify and speed things up compared to Boost, which supports everything.&lt;/p&gt;
&lt;h3 id=&quot;how-its-installed_2&quot;&gt;How It&amp;rsquo;s Installed&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://pybind11.readthedocs.io/en/latest/basics.html&quot;&gt;First Steps&lt;/a&gt; section of the &lt;code&gt;PyBind11&lt;/code&gt; documentation walks you through how to download and build the test cases for &lt;code&gt;PyBind11&lt;/code&gt;. While this doesn&amp;rsquo;t appear to be strictly required, working through these steps will ensure you&amp;rsquo;ve got the proper C++ and Python tools set up.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Most of the examples for &lt;code&gt;PyBind11&lt;/code&gt; use &lt;a href=&quot;https://cmake.org/&quot;&gt;&lt;code&gt;cmake&lt;/code&gt;&lt;/a&gt;, which is a fine tool for building C and C++ projects. For this demo, however, you&amp;rsquo;ll continue to use the &lt;code&gt;invoke&lt;/code&gt; tool, which follows the instructions in the &lt;a href=&quot;https://pybind11.readthedocs.io/en/latest/compiling.html#building-manually&quot;&gt;Building Manually&lt;/a&gt; section of the docs.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;You&amp;rsquo;ll want to install this tool into your &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;virtual environment&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3 -m pip install pybind11
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;PyBind11&lt;/code&gt; is an all-header library, similar to much of Boost. This allows &lt;code&gt;pip&lt;/code&gt; to install the actual C++ source for the library directly into your virtual environment.&lt;/p&gt;
&lt;h3 id=&quot;calling-the-function_2&quot;&gt;Calling the Function&lt;/h3&gt;
&lt;p&gt;Before you dive in, please note that &lt;strong&gt;you&amp;rsquo;re using a different C++ source file&lt;/strong&gt;, &lt;code&gt;cppmult.cpp&lt;/code&gt;, instead of the C file you used for the previous examples. The function is essentially the same in both languages.&lt;/p&gt;
&lt;h4 id=&quot;writing-the-bindings&quot;&gt;Writing the Bindings&lt;/h4&gt;
&lt;p&gt;Similar to &lt;code&gt;CFFI&lt;/code&gt;, you need to create some code to tell the tool how to build your Python bindings. Unlike &lt;code&gt;CFFI&lt;/code&gt;, this code will be in C++ instead of Python. Fortunately, there&amp;rsquo;s a minimal amount of code required:&lt;/p&gt;
&lt;div class=&quot;highlight cpp&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// pybind11_wrapper.cpp&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;pybind11/pybind11.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;cppmult.hpp&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;PYBIND11_MODULE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pybind11_example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;pybind11 example plugin&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Optional module docstring&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;cpp_function&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cppmult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;A function that multiplies two numbers&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let&amp;rsquo;s look at this a piece at a time, as &lt;code&gt;PyBind11&lt;/code&gt; packs a lot of information into a few lines.&lt;/p&gt;
&lt;p&gt;The first two lines include the &lt;code&gt;pybind11.h&lt;/code&gt; file and the header file for your C++ library, &lt;code&gt;cppmult.hpp&lt;/code&gt;. After that, you have the &lt;code&gt;PYBIND11_MODULE&lt;/code&gt; macro. This expands into a block of C++ code that&amp;rsquo;s well described in the &lt;code&gt;PyBind11&lt;/code&gt; source:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This macro creates the entry point that will be invoked when the Python interpreter imports an extension module. The module name is given as the first argument and it should not be in quotes. The second macro argument defines a variable of type &lt;code&gt;py::module&lt;/code&gt; which can be used to initialize the module. (&lt;a href=&quot;https://github.com/pybind/pybind11/blob/1376eb0e518ff2b7b412c84a907dd1cd3f7f2dcd/include/pybind11/detail/common.h#L267&quot;&gt;Source&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What this means for you is that, for this example, you&amp;rsquo;re creating a module called &lt;code&gt;pybind11_example&lt;/code&gt; and that the rest of the code will use &lt;code&gt;m&lt;/code&gt; as the name of the &lt;code&gt;py::module&lt;/code&gt; object. On the next line, inside the C++ function you&amp;rsquo;re defining, you create a &lt;a href=&quot;https://realpython.com/documenting-python-code/#documenting-your-python-code-base-using-docstrings&quot;&gt;docstring&lt;/a&gt; for the module. While this is optional, it&amp;rsquo;s a nice touch to make your module more &lt;a href=&quot;https://realpython.com/learning-paths/writing-pythonic-code/&quot;&gt;Pythonic&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, you have the &lt;code&gt;m.def()&lt;/code&gt; call. This will define a function that&amp;rsquo;s exported by your new Python bindings, meaning it will be visible from Python. In this example, you&amp;rsquo;re passing three parameters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;cpp_function&lt;/code&gt;&lt;/strong&gt; is the exported name of the function that you&amp;rsquo;ll use in Python. As this example shows, it doesn&amp;rsquo;t need to match the name of the C++ function.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;&amp;amp;cppmult&lt;/code&gt;&lt;/strong&gt; takes the address of the function to be exported.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;&quot;A function...&quot;&lt;/code&gt;&lt;/strong&gt; is an optional docstring for the function.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that you have the code for the Python bindings, take a look at how you can build this into a Python module.&lt;/p&gt;
&lt;h4 id=&quot;build-the-python-bindings_1&quot;&gt;Build the Python Bindings&lt;/h4&gt;
&lt;p&gt;The tool you use to build the Python bindings in &lt;code&gt;PyBind11&lt;/code&gt; is the C++ compiler itself. You may need to modify the defaults for your compiler and operating system.&lt;/p&gt;
&lt;p&gt;To begin, you must build the C++ library for which you&amp;rsquo;re creating bindings. For an example this small, you could build the &lt;code&gt;cppmult&lt;/code&gt; library directly into the Python bindings library. However, for most real-world examples, you&amp;rsquo;ll have a pre-existing library you want to wrap, so you&amp;rsquo;ll build the &lt;code&gt;cppmult&lt;/code&gt; library separately. The build is a standard call to the compiler to build a shared library:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# tasks.py&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;g++ -O3 -Wall -Werror -shared -std=c++11 -fPIC cppmult.cpp &amp;quot;&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;-o libcppmult.so &amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Running this with &lt;code&gt;invoke build-cppmult&lt;/code&gt; produces &lt;code&gt;libcppmult.so&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke build-cppmult
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Building C++ Library&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;* Complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The build for the Python bindings, on the other hand, requires some special details:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# tasks.py&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;    &lt;span class=&quot;s2&quot;&gt;&amp;quot;g++ -O3 -Wall -Werror -shared -std=c++11 -fPIC &amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;    &lt;span class=&quot;s2&quot;&gt;&amp;quot;`python3 -m pybind11 --includes` &amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;    &lt;span class=&quot;s2&quot;&gt;&amp;quot;-I /usr/include/python3.7 -I .  &amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;    &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;    &lt;span class=&quot;s2&quot;&gt;&amp;quot;-o &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`python3.7-config --extension-suffix` &amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;    &lt;span class=&quot;s2&quot;&gt;&amp;quot;-L. -lcppmult -Wl,-rpath,.&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpp_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extension_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let&amp;rsquo;s walk through this line-by-line. &lt;strong&gt;Line 3&lt;/strong&gt; contains fairly standard C++ compiler flags that indicate several details, including that you want all warnings caught and treated as errors, that you want a shared library, and that you&amp;rsquo;re using C++11.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Line 4&lt;/strong&gt; is the first step of the magic. It calls the &lt;code&gt;pybind11&lt;/code&gt; module to have it produce the proper &lt;code&gt;include&lt;/code&gt; paths for &lt;code&gt;PyBind11&lt;/code&gt;. You can run this command directly on the console to see what it does:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3 -m pybind11 --includes
&lt;span class=&quot;go&quot;&gt;-I/home/jima/.virtualenvs/realpython/include/python3.7m&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-I/home/jima/.virtualenvs/realpython/include/site/python3.7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Your output should be similar but show different paths.&lt;/p&gt;
&lt;p&gt;In &lt;strong&gt;line 5&lt;/strong&gt; of your compilation call, you can see that you&amp;rsquo;re also adding the path to the Python dev &lt;code&gt;includes&lt;/code&gt;. While it&amp;rsquo;s recommended that you &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; link against the Python library itself, the source needs some code from &lt;code&gt;Python.h&lt;/code&gt; to work its magic. Fortunately, the code it uses is fairly stable across Python versions.&lt;/p&gt;
&lt;p&gt;Line 5 also uses &lt;code&gt;-I .&lt;/code&gt; to add the current directory to the list of &lt;code&gt;include&lt;/code&gt; paths. This allows the &lt;code&gt;#include &amp;lt;cppmult.hpp&amp;gt;&lt;/code&gt; line in your wrapper code to be resolved.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Line 6&lt;/strong&gt; specifies the name of your source file, which is &lt;code&gt;pybind11_wrapper.cpp&lt;/code&gt;. Then, on &lt;strong&gt;line 7&lt;/strong&gt; you see some more build magic happening. This line specifies the name of the output file. Python has some particular ideas on module naming, which include the Python version, the machine architecture, and other details. Python also provides a tool to help with this called &lt;code&gt;python3.7-config&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3.7-config --extension-suffix
&lt;span class=&quot;go&quot;&gt;.cpython-37m-x86_64-linux-gnu.so&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You may need to modify the command if you&amp;rsquo;re using a different version of Python. Your results will likely change if you&amp;rsquo;re using a different version of Python or are on a different operating system.&lt;/p&gt;
&lt;p&gt;The final line of your build command, &lt;strong&gt;line 8&lt;/strong&gt;, points the linker at the &lt;code&gt;libcppmult&lt;/code&gt; library you built earlier. The &lt;code&gt;rpath&lt;/code&gt; section tells the linker to add information to the shared library to help the operating system find &lt;code&gt;libcppmult&lt;/code&gt; at runtime. Finally, you&amp;rsquo;ll notice that this string is formatted with the &lt;code&gt;cpp_name&lt;/code&gt; and the &lt;code&gt;extension_name&lt;/code&gt;. You&amp;rsquo;ll be using this function again when you build your Python bindings module with &lt;code&gt;Cython&lt;/code&gt; in the next section.&lt;/p&gt;
&lt;p&gt;Run this command to build your bindings:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke build-pybind11
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Building C++ Library&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;* Complete&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Building PyBind11 Module&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;* Complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That&amp;rsquo;s it! You&amp;rsquo;ve built your Python bindings with &lt;code&gt;PyBind11&lt;/code&gt;. It&amp;rsquo;s time to test it out!&lt;/p&gt;
&lt;h4 id=&quot;calling-your-function_2&quot;&gt;Calling Your Function&lt;/h4&gt;
&lt;p&gt;Similar to the &lt;code&gt;CFFI&lt;/code&gt; example above, once you&amp;rsquo;ve done the heavy lifting of creating the Python bindings, calling your function looks like normal Python code:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# pybind11_test.py&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pybind11_example&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Sample data for your call&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.3&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pybind11_example&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpp_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;    In Python: int: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{x}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; float &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{y:.1f}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; return val &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{answer:.1f}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Since you used &lt;code&gt;pybind11_example&lt;/code&gt; as the name of your module in the &lt;code&gt;PYBIND11_MODULE&lt;/code&gt; macro, that&amp;rsquo;s the name you import. In the &lt;code&gt;m.def()&lt;/code&gt; call you told &lt;code&gt;PyBind11&lt;/code&gt; to export the &lt;code&gt;cppmult&lt;/code&gt; function as &lt;code&gt;cpp_function&lt;/code&gt;, so that&amp;rsquo;s what you use to call it from Python.&lt;/p&gt;
&lt;p&gt;You can test it with &lt;code&gt;invoke&lt;/code&gt; as well:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke test-pybind11
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Testing PyBind11 Module&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    In cppmul: int: 6 float 2.3 returning  13.8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    In Python: int: 6 float 2.3 return val 13.8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That&amp;rsquo;s what &lt;code&gt;PyBind11&lt;/code&gt; looks like. Next, you&amp;rsquo;ll see when and why &lt;code&gt;PyBind11&lt;/code&gt; is the right tool for the job.&lt;/p&gt;
&lt;h3 id=&quot;strengths-and-weaknesses_2&quot;&gt;Strengths and Weaknesses&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;PyBind11&lt;/code&gt; is focused on C++ instead of C, which makes it different from &lt;code&gt;ctypes&lt;/code&gt; and &lt;code&gt;CFFI&lt;/code&gt;. It has several features that make it quite attractive for C++ libraries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It supports &lt;strong&gt;classes&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It handles &lt;strong&gt;polymorphic subclassing&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It allows you to add &lt;strong&gt;dynamic attributes&lt;/strong&gt; to objects from Python and many other tools, which would be quite difficult to do from the C-based tools you&amp;rsquo;ve examined.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That being said, there&amp;rsquo;s a fair bit of setup and configuration you need to do to get &lt;code&gt;PyBind11&lt;/code&gt; up and running. Getting the installation and build correct can be a bit finicky, but once that&amp;rsquo;s done, it seems fairly solid. Also, &lt;code&gt;PyBind11&lt;/code&gt; requires that you use at least C++11 or newer. This is unlikely to be a big restriction for most projects, but it may be a consideration for you.&lt;/p&gt;
&lt;p&gt;Finally, the extra code you need to write to create the Python bindings is in C++ and not Python. This may or may not be an issue for you, but it &lt;em&gt;is&lt;/em&gt; different than the other tools you&amp;rsquo;ve looked at here. In the next section, you&amp;rsquo;ll move on to &lt;code&gt;Cython&lt;/code&gt;, which takes quite a different approach to this problem.&lt;/p&gt;
&lt;h2 id=&quot;cython&quot;&gt;&lt;code&gt;Cython&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The approach &lt;a href=&quot;https://cython.org/&quot;&gt;&lt;code&gt;Cython&lt;/code&gt;&lt;/a&gt; takes to creating Python bindings uses a &lt;strong&gt;Python-like language&lt;/strong&gt; to define the bindings and then generates C or C++ code that can be compiled into the module. There are several methods for building Python bindings with &lt;code&gt;Cython&lt;/code&gt;. The most common one is to use &lt;code&gt;setup&lt;/code&gt; from &lt;code&gt;distutils&lt;/code&gt;. For this example, you&amp;rsquo;ll stick with the &lt;code&gt;invoke&lt;/code&gt; tool, which will allow you to play with the exact commands that are run.&lt;/p&gt;
&lt;h3 id=&quot;how-its-installed_3&quot;&gt;How It&amp;rsquo;s Installed&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Cython&lt;/code&gt; is a Python module that can be installed into your virtual environment from &lt;a href=&quot;https://realpython.com/courses/how-to-publish-your-own-python-package-pypi/&quot;&gt;PyPI&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3 -m pip install cython
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Again, if you&amp;rsquo;ve installed the &lt;code&gt;requirements.txt&lt;/code&gt; file into your virtual environment, then this will already be there. You can grab a copy of &lt;code&gt;requirements.txt&lt;/code&gt; by clicking on the link below:&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Get Sample Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-bindings-code/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-bindings-code&quot; data-focus=&quot;false&quot;&gt;Click here to get the sample code you&#39;ll use&lt;/a&gt; to learn about Python Bindings in this tutorial.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;That should have you ready to work with &lt;code&gt;Cython&lt;/code&gt;!&lt;/p&gt;
&lt;h3 id=&quot;calling-the-function_3&quot;&gt;Calling the Function&lt;/h3&gt;
&lt;p&gt;To build your Python bindings with &lt;code&gt;Cython&lt;/code&gt;, you&amp;rsquo;ll follow similar steps to those you used for &lt;code&gt;CFFI&lt;/code&gt; and &lt;code&gt;PyBind11&lt;/code&gt;. You&amp;rsquo;ll write the bindings, build them, and then run Python code to call them. &lt;code&gt;Cython&lt;/code&gt; can support both C and C++. For this example, you&amp;rsquo;ll use the &lt;code&gt;cppmult&lt;/code&gt; library that you used for the &lt;code&gt;PyBind11&lt;/code&gt; example above.&lt;/p&gt;
&lt;h4 id=&quot;write-the-bindings_1&quot;&gt;Write the Bindings&lt;/h4&gt;
&lt;p&gt;The most common form of declaring a module in &lt;code&gt;Cython&lt;/code&gt; is to use a &lt;code&gt;.pyx&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# cython_example.pyx&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot; Example cython interface definition &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cdef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cppmult.hpp&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cppmult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;float_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pymult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;float_param&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cppmult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;float_param&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There are two sections here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Lines 3 and 4&lt;/strong&gt; tell &lt;code&gt;Cython&lt;/code&gt; that you&amp;rsquo;re using &lt;code&gt;cppmult()&lt;/code&gt; from &lt;code&gt;cppmult.hpp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lines 6 and 7&lt;/strong&gt; create a wrapper function, &lt;code&gt;pymult()&lt;/code&gt;, to call &lt;code&gt;cppmult()&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The language used here is a special mix of C, C++, and Python. It will look fairly familiar to Python developers, though, as the goal is to make the process easier.&lt;/p&gt;
&lt;p&gt;The first section with &lt;code&gt;cdef extern...&lt;/code&gt; tells &lt;code&gt;Cython&lt;/code&gt; that the function declarations below are also found in the &lt;code&gt;cppmult.hpp&lt;/code&gt; file. This is useful for ensuring that your Python bindings are built against the same declarations as your C++ code. The second section looks like a regular Python function&amp;mdash;because it is! This section creates a Python function that has access to the C++ function &lt;code&gt;cppmult&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now that you&amp;rsquo;ve got the Python bindings defined, it&amp;rsquo;s time to build them!&lt;/p&gt;
&lt;h4 id=&quot;build-the-python-bindings_2&quot;&gt;Build the Python Bindings&lt;/h4&gt;
&lt;p&gt;The build process for &lt;code&gt;Cython&lt;/code&gt; has similarities to the one you used for &lt;code&gt;PyBind11&lt;/code&gt;. You first run &lt;code&gt;Cython&lt;/code&gt; on the &lt;code&gt;.pyx&lt;/code&gt; file to generate a &lt;code&gt;.cpp&lt;/code&gt; file. Once you&amp;rsquo;ve done this, you compile it with the same function you used for &lt;code&gt;PyBind11&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# tasks.py&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;compile_python_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpp_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extension_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;g++ -O3 -Wall -Werror -shared -std=c++11 -fPIC &amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;`python3 -m pybind11 --includes` &amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;-I /usr/include/python3.7 -I .  &amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;-o &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`python3.7-config --extension-suffix` &amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;-L. -lcppmult -Wl,-rpath,.&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpp_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extension_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;build_cython&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot; Build the cython extension module &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;print_banner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Building Cython Module&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# Run cython on the pyx file to create a .cpp file&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;cython --cplus -3 cython_example.pyx -o cython_wrapper.cpp&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# Compile and link the cython wrapper library&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;compile_python_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;cython_wrapper.cpp&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cython_example&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;* Complete&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You start by running &lt;code&gt;cython&lt;/code&gt; on your &lt;code&gt;.pyx&lt;/code&gt; file. There are a few options you use on this command:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--cplus&lt;/code&gt;&lt;/strong&gt; tells the compiler to generate a C++ file instead of a C file.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;-3&lt;/code&gt;&lt;/strong&gt; switches &lt;code&gt;Cython&lt;/code&gt; to generate Python 3 syntax instead of Python 2.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;-o cython_wrapper.cpp&lt;/code&gt;&lt;/strong&gt; specifies the name of the file to generate.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once the C++ file is generated, you use the C++ compiler to generate the Python bindings, just as you did for &lt;code&gt;PyBind11&lt;/code&gt;. Note that the call to produce the extra &lt;code&gt;include&lt;/code&gt; paths using the &lt;code&gt;pybind11&lt;/code&gt; tool is still in that function. It won&amp;rsquo;t hurt anything here, as your source will not need those.&lt;/p&gt;
&lt;p&gt;Running this task in &lt;code&gt;invoke&lt;/code&gt; produces this output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke build-cython
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Building C++ Library&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;* Complete&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Building Cython Module&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;* Complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can see that it builds the &lt;code&gt;cppmult&lt;/code&gt; library and then builds the &lt;code&gt;cython&lt;/code&gt; module to wrap it. Now you have the &lt;code&gt;Cython&lt;/code&gt; Python bindings. (Try saying &lt;em&gt;that&lt;/em&gt; quickly&amp;hellip;) It&amp;rsquo;s time to test it out!&lt;/p&gt;
&lt;h4 id=&quot;calling-your-function_3&quot;&gt;Calling Your Function&lt;/h4&gt;
&lt;p&gt;The Python code to call your new Python bindings is quite similar to what you used to test the other modules:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# cython_test.py&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;cython_example&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Sample data for your call&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.3&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cython_example&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pymult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;    In Python: int: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{x}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; float &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{y:.1f}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; return val &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{answer:.1f}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Line 2 imports your new Python bindings module, and you call &lt;code&gt;pymult()&lt;/code&gt; on line 7. Remember that the &lt;code&gt;.pyx&lt;/code&gt; file provided a Python wrapper around &lt;code&gt;cppmult()&lt;/code&gt; and renamed it to &lt;code&gt;pymult&lt;/code&gt;. Using invoke to run your test produces the following:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; invoke test-cython
&lt;span class=&quot;go&quot;&gt;==================================================&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;= Testing Cython Module&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    In cppmul: int: 6 float 2.3 returning  13.8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    In Python: int: 6 float 2.3 return val 13.8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You get the same result as before!&lt;/p&gt;
&lt;h3 id=&quot;strengths-and-weaknesses_3&quot;&gt;Strengths and Weaknesses&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Cython&lt;/code&gt; is a relatively complex tool that can provide you &lt;strong&gt;a deep level of control&lt;/strong&gt; when creating Python bindings for either C or C++. Though you didn&amp;rsquo;t cover it in depth here, it provides a Python-esque method for writing code that manually controls the &lt;a href=&quot;https://realpython.com/python-gil/&quot;&gt;GIL&lt;/a&gt;, which can significantly speed up certain types of problems.&lt;/p&gt;
&lt;p&gt;That Python-esque language is not quite Python, however, so there&amp;rsquo;s a slight learning curve when you&amp;rsquo;re coming up to speed in figuring out which parts of C and Python fit where.&lt;/p&gt;
&lt;h2 id=&quot;other-solutions&quot;&gt;Other Solutions&lt;/h2&gt;
&lt;p&gt;While researching this tutorial, I came across several different tools and options for creating Python bindings. While I limited this overview to some of the more common options, there are several other tools I stumbled across. The list below is not comprehensive. It&amp;rsquo;s merely a sampling of other possibilities if one of the above tools doesn&amp;rsquo;t fit your project.&lt;/p&gt;
&lt;h3 id=&quot;pybindgen&quot;&gt;&lt;code&gt;PyBindGen&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://pybindgen.readthedocs.io/en/latest/tutorial/#supported-python-versions&quot;&gt;&lt;code&gt;PyBindGen&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; generates Python bindings for C or C++ and is written in Python. It&amp;rsquo;s targeted at producing readable C or C++ code, which should simplify debugging issues. It wasn&amp;rsquo;t clear if this has been updated recently, as the documentation lists Python 3.4 as the latest tested version. There have been yearly releases for the last several years, however.&lt;/p&gt;
&lt;h3 id=&quot;boostpython&quot;&gt;&lt;code&gt;Boost.Python&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.boost.org/doc/libs/1_66_0/libs/python/doc/html/index.html&quot;&gt;&lt;code&gt;Boost.Python&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; has an interface similar to &lt;code&gt;PyBind11&lt;/code&gt;, which you saw above. That&amp;rsquo;s not a coincidence, as &lt;code&gt;PyBind11&lt;/code&gt; was based on this library! &lt;code&gt;Boost.Python&lt;/code&gt; is written in full C++ and supports most, if not all, versions of C++ on most platforms. In contrast, &lt;code&gt;PyBind11&lt;/code&gt; restricts itself to modern C++.&lt;/p&gt;
&lt;h3 id=&quot;sip&quot;&gt;&lt;code&gt;SIP&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.riverbankcomputing.com/software/sip/intro&quot;&gt;&lt;code&gt;SIP&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; is a toolset for generating Python bindings that was developed for the &lt;a href=&quot;https://realpython.com/python-pyqt-gui-calculator/&quot;&gt;PyQt&lt;/a&gt; project. It&amp;rsquo;s also used by the &lt;a href=&quot;https://realpython.com/python-gui-with-wxpython/&quot;&gt;wxPython&lt;/a&gt; project to generate their bindings, as well. It has a code generation tool and an extra Python module that provides support functions for the generated code.&lt;/p&gt;
&lt;h3 id=&quot;cppyy&quot;&gt;&lt;code&gt;Cppyy&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://cppyy.readthedocs.io/en/latest/&quot;&gt;&lt;code&gt;cppyy&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; is an interesting tool that has a slightly different design goal than what you&amp;rsquo;ve seen so far. In the words of the package author:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;The original idea behind cppyy (going back to 2001), was to allow Python programmers that live in a C++ world access to those C++ packages, without having to touch C++ directly (or wait for the C++ developers to come around and provide bindings).&amp;rdquo; (&lt;a href=&quot;https://news.ycombinator.com/item?id=15098764&quot;&gt;Source&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;shiboken&quot;&gt;&lt;code&gt;Shiboken&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://wiki.qt.io/Qt_for_Python/Shiboken&quot;&gt;&lt;code&gt;Shiboken&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; is a tool for generating Python bindings that&amp;rsquo;s developed for the PySide project associated with the Qt project. While it was designed as a tool for that project, the documentation indicates that it&amp;rsquo;s neither Qt- nor PySide-specific and is usable for other projects.&lt;/p&gt;
&lt;h3 id=&quot;swig&quot;&gt;&lt;code&gt;SWIG&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://swig.org/&quot;&gt;&lt;code&gt;SWIG&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; is a different tool than any of the others listed here. It&amp;rsquo;s a general tool used to create bindings to C and C++ programs for &lt;a href=&quot;http://swig.org/compat.html#SupportedLanguages&quot;&gt;many other languages&lt;/a&gt;, not just Python. This ability to generate bindings for different languages can be quite useful in some projects. It, of course, comes with a cost as far as complexity is concerned.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Congrats! You&amp;rsquo;ve now had an overview of several different options for creating &lt;strong&gt;Python bindings&lt;/strong&gt;. You&amp;rsquo;ve learned about marshalling data and issues you need to consider when creating bindings. You&amp;rsquo;ve seen what it takes to be able to call a C or C++ function from Python using the following tools:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;ctypes&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;CFFI&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;PyBind11&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Cython&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You now know that, while &lt;code&gt;ctypes&lt;/code&gt; allow you to load a DLL or shared library directly, the other three tools take an extra step, but still create a full Python module. As a bonus, you&amp;rsquo;ve also played a little with the &lt;code&gt;invoke&lt;/code&gt; tool to run command-line tasks from Python. You can get all of the code you saw in this tutorial by clicking the link below:&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Get Sample Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-bindings-code/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-bindings-code&quot; data-focus=&quot;false&quot;&gt;Click here to get the sample code you&#39;ll use&lt;/a&gt; to learn about Python Bindings in this tutorial.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;Now pick your favorite tool and start building those Python bindings! Special thanks to &lt;strong&gt;Loic Domaigne&lt;/strong&gt; for the extra technical review of this tutorial.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Beginner&#39;s Guide to Python Turtle</title>
      <id>https://realpython.com/beginners-guide-python-turtle/</id>
      <link href="https://realpython.com/beginners-guide-python-turtle/"/>
      <updated>2020-02-26T14:00:00+00:00</updated>
      <summary>In this step-by-step tutorial, you&#39;ll learn the basics of Python programming with the help of a simple and interactive Python library called turtle. If you&#39;re a beginner to Python, then this tutorial will definitely help you on your journey as you take your first steps into the world of programming.</summary>
      <content type="html">
        &lt;p&gt;When I was a kid, I used to learn &lt;a href=&quot;https://en.wikipedia.org/wiki/Logo_(programming_language)&quot;&gt;Logo&lt;/a&gt;, a programming language that involved a turtle that you could move around the screen with just a few commands. I remember feeling like a computer genius as I controlled this little object on my screen, and this was what got me interested in programming in the first place. The Python &lt;code&gt;turtle&lt;/code&gt; library comes with a similar interactive feature that gives new programmers a taste of what it&amp;rsquo;s like to work with Python.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this tutorial, you will:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Understand&lt;/strong&gt; what the Python &lt;code&gt;turtle&lt;/code&gt; library is&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learn&lt;/strong&gt; how to set &lt;code&gt;turtle&lt;/code&gt; up on your computer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Program&lt;/strong&gt; with the Python &lt;code&gt;turtle&lt;/code&gt; library&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grasp&lt;/strong&gt; some important Python concepts and &lt;code&gt;turtle&lt;/code&gt; commands&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Develop&lt;/strong&gt; a short but entertaining game using what you&amp;rsquo;ve learned&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;rsquo;re a beginner to Python, then this tutorial will help you as you take your first steps into the world of programming with the help of the Python &lt;code&gt;turtle&lt;/code&gt; library!&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-cheat-sheet-shortened&quot; data-focus=&quot;false&quot;&gt;Click here to get a Python Cheat Sheet&lt;/a&gt; and learn the basics of Python 3, like working with data types, dictionaries, lists, and Python functions.&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;getting-to-know-the-python-turtle-library&quot;&gt;Getting to Know the Python &lt;code&gt;turtle&lt;/code&gt; Library&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;turtle&lt;/code&gt; is a pre-installed Python library that enables users to create pictures and shapes by providing them with a virtual canvas. The onscreen pen that you use for drawing is called the &lt;strong&gt;turtle&lt;/strong&gt; and this is what gives the library its name. In short, the Python &lt;code&gt;turtle&lt;/code&gt; library helps new programmers get a feel for what programming with Python is like in a fun and interactive way.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;turtle&lt;/code&gt; is mainly used to introduce children to the world of computers. It&amp;rsquo;s a straightforward yet versatile way to understand the concepts of Python. This makes it a great avenue for &lt;a href=&quot;https://realpython.com/best-python-books/#python-for-kids-a-playful-introduction-to-programming&quot;&gt;kids&lt;/a&gt; to take their first steps in Python programming. That being said, the Python &lt;code&gt;turtle&lt;/code&gt; library is not restricted to little ones alone! It&amp;rsquo;s also proved extremely useful for adults who are trying their hands at Python, which makes it great for Python &lt;a href=&quot;https://realpython.com/learning-paths/python3-introduction/&quot;&gt;beginners&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With the Python &lt;code&gt;turtle&lt;/code&gt; library, you can draw and create various types of shapes and images. Here&amp;rsquo;s a sample of the kinds of drawings you can make with &lt;code&gt;turtle&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Turtle_Initial_Demo_GIF.923f9cc7d490.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Turtle_Initial_Demo_GIF.923f9cc7d490.gif&quot; width=&quot;480&quot; height=&quot;466&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Initial_Demo_GIF.923f9cc7d490.gif&amp;amp;w=120&amp;amp;sig=cc4adb8375170b9ca647820fcee23797a8a66024 120w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Initial_Demo_GIF.923f9cc7d490.gif&amp;amp;w=240&amp;amp;sig=e43f2a4d1d25f618079f347d694ee322c6b6ddc1 240w, https://files.realpython.com/media/Turtle_Initial_Demo_GIF.923f9cc7d490.gif 480w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Initial Demo&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cool, right? This is just one of many different drawings you can make using the Python &lt;code&gt;turtle&lt;/code&gt; library. Most developers use &lt;code&gt;turtle&lt;/code&gt; to draw shapes, create designs, and make images. Others use &lt;code&gt;turtle&lt;/code&gt; to create mini-games and animations, just like the one you saw above.&lt;/p&gt;
&lt;h2 id=&quot;getting-started-with-turtle&quot;&gt;Getting Started With &lt;code&gt;turtle&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Before you continue, there are two important things that you&amp;rsquo;ll need to do to make the most of this tutorial:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Python Environment:&lt;/strong&gt; Make sure that you&amp;rsquo;re familiar with your programming &lt;a href=&quot;https://realpython.com/learning-paths/perfect-your-python-development-setup/&quot;&gt;environment&lt;/a&gt;. You can use applications like &lt;a href=&quot;https://realpython.com/python-idle/&quot;&gt;IDLE&lt;/a&gt; or &lt;a href=&quot;https://realpython.com/jupyter-notebook-introduction/&quot;&gt;Jupyter Notebook&lt;/a&gt; to program with &lt;code&gt;turtle&lt;/code&gt;. However, if you&amp;rsquo;re not comfortable with them, then you can program with the &lt;a href=&quot;https://realpython.com/interacting-with-python/&quot;&gt;REPL&lt;/a&gt;, which you&amp;rsquo;ll use in this tutorial.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Python Version:&lt;/strong&gt; Ensure that you have &lt;a href=&quot;https://realpython.com/python-introduction/&quot;&gt;version 3 of Python&lt;/a&gt; on your computer. If not, then you can download it from the &lt;a href=&quot;https://www.python.org/downloads/&quot;&gt;Python website&lt;/a&gt;. For help setting things up, check out &lt;a href=&quot;https://realpython.com/installing-python/&quot;&gt;Python 3 Installation &amp;amp; Setup Guide&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The good thing about &lt;code&gt;turtle&lt;/code&gt; is that it&amp;rsquo;s a built-in library, so you don&amp;rsquo;t need to install any new packages. All you need to do is import the library into your Python environment, which in this case would be the REPL. Once you open your REPL application, you can run Python 3 on it by typing the following line of code:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;python3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This calls Python 3 into your REPL application and opens up the environment for you. &lt;/p&gt;
&lt;p&gt;Before you begin your Python programming, you need to understand what a &lt;strong&gt;library&lt;/strong&gt; is. In the non-computer world, a library is a place where different types of books are stored. You can access these books at any time, take whatever information you need from them, and return them to the same place.  &lt;/p&gt;
&lt;p&gt;In the computer world, a library works similarly. By definition, a &lt;strong&gt;library&lt;/strong&gt; is a set of important functions and methods that you can access to make your programming easier. The Python &lt;code&gt;turtle&lt;/code&gt; library contains all the methods and functions that you&amp;rsquo;ll need to create your images. To access a Python library, you need to import it into your Python environment, like this:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;turtle&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that you have &lt;code&gt;turtle&lt;/code&gt; in your Python environment, you can begin programming with it. &lt;code&gt;turtle&lt;/code&gt; is a graphical library, which means you&amp;rsquo;ll need to create a separate window (called the &lt;strong&gt;screen&lt;/strong&gt;) to carry out each drawing command. You can create this screen by initializing a variable for it.&lt;/p&gt;
&lt;p&gt;In Python, you use &lt;strong&gt;variables&lt;/strong&gt; to store information that you&amp;rsquo;ll use later on in your program. You &lt;strong&gt;initialize&lt;/strong&gt; a variable when you assign a starting value to it. Since the value of the variable isn&amp;rsquo;t constant, it can change several times during the execution of your program.&lt;/p&gt;
&lt;p&gt;Now, to open the &lt;code&gt;turtle&lt;/code&gt; screen, you initialize a variable for it in the following way:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;turtle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getscreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You should see a separate window open up:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-12-10_at_7.40.34_AM.86e4071c3bb4.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-12-10_at_7.40.34_AM.86e4071c3bb4.png&quot; width=&quot;719&quot; height=&quot;696&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-12-10_at_7.40.34_AM.86e4071c3bb4.png&amp;amp;w=179&amp;amp;sig=4fb33b3051670330c0f700df04f9cf5e59516ba1 179w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-12-10_at_7.40.34_AM.86e4071c3bb4.png&amp;amp;w=359&amp;amp;sig=890ce0952ddab8fee74fee1592337c7082c8a81d 359w, https://files.realpython.com/media/Screenshot_2019-12-10_at_7.40.34_AM.86e4071c3bb4.png 719w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Initial Screen New&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This window is called the &lt;strong&gt;screen&lt;/strong&gt;. It&amp;rsquo;s where you can view the output of your code. The little black triangular shape in the middle of the screen is called the &lt;strong&gt;turtle&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Keep in mind that when you name a variable, you need to pick a name that can be easily understood by anyone who&amp;rsquo;s looking at your program. However, you must also choose a name that&amp;rsquo;s convenient for you to use, especially because you&amp;rsquo;ll be calling it very often throughout your program!&lt;/p&gt;
&lt;p&gt;For example, choosing a name like &lt;code&gt;my_turtle_screen_name&lt;/code&gt; would be tedious to keep typing, while a name like &lt;code&gt;Joe&lt;/code&gt; or &lt;code&gt;a&lt;/code&gt; would appear to be very random. Using a single alphabet character, like &lt;code&gt;s&lt;/code&gt; in this case, would be much more suitable. That&amp;rsquo;s because it&amp;rsquo;s short and sweet, and it&amp;rsquo;s clear to remember that the letter &lt;code&gt;s&lt;/code&gt; refers to the &lt;strong&gt;screen&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Next, you initialize the variable &lt;code&gt;t&lt;/code&gt;, which you&amp;rsquo;ll then use throughout the program to refer to the turtle:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;turtle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Turtle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Just like for the screen, you can also give this variable another name like &lt;code&gt;a&lt;/code&gt; or &lt;code&gt;Jane&lt;/code&gt; or even &lt;code&gt;my_turtle&lt;/code&gt;, but in this case, you&amp;rsquo;ll stick with &lt;code&gt;t&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You now have your screen and your turtle. The screen acts as a canvas, while the turtle acts like a pen. You can program the turtle to move around the screen. The turtle has certain changeable characteristics, like size, color, and speed. It always points in a specific direction, and will move in that direction unless you tell it otherwise:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When it&amp;rsquo;s &lt;strong&gt;up&lt;/strong&gt;, it means that no line will be drawn when it moves.&lt;/li&gt;
&lt;li&gt;When it&amp;rsquo;s &lt;strong&gt;down&lt;/strong&gt;, it means that a line will be drawn when it moves.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the next section, you&amp;rsquo;ll explore the different ways of programming with the Python &lt;code&gt;turtle&lt;/code&gt; library.&lt;/p&gt;
&lt;h2 id=&quot;programming-with-turtle&quot;&gt;Programming With &lt;code&gt;turtle&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The first thing you&amp;rsquo;ll learn when it comes to programming with the Python &lt;code&gt;turtle&lt;/code&gt; library is how to make the turtle move in the direction you want it to go. Next, you&amp;rsquo;ll learn how to customize your turtle and its environment. Finally, you&amp;rsquo;ll learn a couple of extra commands with which you can perform some special tasks.&lt;/p&gt;
&lt;h3 id=&quot;moving-the-turtle&quot;&gt;Moving the Turtle&lt;/h3&gt;
&lt;p&gt;There are four directions that a turtle can move in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Forward&lt;/li&gt;
&lt;li&gt;Backward&lt;/li&gt;
&lt;li&gt;Left&lt;/li&gt;
&lt;li&gt;Right&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The turtle moves &lt;code&gt;.forward()&lt;/code&gt; or &lt;code&gt;.backward()&lt;/code&gt; in the direction that it&amp;rsquo;s facing. You can change this direction by turning it &lt;code&gt;.left()&lt;/code&gt; or &lt;code&gt;.right()&lt;/code&gt; by a certain degree. You can try each of these commands like so:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you run these commands, the turtle will turn right by ninety degrees, go forward by a hundred units, turn left by ninety degrees, and move backward by a hundred units. You can see how this looks in the image below:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Update_-_Moving_Turtle_VIDEO_GIF.61623cf40fed.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Update_-_Moving_Turtle_VIDEO_GIF.61623cf40fed.gif&quot; width=&quot;480&quot; height=&quot;466&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Update_-_Moving_Turtle_VIDEO_GIF.61623cf40fed.gif&amp;amp;w=120&amp;amp;sig=4d88c87883c41a1d08fa69b7106393c48a2c68d9 120w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Update_-_Moving_Turtle_VIDEO_GIF.61623cf40fed.gif&amp;amp;w=240&amp;amp;sig=a92b4c42dc3de4a9965d4facd40b416b8681752b 240w, https://files.realpython.com/media/Update_-_Moving_Turtle_VIDEO_GIF.61623cf40fed.gif 480w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Moving Updated&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can use the shortened versions of these commands as well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;t.rt()&lt;/code&gt;&lt;/strong&gt; instead of &lt;code&gt;t.right()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;t.fd()&lt;/code&gt;&lt;/strong&gt; instead of &lt;code&gt;t.forward()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;t.lt()&lt;/code&gt;&lt;/strong&gt; instead of &lt;code&gt;t.left()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;t.bk()&lt;/code&gt;&lt;/strong&gt; instead of &lt;code&gt;t.backward()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also draw a line from your current position to any other arbitrary position on the screen. This is done with the help of coordinates:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Turtle_EDIT_Graph.790c213ce0ba.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/Turtle_EDIT_Graph.790c213ce0ba.jpg&quot; width=&quot;1080&quot; height=&quot;1080&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_EDIT_Graph.790c213ce0ba.jpg&amp;amp;w=270&amp;amp;sig=cc34b23be8c86e13fd76b8df78506813e18381aa 270w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_EDIT_Graph.790c213ce0ba.jpg&amp;amp;w=540&amp;amp;sig=65da7d36011257ddb6720849a7f89b2cf40cf6df 540w, https://files.realpython.com/media/Turtle_EDIT_Graph.790c213ce0ba.jpg 1080w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Coordinates New&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The screen is divided into four &lt;a href=&quot;https://www.mathsisfun.com/data/cartesian-coordinates.html&quot;&gt;quadrants&lt;/a&gt;. The point where the turtle is initially positioned at the beginning of your program is &lt;code&gt;(0,0)&lt;/code&gt;. This is called &lt;strong&gt;Home&lt;/strong&gt;. To move the turtle to any other area on the screen, you use &lt;code&gt;.goto()&lt;/code&gt; and enter the coordinates like this:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Your output will look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/TURTLE_EDIT_GOTO_GIF.ac9b7de34b40.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/TURTLE_EDIT_GOTO_GIF.ac9b7de34b40.gif&quot; width=&quot;480&quot; height=&quot;464&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/TURTLE_EDIT_GOTO_GIF.ac9b7de34b40.gif&amp;amp;w=120&amp;amp;sig=0f21b492a89e0f761f0d307ac9946bfb50471ab0 120w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/TURTLE_EDIT_GOTO_GIF.ac9b7de34b40.gif&amp;amp;w=240&amp;amp;sig=e4b16d16ea36c7e9231a096160f67ac058ccba03 240w, https://files.realpython.com/media/TURTLE_EDIT_GOTO_GIF.ac9b7de34b40.gif 480w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle GOTO NEWER&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ve drawn a line from your current position to the point &lt;code&gt;(100,100)&lt;/code&gt; on the screen.&lt;/p&gt;
&lt;p&gt;To bring the turtle back to its home position, you type the following:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;home&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is like a shortcut command that sends the turtle back to the point &lt;code&gt;(0,0)&lt;/code&gt;. It&amp;rsquo;s quicker than typing &lt;code&gt;t.goto(0,0)&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;drawing-a-shape&quot;&gt;Drawing a Shape&lt;/h3&gt;
&lt;p&gt;Now that you know the movements of the turtle, you can move on to making actual shapes. You can start by drawing &lt;strong&gt;polygons&lt;/strong&gt; since they all consist of straight lines connected at certain angles. Here&amp;rsquo;s an example that you can try:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Your output will look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/TURTLE_SQUARE_EDIT.626bc3fccd67.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/TURTLE_SQUARE_EDIT.626bc3fccd67.gif&quot; width=&quot;480&quot; height=&quot;466&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/TURTLE_SQUARE_EDIT.626bc3fccd67.gif&amp;amp;w=120&amp;amp;sig=bb34898ec7631bf4744534d9e8a7d9bc8de5f8c7 120w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/TURTLE_SQUARE_EDIT.626bc3fccd67.gif&amp;amp;w=240&amp;amp;sig=a52d5e6df9e5559aa369f7ddcdc5b6293864e1bb 240w, https://files.realpython.com/media/TURTLE_SQUARE_EDIT.626bc3fccd67.gif 480w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Square Edit Newer&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Well done! You&amp;rsquo;ve just drawn a square. In this way, the turtle can be programmed to &lt;strong&gt;create different shapes and images&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now, try drawing a rectangle, using this code as a template. Remember, in a rectangle, all four sides are not equal. You&amp;rsquo;ll need to change the code accordingly. Once you do that, you can even try creating other polygons by increasing the number of sides and changing the angles.&lt;/p&gt;
&lt;h3 id=&quot;drawing-preset-figures&quot;&gt;Drawing Preset Figures&lt;/h3&gt;
&lt;p&gt;Suppose you want to draw a &lt;strong&gt;circle&lt;/strong&gt;. If you attempt to draw it in the same way as you drew the square, then it would be extremely tedious, and you&amp;rsquo;d have to spend a lot of time just for that one shape. Thankfully, the Python &lt;code&gt;turtle&lt;/code&gt; library provides a solution for this. You can use a single command to draw a circle:  &lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You&amp;rsquo;ll get an output like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Update_-_Turtle_Circle_GIF.14906fdf5060.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Update_-_Turtle_Circle_GIF.14906fdf5060.gif&quot; width=&quot;480&quot; height=&quot;468&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Update_-_Turtle_Circle_GIF.14906fdf5060.gif&amp;amp;w=120&amp;amp;sig=fb55632f30e6cce21aeb8af7e0977b71bbdad497 120w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Update_-_Turtle_Circle_GIF.14906fdf5060.gif&amp;amp;w=240&amp;amp;sig=41ada7841b22562573f8edba581ba30743114d6c 240w, https://files.realpython.com/media/Update_-_Turtle_Circle_GIF.14906fdf5060.gif 480w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Circle Updated&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The number within the brackets is the &lt;strong&gt;radius&lt;/strong&gt; of the circle. You can increase or decrease the size of the circle by changing the value of its radius.&lt;/p&gt;
&lt;p&gt;In the same way, you can also draw a &lt;strong&gt;dot&lt;/strong&gt;, which is nothing but a filled-in circle. Type in this command:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You&amp;rsquo;ll get a filled-in circle like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Turtle_Dot_Pic.8f171e2c7d98.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Turtle_Dot_Pic.8f171e2c7d98.png&quot; width=&quot;721&quot; height=&quot;697&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Dot_Pic.8f171e2c7d98.png&amp;amp;w=180&amp;amp;sig=261d823f4f873214a18dc8cc1ed6a1b71aa359a3 180w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Dot_Pic.8f171e2c7d98.png&amp;amp;w=360&amp;amp;sig=da357dac4d8007bdb867d2fb86036220f3bce2f3 360w, https://files.realpython.com/media/Turtle_Dot_Pic.8f171e2c7d98.png 721w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Dot Update&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The number within the brackets is the diameter of the dot. Just like with the circle, you can increase or decrease the size of the dot by changing the value of its diameter.&lt;/p&gt;
&lt;p&gt;Great job so far! You&amp;rsquo;ve learned how to move the turtle around and create different shapes with it. In the next few sections, you&amp;rsquo;ll see how you can customize your turtle and its environment, based on your requirements.&lt;/p&gt;
&lt;h3 id=&quot;changing-the-screen-color&quot;&gt;Changing the Screen Color&lt;/h3&gt;
&lt;p&gt;By default, &lt;code&gt;turtle&lt;/code&gt; always opens up a screen with a white background. However, you can change the &lt;strong&gt;color&lt;/strong&gt; of the screen at any time using the following command:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;turtle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bgcolor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;blue&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can replace &lt;code&gt;&quot;blue&quot;&lt;/code&gt; with any other color. Try &lt;code&gt;&quot;green&quot;&lt;/code&gt; or &lt;code&gt;&quot;red&quot;&lt;/code&gt;. You&amp;rsquo;ll get a result like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/1-BG_COLOR-GIF.8619d9e1783f.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/1-BG_COLOR-GIF.8619d9e1783f.gif&quot; width=&quot;478&quot; height=&quot;462&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/1-BG_COLOR-GIF.8619d9e1783f.gif&amp;amp;w=119&amp;amp;sig=a1ea2fa9bed21e6b030db10587ffd93b9bc63942 119w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/1-BG_COLOR-GIF.8619d9e1783f.gif&amp;amp;w=239&amp;amp;sig=7cd5fe99eee5a37ad51497d44040881ec5caf9d6 239w, https://files.realpython.com/media/1-BG_COLOR-GIF.8619d9e1783f.gif 478w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Background Color&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can use a variety of colors for your screen just by typing in their &lt;a href=&quot;https://en.wikipedia.org/wiki/Web_colors&quot;&gt;hex code&lt;/a&gt; number. To learn more about using different colors, check out the Python &lt;code&gt;turtle&lt;/code&gt; library &lt;a href=&quot;https://docs.python.org/3/library/turtle.html#turtle.color&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;changing-the-screen-title&quot;&gt;Changing the Screen Title&lt;/h3&gt;
&lt;p&gt;Sometimes, you may want to change the &lt;strong&gt;title&lt;/strong&gt; of your screen. You can make it more personal, like &lt;code&gt;&quot;My Turtle Program&quot;&lt;/code&gt;, or more suitable to what you&amp;rsquo;re working on, like &lt;code&gt;&quot;Drawing Shapes With Turtle&quot;&lt;/code&gt;. You can change the title of your screen with the help of this command:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;turtle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;My Turtle Program&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Your title bar will now display this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Change_in_Screen_Title_UPDATE.bf645f90e3d0.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Change_in_Screen_Title_UPDATE.bf645f90e3d0.jpg&quot; width=&quot;600&quot; height=&quot;200&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Change_in_Screen_Title_UPDATE.bf645f90e3d0.jpg&amp;amp;w=150&amp;amp;sig=e3c015a0849fc377fe72189c997d8a16df69a7a9 150w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Change_in_Screen_Title_UPDATE.bf645f90e3d0.jpg&amp;amp;w=300&amp;amp;sig=1767a2a226f5d1ad559473db3206a63425511ad9 300w, https://files.realpython.com/media/Change_in_Screen_Title_UPDATE.bf645f90e3d0.jpg 600w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Screen Title Updated&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this way, you can change the heading of your screen according to your preference.&lt;/p&gt;
&lt;h3 id=&quot;changing-the-turtle-size&quot;&gt;Changing the Turtle Size&lt;/h3&gt;
&lt;p&gt;You can increase or decrease the &lt;strong&gt;size&lt;/strong&gt; of the onscreen turtle to make it bigger or smaller. This changes only the size of the shape without affecting the output of the pen as it draws on the screen. Try typing in the following commands:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shapesize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shapesize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shapesize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shapesize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Your outputs will look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Turtle_Shape_Size_Updated_GIF.3f31c5f85340.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Turtle_Shape_Size_Updated_GIF.3f31c5f85340.gif&quot; width=&quot;478&quot; height=&quot;462&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Shape_Size_Updated_GIF.3f31c5f85340.gif&amp;amp;w=119&amp;amp;sig=9c440877970f45261b1ad23417e2195ea2322c9e 119w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Shape_Size_Updated_GIF.3f31c5f85340.gif&amp;amp;w=239&amp;amp;sig=f1e9deb37a673299f5574a16a88e783e800e9be4 239w, https://files.realpython.com/media/Turtle_Shape_Size_Updated_GIF.3f31c5f85340.gif 478w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Shape Size Updated&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The numbers given are the &lt;strong&gt;parameters&lt;/strong&gt; for the size of the turtle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stretch length&lt;/li&gt;
&lt;li&gt;Stretch width&lt;/li&gt;
&lt;li&gt;Outline width&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can change these according to your preference. In the example given above, you can see a visible difference in the appearance of the turtle. For more information on how you can change the size of the turtle, check out the Python &lt;code&gt;turtle&lt;/code&gt; library &lt;a href=&quot;https://docs.python.org/3/library/turtle.html#turtle.turtlesize&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;changing-the-pen-size&quot;&gt;Changing the Pen Size&lt;/h3&gt;
&lt;p&gt;The previous command changed the size of the turtle&amp;rsquo;s shape only. However, sometimes, you may need to increase or decrease the &lt;strong&gt;thickness&lt;/strong&gt; of your pen. You can do this using the following command:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pensize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This results in an outcome like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Pen_Size_GIF.4d1fb1beefd6.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Pen_Size_GIF.4d1fb1beefd6.gif&quot; width=&quot;478&quot; height=&quot;464&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Pen_Size_GIF.4d1fb1beefd6.gif&amp;amp;w=119&amp;amp;sig=1a442a93d46014cb70a19e81601d7f005d604884 119w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Pen_Size_GIF.4d1fb1beefd6.gif&amp;amp;w=239&amp;amp;sig=c15ceefff99f1eeb37f11982bb8567aa99f45512 239w, https://files.realpython.com/media/Pen_Size_GIF.4d1fb1beefd6.gif 478w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Pen Size More NEW&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see, the size of your pen is now five times the original size (which was one). Try drawing some more lines of various sizes, and compare the difference in thickness between them.&lt;/p&gt;
&lt;h3 id=&quot;changing-the-turtle-and-pen-color&quot;&gt;Changing the Turtle and Pen Color&lt;/h3&gt;
&lt;p&gt;When you first open a new screen, the turtle starts out as a black figure and draws with black ink. Based on your requirements, you can do two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Change the color of the turtle:&lt;/strong&gt; This changes the fill color.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Change the color of the pen:&lt;/strong&gt; This changes the outline or the ink color.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can even choose both of these if you wish. Before you change the colors, increase the size of your turtle to help you see the color difference more clearly. Type in this code:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shapesize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, to change the color of the turtle (or the fill), you type the following:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fillcolor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Your turtle will look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Turtle_Fill_Color_Red_Update.216d34fcf201.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Turtle_Fill_Color_Red_Update.216d34fcf201.png&quot; width=&quot;722&quot; height=&quot;698&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Fill_Color_Red_Update.216d34fcf201.png&amp;amp;w=180&amp;amp;sig=799fb83415df10e432acb6112856729df05b76c9 180w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Fill_Color_Red_Update.216d34fcf201.png&amp;amp;w=361&amp;amp;sig=097b3ad456889f3f4a6c71f3334ef28bf774ca11 361w, https://files.realpython.com/media/Turtle_Fill_Color_Red_Update.216d34fcf201.png 722w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Fill Color Red&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To change the color of the pen (or the outline), you type the following:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pencolor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;green&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Your turtle will look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Turtle_Pen_Color_Updated.362202ac18cb.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Turtle_Pen_Color_Updated.362202ac18cb.png&quot; width=&quot;721&quot; height=&quot;698&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Pen_Color_Updated.362202ac18cb.png&amp;amp;w=180&amp;amp;sig=6cf4e41f4efd673c82f9aebcfbec86c4bee83f6b 180w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Pen_Color_Updated.362202ac18cb.png&amp;amp;w=360&amp;amp;sig=df4dc2ac68818ef14845298c6fb912653d707ce6 360w, https://files.realpython.com/media/Turtle_Pen_Color_Updated.362202ac18cb.png 721w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Pen Color Updated Green&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To change the color of both, you type the following:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;green&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Your turtle will look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Turtle_Color_One_Line_Green_and_Red_Updated.060568e73634.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Turtle_Color_One_Line_Green_and_Red_Updated.060568e73634.png&quot; width=&quot;720&quot; height=&quot;699&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Color_One_Line_Green_and_Red_Updated.060568e73634.png&amp;amp;w=180&amp;amp;sig=91f906d6a23c1214c1c113c59a81fa3834ac345d 180w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Color_One_Line_Green_and_Red_Updated.060568e73634.png&amp;amp;w=360&amp;amp;sig=97faf3415c3694a077822f58f8d903634910f050 360w, https://files.realpython.com/media/Turtle_Color_One_Line_Green_and_Red_Updated.060568e73634.png 720w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Color Single Line Updated&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here, the first color is for the pen, and the second is for the fill. Note that changing the color of the pen and the fill also changes the color of the onscreen turtle accordingly.&lt;/p&gt;
&lt;h3 id=&quot;filling-in-an-image&quot;&gt;Filling in an Image&lt;/h3&gt;
&lt;p&gt;Coloring in an image usually makes it look better, doesn&amp;rsquo;t it? The Python &lt;code&gt;turtle&lt;/code&gt; library gives you the option to add color to your drawings. Try typing in the following code and see what happens:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin_fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;120&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;120&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end_fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you execute this code, you&amp;rsquo;ll get a triangle that&amp;rsquo;s filled in with a solid color, like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Turtle_Begin_End_Fill_GIF.849f73374a22.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Turtle_Begin_End_Fill_GIF.849f73374a22.gif&quot; width=&quot;478&quot; height=&quot;462&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Begin_End_Fill_GIF.849f73374a22.gif&amp;amp;w=119&amp;amp;sig=dacdd589820b6b152df6827f860aad7be0898cf8 119w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Turtle_Begin_End_Fill_GIF.849f73374a22.gif&amp;amp;w=239&amp;amp;sig=243a7a14c03eecd557d354a35fd99fd522195811 239w, https://files.realpython.com/media/Turtle_Begin_End_Fill_GIF.849f73374a22.gif 478w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Begin Fill End Fill New&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When you use &lt;code&gt;.beginfill()&lt;/code&gt;, you&amp;rsquo;re telling your program that you&amp;rsquo;re going to be drawing a closed shape which will need to be filled in. Then, you use &lt;code&gt;.endfill()&lt;/code&gt; to indicate that you&amp;rsquo;re done creating your shape and it can now be filled in.&lt;/p&gt;
&lt;h3 id=&quot;changing-the-turtle-shape&quot;&gt;Changing the Turtle Shape&lt;/h3&gt;
&lt;p&gt;The initial shape of the turtle isn&amp;rsquo;t really a turtle, but a triangular figure. However, you can &lt;strong&gt;change the way the turtle looks&lt;/strong&gt;, and you do have a couple of options when it comes to doing so. You can have a look at some of them by typing in the following commands:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;turtle&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;arrow&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;circle&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The shape of the turtle will change accordingly, like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/4-Turtle_Shape-Gif.daf6a648bd8c.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/4-Turtle_Shape-Gif.daf6a648bd8c.gif&quot; width=&quot;478&quot; height=&quot;462&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/4-Turtle_Shape-Gif.daf6a648bd8c.gif&amp;amp;w=119&amp;amp;sig=fd64cb6a420686bcf0262fce5ebf085dc5899b5e 119w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/4-Turtle_Shape-Gif.daf6a648bd8c.gif&amp;amp;w=239&amp;amp;sig=a2886eb17ceeca44945fd6dc412b84d4ce86554d 239w, https://files.realpython.com/media/4-Turtle_Shape-Gif.daf6a648bd8c.gif 478w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Shapes&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You have a couple of other options that you can try as well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Square&lt;/li&gt;
&lt;li&gt;Arrow&lt;/li&gt;
&lt;li&gt;Circle&lt;/li&gt;
&lt;li&gt;Turtle&lt;/li&gt;
&lt;li&gt;Triangle&lt;/li&gt;
&lt;li&gt;Classic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The classic shape is the original shape. Check out the Python &lt;code&gt;turtle&lt;/code&gt; library &lt;a href=&quot;https://docs.python.org/3/library/turtle.html#turtle.shape&quot;&gt;documentation&lt;/a&gt; to learn more about the types of shapes that you can use.&lt;/p&gt;
&lt;h3 id=&quot;changing-the-pen-speed&quot;&gt;Changing the Pen Speed&lt;/h3&gt;
&lt;p&gt;The turtle generally moves at a moderate pace. If you want to decrease or increase the &lt;strong&gt;speed&lt;/strong&gt; to make your turtle move slower or faster, then you can do so by typing the following:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This code will first decrease the speed and move the turtle forward, then increase the speed and move the turtle forward again, like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Update_-_Turtle_Speed_1_and_10.a35c56e8f016.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Update_-_Turtle_Speed_1_and_10.a35c56e8f016.gif&quot; width=&quot;480&quot; height=&quot;466&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Update_-_Turtle_Speed_1_and_10.a35c56e8f016.gif&amp;amp;w=120&amp;amp;sig=d2ccf8d55f0ea1f21d65de0dea6507eb29c95086 120w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Update_-_Turtle_Speed_1_and_10.a35c56e8f016.gif&amp;amp;w=240&amp;amp;sig=b649f4a96758dbae6b90775e8c270068171a7a3d 240w, https://files.realpython.com/media/Update_-_Turtle_Speed_1_and_10.a35c56e8f016.gif 480w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Speed Updated&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The speed can be any number ranging from 0 (the slowest speed) to 10 (the highest speed). You can play around with your code to see how fast or slow the turtle will go.&lt;/p&gt;
&lt;h3 id=&quot;customizing-in-one-line&quot;&gt;Customizing in One Line&lt;/h3&gt;
&lt;p&gt;Suppose you want to set your turtle&amp;rsquo;s characteristics to the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pen color:&lt;/strong&gt; purple&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fill color:&lt;/strong&gt; orange&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pen size:&lt;/strong&gt; 10&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pen speed:&lt;/strong&gt; 9&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From what you&amp;rsquo;ve just learned, the code should look something like this:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pencolor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;purple&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fillcolor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;orange&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pensize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin_fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end_fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It&amp;rsquo;s pretty long, but not that bad, right?&lt;/p&gt;
&lt;p&gt;Now, just imagine if you had &lt;strong&gt;ten different turtles&lt;/strong&gt;. Changing all of their characteristics would be extremely tiresome for you to do! The good news is that you can reduce your workload by altering the parameters in just a single line of code, like this:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pencolor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;purple&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fillcolor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;orange&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pensize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin_fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end_fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will give you a result like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/TURTLE_EDIT_SINGLE_LINE_CUSTOMISATION_GIF.c30c0839af72.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/TURTLE_EDIT_SINGLE_LINE_CUSTOMISATION_GIF.c30c0839af72.gif&quot; width=&quot;480&quot; height=&quot;466&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/TURTLE_EDIT_SINGLE_LINE_CUSTOMISATION_GIF.c30c0839af72.gif&amp;amp;w=120&amp;amp;sig=cdc6671664565c128133682dec60c86831c89a46 120w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/TURTLE_EDIT_SINGLE_LINE_CUSTOMISATION_GIF.c30c0839af72.gif&amp;amp;w=240&amp;amp;sig=c374f4a7bb77f56a9feb426a30c27ed8c0ed4c5c 240w, https://files.realpython.com/media/TURTLE_EDIT_SINGLE_LINE_CUSTOMISATION_GIF.c30c0839af72.gif 480w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Single Line Pen Newer&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This single line of code changed the entire pen, without you having to change each characteristic individually. To learn more about this command, check out the Python &lt;code&gt;turtle&lt;/code&gt; library &lt;a href=&quot;https://docs.python.org/3/library/turtle.html#turtle.pen&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Great job! Now that you&amp;rsquo;ve learned to customize your turtle and the screen, take a look at some other important commands that are required while drawing with the Python &lt;code&gt;turtle&lt;/code&gt; library.&lt;/p&gt;
&lt;h3 id=&quot;picking-the-pen-up-and-down&quot;&gt;Picking the Pen Up and Down&lt;/h3&gt;
&lt;p&gt;Sometimes, you may want to move your turtle to another point on the screen without drawing anything on the screen itself. To do this, you use &lt;code&gt;.penup()&lt;/code&gt;. Then, when you want to start drawing again, you use &lt;code&gt;.pendown()&lt;/code&gt;. Give it a shot using the code that you used previously to draw a square. Try typing the following code:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;penup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pendown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;penup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pendown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you run this code, your output will look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-10-01_at_9.22.37_PM.20eeea07c674.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-10-01_at_9.22.37_PM.20eeea07c674.png&quot; width=&quot;716&quot; height=&quot;695&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-10-01_at_9.22.37_PM.20eeea07c674.png&amp;amp;w=179&amp;amp;sig=1b1ca83fb71244085cdf272c0a694917644da91c 179w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-10-01_at_9.22.37_PM.20eeea07c674.png&amp;amp;w=358&amp;amp;sig=3df27bbb807b4451fa58eabf849699bf59662fbf 358w, https://files.realpython.com/media/Screenshot_2019-10-01_at_9.22.37_PM.20eeea07c674.png 716w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Pen Up Pen Down Edit&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here, you&amp;rsquo;ve obtained two parallel lines instead of a square by adding some extra commands in between the original program.&lt;/p&gt;
&lt;h3 id=&quot;undoing-changes&quot;&gt;Undoing Changes&lt;/h3&gt;
&lt;p&gt;No matter how careful you are, there&amp;rsquo;s always a possibility of making a mistake. Don&amp;rsquo;t worry, though! The Python &lt;code&gt;turtle&lt;/code&gt; library gives you the option to undo what you&amp;rsquo;ve done. If you want to &lt;strong&gt;undo&lt;/strong&gt; the very last thing you did, then type in the following:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This undoes the last command that you ran. If you want to undo your last three commands, then you would type &lt;code&gt;t.undo()&lt;/code&gt; three times.&lt;/p&gt;
&lt;h3 id=&quot;clearing-the-screen&quot;&gt;Clearing the Screen&lt;/h3&gt;
&lt;p&gt;Right now, you probably have a lot on your screen since you&amp;rsquo;ve started this tutorial. To make room for more, just type in the following command:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will clean up your screen so that you can continue drawing. Note here that your variables will not change, and the turtle will remain in the same position. If you have other turtles on your screen other than the original turtle, then their drawings will not be cleared out unless you specifically call them out in your code.&lt;/p&gt;
&lt;h3 id=&quot;resetting-the-environment&quot;&gt;Resetting the Environment&lt;/h3&gt;
&lt;p&gt;You also have the option to start on a clean slate with a &lt;strong&gt;reset&lt;/strong&gt; command. The screen will get cleared up, and the turtle&amp;rsquo;s settings will all be restored to their default parameters. All you need to to do is type in the following command:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This clears the screen and takes the turtle back to its home position. Your default settings, like the turtle&amp;rsquo;s size, shape, color, and other features, will also be restored.&lt;/p&gt;
&lt;p&gt;Now that you&amp;rsquo;ve learned the fundamentals of programming with the Python &lt;code&gt;turtle&lt;/code&gt; library, you&amp;rsquo;ll check out some bonus features that you may want to use while programming.&lt;/p&gt;
&lt;h3 id=&quot;leaving-a-stamp&quot;&gt;Leaving a Stamp&lt;/h3&gt;
&lt;p&gt;You have the option of leaving a &lt;strong&gt;stamp&lt;/strong&gt; of your turtle on the screen, which is nothing but an imprint of the turtle. Try typing in this code to see how it works:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;9&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Your output will look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/RP_STAMPS_GIF.05609e29d05f.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/RP_STAMPS_GIF.05609e29d05f.gif&quot; width=&quot;478&quot; height=&quot;462&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/RP_STAMPS_GIF.05609e29d05f.gif&amp;amp;w=119&amp;amp;sig=59d6c1ab3b2cb768fcbc48ba8a6a76cfab898190 119w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/RP_STAMPS_GIF.05609e29d05f.gif&amp;amp;w=239&amp;amp;sig=2c92242ff1f15e44e69d3d7fa353f19b976fb0cd 239w, https://files.realpython.com/media/RP_STAMPS_GIF.05609e29d05f.gif 478w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Stamps Edit&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The numbers that appear are the turtle&amp;rsquo;s location or &lt;strong&gt;stamp ID&lt;/strong&gt;. Now, if you want to remove a particular stamp, then just use the following:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clearstamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will clear the one with the stamp ID of &lt;code&gt;8&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;cloning-your-turtle&quot;&gt;Cloning Your Turtle&lt;/h3&gt;
&lt;p&gt;Sometimes, you may need to have more than one turtle on your screen. You&amp;rsquo;ll see an example of this later on in the final project. For now, you can get another turtle by &lt;strong&gt;cloning&lt;/strong&gt; your current turtle into your environment. Try running this code to create a clone turtle, &lt;code&gt;c&lt;/code&gt;, and then move both the turtles on the screen:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;magenta&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output will look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/TURTLE_EDIT_CLONE_GIF.1736204d0292.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/TURTLE_EDIT_CLONE_GIF.1736204d0292.gif&quot; width=&quot;480&quot; height=&quot;466&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/TURTLE_EDIT_CLONE_GIF.1736204d0292.gif&amp;amp;w=120&amp;amp;sig=84903c4baba464b3fc82240c28c0900b163614bb 120w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/TURTLE_EDIT_CLONE_GIF.1736204d0292.gif&amp;amp;w=240&amp;amp;sig=56a66eea63c428e9ef9bebb41c77b8c90ed35c35 240w, https://files.realpython.com/media/TURTLE_EDIT_CLONE_GIF.1736204d0292.gif 480w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Clone NEWER&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Awesome!&lt;/p&gt;
&lt;p&gt;Now that you have an idea of some important commands from the Python &lt;code&gt;turtle&lt;/code&gt; library, you&amp;rsquo;re ready to move on to a few more concepts that you&amp;rsquo;ll need to understand. These concepts are very much needed when it comes to programming in any language.&lt;/p&gt;
&lt;h2 id=&quot;using-loops-and-conditional-statements&quot;&gt;Using Loops and Conditional Statements&lt;/h2&gt;
&lt;p&gt;When you get into higher-level programming, you&amp;rsquo;ll find yourself using &lt;strong&gt;loops and conditional statements&lt;/strong&gt; very often. That&amp;rsquo;s why, in this section, you&amp;rsquo;ll be going through a couple of turtle programs that make use of these types of commands. This will give you a practical approach when it comes to understanding these concepts. Before you begin, however, here are three definitions for you to keep in mind:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Loops&lt;/strong&gt; are a set of instructions that are continuously repeated until a particular condition is satisfied.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conditional statements&lt;/strong&gt; carry out a certain task based on a condition that&amp;rsquo;s satisfied.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Indentations&lt;/strong&gt; are used to define blocks of code, especially when using loops and conditional statements. In general, you create an indentation by tapping the &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-tab&quot;&gt;Tab&lt;/kbd&gt;&lt;/span&gt; key on the keyboard.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, let&amp;rsquo;s go ahead and explore these commands!&lt;/p&gt;
&lt;h3 id=&quot;for-loops&quot;&gt;&lt;code&gt;for&lt;/code&gt; Loops&lt;/h3&gt;
&lt;p&gt;Do you remember the program that you used to create a square? You had to repeat the same line of code four times, like this:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A much shorter way to do this is with the help of a &lt;a href=&quot;https://realpython.com/courses/python-for-loop/&quot;&gt;&lt;code&gt;for&lt;/code&gt; loop&lt;/a&gt;. Try running this code:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, the &lt;code&gt;i&lt;/code&gt; is like a &lt;strong&gt;counter&lt;/strong&gt; that starts from zero and keeps increasing by 1. When you say &lt;code&gt;in range(4)&lt;/code&gt;, you&amp;rsquo;re telling the program that the value of this &lt;code&gt;i&lt;/code&gt; should be less than 4. It will terminate the program before &lt;code&gt;i&lt;/code&gt; reaches 4.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a breakdown of how the program works:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;At i = 0,&lt;/strong&gt; the turtle moves forward by 100 units and then turns 90 degrees to the right.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;At i = 0 + 1 = 1,&lt;/strong&gt; the turtle moves forward by 100 units and then turns 90 degrees to the right.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;At i = 1 + 1 = 2,&lt;/strong&gt; the turtle moves forward by 100 units and then turns 90 degrees to the right.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;At i = 2 + 1 = 3,&lt;/strong&gt; the turtle moves forward by 100 units and then turns 90 degrees to the right.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The turtle will then exit the loop. To check the value of &lt;code&gt;i&lt;/code&gt;, type &lt;code&gt;i&lt;/code&gt; and then press the &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt; key. You&amp;rsquo;ll get the value of &lt;code&gt;i&lt;/code&gt; equal to 3:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that the whitespace that comes before line 2 and line 3 in the program is the &lt;strong&gt;indentation&lt;/strong&gt;. This indicates that all 3 lines form a single block of code. To learn more about &lt;code&gt;for&lt;/code&gt; loops in Python, check out &lt;a href=&quot;https://realpython.com/python-for-loop/&quot;&gt;Python &amp;ldquo;for&amp;rdquo; Loops (Definite Iteration)&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;while-loops&quot;&gt;&lt;code&gt;while&lt;/code&gt; Loops&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://realpython.com/courses/mastering-while-loops/&quot;&gt;&lt;code&gt;while&lt;/code&gt; loop&lt;/a&gt; is used to perform a certain task while a condition is still satisfied. If the condition is no longer satisfied, then your code will terminate the process. You can use a &lt;code&gt;while&lt;/code&gt; loop to create a series of circles by typing in this code:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you run this code, you&amp;rsquo;ll see the circles appearing one after the other, and each new circle will be larger than the previous one:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/TURTLE_EDIT_WHILE_LOOP_GIF.c0b9eae029cc.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/TURTLE_EDIT_WHILE_LOOP_GIF.c0b9eae029cc.gif&quot; width=&quot;480&quot; height=&quot;466&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/TURTLE_EDIT_WHILE_LOOP_GIF.c0b9eae029cc.gif&amp;amp;w=120&amp;amp;sig=63c77d71ba256b6917b75ee008eb9d83477b90c2 120w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/TURTLE_EDIT_WHILE_LOOP_GIF.c0b9eae029cc.gif&amp;amp;w=240&amp;amp;sig=8b5db6dfbc7779c1f4c48b4ce7a1ccc6bf73658b 240w, https://files.realpython.com/media/TURTLE_EDIT_WHILE_LOOP_GIF.c0b9eae029cc.gif 480w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle While Loop Edited Newer&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here, &lt;code&gt;n&lt;/code&gt; is used as a counter. You&amp;rsquo;ll need to specify by how much you want the value of &lt;code&gt;n&lt;/code&gt; to increase in each loop. Take a look at this mini walk-through to see how the program works:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;At n = 10,&lt;/strong&gt; the turtle draws a circle with a radius of 10 units. After that, the value of &lt;code&gt;n&lt;/code&gt; is increased by 10.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;At n = 20,&lt;/strong&gt; the turtle draws a circle with a radius of 20 units. Once again, the value of &lt;code&gt;n&lt;/code&gt; is increased by 10.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;At n = 30,&lt;/strong&gt; the turtle draws a circle with a radius of 30 units. For the third time, the value of &lt;code&gt;n&lt;/code&gt; is increased by 10.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;At n = 40,&lt;/strong&gt; the turtle draws a circle with a radius of 40 units. For the last time, the value of &lt;code&gt;n&lt;/code&gt; is increased by 10.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;At n = 50,&lt;/strong&gt; &lt;code&gt;n&lt;/code&gt; is no longer less than or equal to 40. The loop is terminated.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To read more about &lt;code&gt;while&lt;/code&gt; loops, check out &lt;a href=&quot;https://realpython.com/python-while-loop/&quot;&gt;Python &amp;ldquo;while&amp;rdquo; Loops (Indefinite Iteration)&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;conditional-statements&quot;&gt;Conditional Statements&lt;/h3&gt;
&lt;p&gt;You use &lt;a href=&quot;https://realpython.com/courses/python-conditional-statements/&quot;&gt;conditional statements&lt;/a&gt; to check if a given condition is true. If it is, then the corresponding command is executed. Try typing in this program:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Would you like me to draw a shape? Type yes or no: &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;input()&lt;/code&gt; is used to obtain &lt;strong&gt;input&lt;/strong&gt; from the user. Here, it will store the user&amp;rsquo;s response under the variable &lt;code&gt;u&lt;/code&gt;. Next, it will compare the value of &lt;code&gt;u&lt;/code&gt; with the condition provided and check whether the value of &lt;code&gt;u&lt;/code&gt; is &lt;code&gt;&quot;yes&quot;&lt;/code&gt;. If it&amp;rsquo;s &lt;code&gt;&quot;yes&quot;&lt;/code&gt;, then your program draws a circle. If the user types in anything else, then the program won&amp;rsquo;t do anything.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The comparison operator &lt;code&gt;==&lt;/code&gt; indicates a &lt;strong&gt;comparison&lt;/strong&gt;. It&amp;rsquo;s used to check if the value of something is equal to something else. The assignment operator &lt;code&gt;=&lt;/code&gt; is used to assign a value to something. To learn more about the differences between the two, check out &lt;a href=&quot;https://realpython.com/python-operators-expressions/&quot;&gt;Operators and Expressions in Python&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;When you add an &lt;code&gt;else&lt;/code&gt; clause to an &lt;code&gt;if&lt;/code&gt; statement, you can specify two results based on whether the condition is true or false. Let&amp;rsquo;s see this in a program:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Would you like me to draw a shape? Type yes or no: &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Okay&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you tell the program to display a particular output even when the user does not say &lt;code&gt;&quot;yes&quot;&lt;/code&gt;. You use &lt;code&gt;print()&lt;/code&gt; to display some pre-defined characters on the screen.&lt;/p&gt;
&lt;p&gt;Note that the user doesn&amp;rsquo;t need to type &lt;code&gt;&quot;no&quot;&lt;/code&gt;. They can type anything else, in which case, the result will always be &lt;code&gt;&quot;Okay&quot;&lt;/code&gt;, because you&amp;rsquo;re not explicitly telling the program that the user needs to type &lt;code&gt;&quot;no&quot;&lt;/code&gt;. Not to worry, however, as that can be fixed. You can add an &lt;code&gt;elif&lt;/code&gt; clause to provide the program with several conditions and their respective outputs, as you can observe here:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Would you like me to draw a shape? Type yes or no: &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;no&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Okay&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Invalid Reply&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, this program now has more than one outcome, depending on the input it receives. Here&amp;rsquo;s how this code works:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;If you type in &lt;code&gt;&quot;yes&quot;&lt;/code&gt;,&lt;/strong&gt; then the code processes the input and draws a circle, as per your instructions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If you type in &lt;code&gt;&quot;no&quot;&lt;/code&gt;,&lt;/strong&gt; then the code prints out &lt;code&gt;&quot;Okay&quot;&lt;/code&gt; and your program is terminated.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If you type in anything else,&lt;/strong&gt; like &lt;code&gt;&quot;Hello&quot;&lt;/code&gt; or &lt;code&gt;&quot;Sandwich&quot;&lt;/code&gt;, then the code prints &lt;code&gt;&quot;Invalid Reply&quot;&lt;/code&gt; and your program is terminated.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that this program is case-sensitive, so when you&amp;rsquo;re trying it out, be sure to put the strings in upper-case or lower-case accordingly.&lt;/p&gt;
&lt;p&gt;To learn more about conditional statements, check out &lt;a href=&quot;https://realpython.com/python-conditional-statements/&quot;&gt;Conditional Statements in Python&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;final-project-the-python-turtle-race&quot;&gt;Final Project: The Python Turtle Race&lt;/h2&gt;
&lt;p&gt;So far, you&amp;rsquo;ve learned how to customize your turtle environment, program your turtle to move around the screen, and use loops and conditional statements to improve your code. Now it&amp;rsquo;s time for the most important part of your programming journey. In this section, you&amp;rsquo;ll be implementing all that you&amp;rsquo;ve learned into a single program by creating a fun game that you can play with your friends.&lt;/p&gt;
&lt;p&gt;Before you begin, here&amp;rsquo;s what you need to know about the game:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Objective:&lt;/strong&gt; The player whose turtle reaches its home first wins the game.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;How to Play:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each player rolls a dice to get a number.&lt;/li&gt;
&lt;li&gt;The player then moves their turtle by that many steps.&lt;/li&gt;
&lt;li&gt;The players alternate turns until one of them wins.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Structure:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each player had a turtle indicated by a different color. You can have more than two players, but for the sake of this tutorial, you&amp;rsquo;ll be creating a two-player game.&lt;/li&gt;
&lt;li&gt;Each turtle has a home position that it must reach.&lt;/li&gt;
&lt;li&gt;Each player uses a die to choose a value at random for their turn. In your program, the die is represented by a list of numbers from 1 to 6.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that you&amp;rsquo;ve understood the logic of the game, you can go ahead and begin creating it! First, you&amp;rsquo;ll need to set up the environment.&lt;/p&gt;
&lt;h3 id=&quot;setting-up-the-game-environment&quot;&gt;Setting Up the Game Environment&lt;/h3&gt;
&lt;p&gt;Start by importing the Python &lt;code&gt;turtle&lt;/code&gt; library. After this, import the built-in &lt;code&gt;random&lt;/code&gt; library, which you&amp;rsquo;ll use randomly select an item from a list:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;turtle&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once these libraries are successfully called into your environment, you can proceed with the rest of your program.&lt;/p&gt;
&lt;h3 id=&quot;setting-up-the-turtles-and-homes&quot;&gt;Setting Up the Turtles and Homes&lt;/h3&gt;
&lt;p&gt;You now have to create the two turtles that will represent the players. Each turtle will be a different color, corresponding to the different players. Here, player one is &lt;strong&gt;green&lt;/strong&gt; and player two is &lt;strong&gt;blue&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;turtle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Turtle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;green&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;turtle&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;penup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_two&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_two&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;blue&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_two&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;penup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_two&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;One you&amp;rsquo;ve created the turtles, you place them at their starting positions and make sure that these positions are aligned. Note that you created player two&amp;rsquo;s turtle by cloning player one&amp;rsquo;s turtle, changing its color, and placing it at a different starting point.&lt;/p&gt;
&lt;p&gt;You now need to set up homes for the turtles. These homes will act as the finishing points for each turtle. Each of the turtles&amp;rsquo; &lt;strong&gt;homes&lt;/strong&gt; will be represented by a circle. Here, you need to make sure that both homes are equidistant from the starting point:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pendown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;penup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_two&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;140&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_two&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pendown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_two&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_two&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;penup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player_two&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After drawing the respective homes, you send the turtles back to their starting positions:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/UPDATE_Turtle_Race_Setup_Blue_and_Green.16e6da3cc20d.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/UPDATE_Turtle_Race_Setup_Blue_and_Green.16e6da3cc20d.png&quot; width=&quot;721&quot; height=&quot;699&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/UPDATE_Turtle_Race_Setup_Blue_and_Green.16e6da3cc20d.png&amp;amp;w=180&amp;amp;sig=52f9cf3604700ccac80886533d1c805282740eaf 180w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/UPDATE_Turtle_Race_Setup_Blue_and_Green.16e6da3cc20d.png&amp;amp;w=360&amp;amp;sig=17033e8fe78b2435d9edd9acb88ec4bb11614d7a 360w, https://files.realpython.com/media/UPDATE_Turtle_Race_Setup_Blue_and_Green.16e6da3cc20d.png 721w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Race Setup Updated&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Awesome! The visual aspects of your game are complete. You can now create the die that you&amp;rsquo;ll be using to play the game.&lt;/p&gt;
&lt;h3 id=&quot;creating-the-die&quot;&gt;Creating the Die&lt;/h3&gt;
&lt;p&gt;You can create a virtual die for your game with a &lt;strong&gt;&lt;a href=&quot;https://realpython.com/courses/lists-tuples-python/&quot;&gt;list&lt;/a&gt;&lt;/strong&gt;, which is an ordered sequence of items. In real life, you might prepare grocery lists and to-do lists to help you stay organized. In Python, lists work in a similar way.&lt;/p&gt;
&lt;p&gt;In this case, you&amp;rsquo;ll be using a list to create your die. First, you define your list of numbers in ascending order from 1 to 6. You can define a list by giving it a name and then enclosing its items within square brackets, like this:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;die&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This list has now become your die. To roll the dice, all you have to do is program your system to randomly select a number from it. The number that is selected will be considered as the output of the die.&lt;/p&gt;
&lt;h3 id=&quot;developing-the-game&quot;&gt;Developing the Game&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s time to develop the code for the rest of the game. You&amp;rsquo;ll be using loops and conditional statements here, so you need to be careful with the indentations and spaces. To start, take a look at the steps your program will need to take to run the game:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; You&amp;rsquo;ll start by telling your program to check if either turtle has reached its home.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; If they haven&amp;rsquo;t, then you&amp;rsquo;ll tell your program to allow the players to continue trying.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; In each loop, you tell your program to roll the die by randomly picking a number from the list.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; You then tell it to move the respective turtle accordingly, with the number of steps based on the outcome of this random selection.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The program keeps repeating this process, and stops once one of the turtles reaches the goal. Here&amp;rsquo;s how the code looks:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Player One Wins!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player_two&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Player Two Wins!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;player_one_turn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Press &amp;#39;Enter&amp;#39; to roll the die &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;die_outcome&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;die&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The result of the die roll is: &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;die_outcome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The number of steps will be: &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;die_outcome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;player_one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;die_outcome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;player_two_turn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Press &amp;#39;Enter&amp;#39; to roll the die &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;die&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The result of the die roll is: &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;die_outcome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The number of steps will be: &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;die_outcome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;player_two&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;die_outcome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Your final output will look a little something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Update_-_Turtle_Race_Green_and_Blue.b1ee6be37a9f.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Update_-_Turtle_Race_Green_and_Blue.b1ee6be37a9f.gif&quot; width=&quot;480&quot; height=&quot;470&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Update_-_Turtle_Race_Green_and_Blue.b1ee6be37a9f.gif&amp;amp;w=120&amp;amp;sig=401560a0825a77ce6f1a4b5372a22bac81e83ac8 120w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Update_-_Turtle_Race_Green_and_Blue.b1ee6be37a9f.gif&amp;amp;w=240&amp;amp;sig=d9472f108ad040a7923ae5eb0362243833188693 240w, https://files.realpython.com/media/Update_-_Turtle_Race_Green_and_Blue.b1ee6be37a9f.gif 480w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Turtle Race Updated&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In summary, this is what the code is doing:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Line 1&lt;/strong&gt; sets up a &lt;code&gt;for&lt;/code&gt; loop with a range from 1 to 20.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lines 2 through 7&lt;/strong&gt; check if either player has reached their goal. If one of them has, then the program prints out the corresponding statement and breaks the loop.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Line 8&lt;/strong&gt; moves the program on to the next set of steps if neither player has won.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Line 9&lt;/strong&gt; prints out a statement asking player one to press the &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt; key to roll the die.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Line 10&lt;/strong&gt; takes a random value from the list &lt;code&gt;die&lt;/code&gt; and stores it in &lt;code&gt;dice_outcome&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Line 11&lt;/strong&gt; prints a statement prior to displaying the outcome of the dice roll.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Line 12&lt;/strong&gt; prints the dice outcome.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Line 14&lt;/strong&gt; multiplies this value by 20 to reduce the overall number of steps required to complete the game.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Line 15&lt;/strong&gt; moves player one&amp;rsquo;s turtle forward by this number of steps.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lines 16 to 22&lt;/strong&gt; repeat these steps for player two.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The entire &lt;code&gt;for&lt;/code&gt; loop is repeated until one of the player&amp;rsquo;s turtles reaches the final position.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In Python, you use the asterisk (&lt;code&gt;*&lt;/code&gt;) to indicate multiplication. This is known as an &lt;strong&gt;arithmetic operator&lt;/strong&gt;. You can also use the plus sign (&lt;code&gt;+&lt;/code&gt;) for addition, the minus sign (&lt;code&gt;-&lt;/code&gt;) for subtraction, and a slash (&lt;code&gt;/&lt;/code&gt;) for division. To learn more about arithmetic operators, check out the Arithmetic Operators section of &lt;a href=&quot;https://realpython.com/python-operators-expressions/#arithmetic-operators&quot;&gt;Operators and Expressions in Python&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Remember, you can customize the game however you want, so go ahead and play around with it! You can add more turtles, change the colors, change the speed, or even create some obstacles to challenge your players. It&amp;rsquo;s all up to you as the developer of the game!&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this tutorial, you&amp;rsquo;ve learned how to program with the Python &lt;code&gt;turtle&lt;/code&gt; library and grasped some very important programming concepts. You know how to deal with variable initialization, loops, conditional statements, indentations, lists, and operators. This is a great start for you, especially if you&amp;rsquo;re new to the Python programming language!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now you can:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Set up&lt;/strong&gt; the Python &lt;code&gt;turtle&lt;/code&gt; library&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Move&lt;/strong&gt; your turtle around&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Customize&lt;/strong&gt; your turtle and its environment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Program&lt;/strong&gt; your turtle&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use&lt;/strong&gt; basic programming concepts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create&lt;/strong&gt; a game that you can play with friends&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now you&amp;rsquo;re ready to venture into some higher-level Python programming. To progress further in your Python journey, check out &lt;a href=&quot;https://realpython.com/learning-paths/python3-introduction/&quot;&gt;Introduction to Python&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/python-beginner-tips/&quot;&gt;11 Beginner Tips for Learning Python Programming&lt;/a&gt;. Just remember to work hard and keep practicing, and you&amp;rsquo;ll find that you&amp;rsquo;re a Python expert in no time!&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>How to Work With a PDF in Python</title>
      <id>https://realpython.com/courses/pdf-python/</id>
      <link href="https://realpython.com/courses/pdf-python/"/>
      <updated>2020-02-25T14:00:00+00:00</updated>
      <summary>In this step-by-step course, you&#39;ll learn how to work with a PDF in Python. You&#39;ll see how to extract metadata from preexisting PDFs. You&#39;ll also learn how to merge, split, watermark, and rotate pages in PDFs using Python and PyPDF2.</summary>
      <content type="html">
        &lt;p&gt;The &lt;strong&gt;Portable Document Format&lt;/strong&gt; or &lt;strong&gt;PDF&lt;/strong&gt; is a file format that can be used to present and exchange documents reliably across operating systems. While the PDF was originally invented by Adobe, it is now an &lt;a href=&quot;https://www.iso.org/standard/51502.html&quot;&gt;open standard&lt;/a&gt; that is maintained by the International Organization for Standardization (ISO). You can work with a preexisting PDF in Python by using the &lt;strong&gt;&lt;code&gt;PyPDF2&lt;/code&gt;&lt;/strong&gt; package.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PyPDF2&lt;/code&gt; is a &lt;a href=&quot;https://stackoverflow.com/questions/45976946/what-is-pure-python&quot;&gt;pure-Python&lt;/a&gt; package that you can use for many different types of PDF operations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll know how to:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Extract document information from a PDF in Python&lt;/li&gt;
&lt;li&gt;Rotate pages&lt;/li&gt;
&lt;li&gt;Merge PDFs&lt;/li&gt;
&lt;li&gt;Split PDFs&lt;/li&gt;
&lt;li&gt;Add watermarks&lt;/li&gt;
&lt;li&gt;Encrypt a PDF&lt;/li&gt;
&lt;/ul&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Introduction to Python SQL Libraries</title>
      <id>https://realpython.com/python-sql-libraries/</id>
      <link href="https://realpython.com/python-sql-libraries/"/>
      <updated>2020-02-24T14:00:00+00:00</updated>
      <summary>In this step-by-step tutorial, you&#39;ll learn how to connect to different database management systems by using various Python SQL libraries. You&#39;ll interact with SQLite, MySQL, and PostgreSQL databases and perform common database queries using a Python application.</summary>
      <content type="html">
        &lt;p&gt;All software applications interact with &lt;strong&gt;data&lt;/strong&gt;, most commonly through a &lt;a href=&quot;https://en.wikipedia.org/wiki/Database#Database_management_system&quot;&gt;database management system (DBMS)&lt;/a&gt;. Some programming languages come with modules that you can use to interact with a DBMS, while others require the use of third-party packages. In this tutorial, you&amp;rsquo;ll explore the different &lt;strong&gt;Python SQL libraries&lt;/strong&gt; that you can use. You&amp;rsquo;ll develop a straightforward application to interact with SQLite, MySQL, and PostgreSQL databases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this tutorial, you&amp;rsquo;ll learn how to:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Connect&lt;/strong&gt; to different database management systems with Python SQL libraries&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interact&lt;/strong&gt; with SQLite, MySQL, and PostgreSQL databases&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Perform&lt;/strong&gt; common database queries using a Python application&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Develop&lt;/strong&gt; applications across different databases using a Python script&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To get the most out of this tutorial, you should have knowledge of basic Python, SQL, and working with database management systems. You should also be able to download and import packages in Python and know how to install and run different database servers locally or remotely.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free PDF Download:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-cheat-sheet-short/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-cheat-sheet-short&quot; data-focus=&quot;false&quot;&gt;Python 3 Cheat Sheet&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;understanding-the-database-schema&quot;&gt;Understanding the Database Schema&lt;/h2&gt;
&lt;p&gt;In this tutorial, you&amp;rsquo;ll develop a very small database for a social media application. The database will consist of four tables:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;users&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;posts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;comments&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;likes&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A high-level diagram of the database schema is shown below:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/python-sql-database-schema.3f28bf80fefe.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/python-sql-database-schema.3f28bf80fefe.png&quot; width=&quot;589&quot; height=&quot;517&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/python-sql-database-schema.3f28bf80fefe.png&amp;amp;w=147&amp;amp;sig=0997cd8127e54cbe49bec9b058656585b3cb6d99 147w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/python-sql-database-schema.3f28bf80fefe.png&amp;amp;w=294&amp;amp;sig=c8684fe62b0bc97c93df69d7188f9d21b7e2f87b 294w, https://files.realpython.com/media/python-sql-database-schema.3f28bf80fefe.png 589w&quot; sizes=&quot;75vw&quot; alt=&quot;python-sql-database-schema&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Both &lt;code&gt;users&lt;/code&gt; and &lt;code&gt;posts&lt;/code&gt; will have a &lt;a href=&quot;https://www.lifewire.com/one-to-many-relationships-1019756&quot;&gt;one-to-many relationship&lt;/a&gt; since one user can like many posts. Similarly, one user can post many comments, and one post can also have multiple comments. So, both &lt;code&gt;users&lt;/code&gt; and &lt;code&gt;posts&lt;/code&gt; will also have one-to-many relationships with the &lt;code&gt;comments&lt;/code&gt; table. This also applies to the &lt;code&gt;likes&lt;/code&gt; table, so both &lt;code&gt;users&lt;/code&gt; and &lt;code&gt;posts&lt;/code&gt; will have a one-to-many relationship with the &lt;code&gt;likes&lt;/code&gt; table.&lt;/p&gt;
&lt;h2 id=&quot;using-python-sql-libraries-to-connect-to-a-database&quot;&gt;Using Python SQL Libraries to Connect to a Database&lt;/h2&gt;
&lt;p&gt;Before you interact with any database through a Python SQL Library, you have to &lt;strong&gt;connect&lt;/strong&gt; to that database. In this section, you&amp;rsquo;ll see how to connect to &lt;a href=&quot;https://www.sqlite.org/index.html&quot;&gt;SQLite&lt;/a&gt;, &lt;a href=&quot;https://www.mysql.com/&quot;&gt;MySQL&lt;/a&gt;, and &lt;a href=&quot;https://www.postgresql.org/&quot;&gt;PostgreSQL&lt;/a&gt; databases from within a Python application.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You&amp;rsquo;ll need &lt;a href=&quot;https://dev.mysql.com/downloads/&quot;&gt;MySQL&lt;/a&gt; and &lt;a href=&quot;https://www.postgresql.org/download/&quot;&gt;PostgreSQL&lt;/a&gt; servers up and running before you execute the scripts in the MySQL and PostgreSQL database sections. For a quick intro on how to start a MySQL server, check out the MySQL section of &lt;a href=&quot;https://realpython.com/django-setup/#mysql&quot;&gt;Starting a Django Project&lt;/a&gt;. To learn how to create a database in PostgreSQL, check out the Setting Up a Database section of &lt;a href=&quot;https://realpython.com/prevent-python-sql-injection/#setting-up-a-database&quot;&gt;Preventing SQL Injection Attacks With Python&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;It&amp;rsquo;s recommended that you create three different Python files, so you have one for each of the three databases. You&amp;rsquo;ll execute the script for each database in its corresponding file.&lt;/p&gt;
&lt;h3 id=&quot;sqlite&quot;&gt;SQLite&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.sqlite.org/docs.html&quot;&gt;&lt;strong&gt;SQLite&lt;/strong&gt;&lt;/a&gt; is probably the most straightforward database to connect to with a Python application since you don&amp;rsquo;t need to install any external Python SQL modules to do so. By default, your Python installation contains a Python SQL library named &lt;a href=&quot;https://docs.python.org/2/library/sqlite3.html&quot;&gt;&lt;code&gt;sqlite3&lt;/code&gt;&lt;/a&gt; that you can use to interact with an SQLite database.&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s more, SQLite databases are &lt;strong&gt;serverless&lt;/strong&gt; and &lt;strong&gt;self-contained&lt;/strong&gt;, since they read and write data to a file. This means that, unlike with MySQL and PostgreSQL, you don&amp;rsquo;t even need to install and run an SQLite server to perform database operations!&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how you use &lt;code&gt;sqlite3&lt;/code&gt; to connect to an SQLite database in Python:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sqlite3&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sqlite3&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sqlite3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Connection to SQLite DB successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here&amp;rsquo;s how this code works:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lines 1 and 2&lt;/strong&gt; import &lt;code&gt;sqlite3&lt;/code&gt; and the module&amp;rsquo;s &lt;code&gt;Error&lt;/code&gt; class.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 4&lt;/strong&gt; defines a function &lt;code&gt;.create_connection()&lt;/code&gt; that accepts the path to the SQLite database.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 7&lt;/strong&gt; uses &lt;code&gt;.connect()&lt;/code&gt; from the &lt;code&gt;sqlite3&lt;/code&gt; module and takes the SQLite database path as a parameter. If the database exists at the specified location, then a connection to the database is established. Otherwise, a new database is created at the specified location, and a connection is established.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 8&lt;/strong&gt; prints the status of the successful database connection.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 9&lt;/strong&gt; catches any &lt;a href=&quot;https://realpython.com/python-exceptions/&quot;&gt;exception&lt;/a&gt; that might be thrown if &lt;code&gt;.connect()&lt;/code&gt; fails to establish a connection.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 10&lt;/strong&gt; displays the error message in the console.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sqlite3.connect(path)&lt;/code&gt; returns a &lt;code&gt;connection&lt;/code&gt; object, which is in turn returned by &lt;code&gt;create_connection()&lt;/code&gt;. This &lt;code&gt;connection&lt;/code&gt; object can be used to execute queries on an SQLite database. The following script creates a connection to the SQLite database:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;E:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;sm_app.sqlite&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once you execute the above script, you&amp;rsquo;ll see that a database file &lt;code&gt;sm_app.sqlite&lt;/code&gt; is created in the root directory. Note that you can change the location to match your setup.&lt;/p&gt;
&lt;h3 id=&quot;mysql&quot;&gt;MySQL&lt;/h3&gt;
&lt;p&gt;Unlike SQLite, there&amp;rsquo;s no default Python SQL module that you can use to connect to a MySQL database. Instead, you&amp;rsquo;ll need to install a &lt;strong&gt;Python SQL driver&lt;/strong&gt; for MySQL in order to interact with a MySQL database from within a Python application. One such driver is &lt;code&gt;mysql-connector-python&lt;/code&gt;. You can download this Python SQL module with &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; pip install mysql-connector-python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that MySQL is a &lt;strong&gt;server-based&lt;/strong&gt; database management system. One MySQL server can have multiple databases. Unlike SQLite, where creating a connection is tantamount to creating a database, a MySQL database has a two-step process for database creation:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Make a connection&lt;/strong&gt; to a MySQL server.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Execute a separate query&lt;/strong&gt; to create the database.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Define a function that connects to the MySQL database server and returns the connection object:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mysql.connector&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mysql.connector&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;passwd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_password&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Connection to MySQL DB successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;root&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the above script, you define a function &lt;code&gt;create_connection()&lt;/code&gt; that accepts three parameters:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;host_name&lt;/li&gt;
&lt;li&gt;user_name&lt;/li&gt;
&lt;li&gt;user_password&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;code&gt;mysql.connector&lt;/code&gt; Python SQL module contains a method &lt;code&gt;.connect()&lt;/code&gt; that you use in line 7 to connect to a MySQL database server. Once the connection is established, the &lt;code&gt;connection&lt;/code&gt; object is returned to the calling function. Finally, in line 18 you call &lt;code&gt;create_connection()&lt;/code&gt; with the host name, username, and password.&lt;/p&gt;
&lt;p&gt;So far, you&amp;rsquo;ve only established the connection. The database is not yet created. To do this, you&amp;rsquo;ll define another function &lt;code&gt;create_database()&lt;/code&gt; that accepts two parameters:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;connection&lt;/code&gt;&lt;/strong&gt; is the &lt;code&gt;connection&lt;/code&gt; object to the database server that you want to interact with.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;query&lt;/code&gt;&lt;/strong&gt; is the query that creates the database.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here&amp;rsquo;s what this function looks like:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Database created successfully&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To execute queries, you use the &lt;code&gt;cursor&lt;/code&gt; object. The &lt;code&gt;query&lt;/code&gt; to be executed is passed to &lt;code&gt;cursor.execute()&lt;/code&gt; in &lt;a href=&quot;https://realpython.com/python-strings/&quot;&gt;string&lt;/a&gt; format.&lt;/p&gt;
&lt;p&gt;Create a database named &lt;code&gt;sm_app&lt;/code&gt; for your social media app in the MySQL database server:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_database_query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;CREATE DATABASE sm_app&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;create_database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_database_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you&amp;rsquo;ve created a database &lt;code&gt;sm_app&lt;/code&gt; on the database server. However, the &lt;code&gt;connection&lt;/code&gt; object returned by the &lt;code&gt;create_connection()&lt;/code&gt; is connected to the MySQL database server. You need to connect to the &lt;code&gt;sm_app&lt;/code&gt; database. To do so, you can modify &lt;code&gt;create_connection()&lt;/code&gt; as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;passwd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;            &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db_name&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Connection to MySQL DB successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can see in line 8 that &lt;code&gt;create_connection()&lt;/code&gt; now accepts an additional parameter called &lt;code&gt;db_name&lt;/code&gt;. This parameter specifies the name of the database that you want to connect to. You can pass in the name of the database you want to connect to when you call this function:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;root&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sm_app&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The above script successfully calls &lt;code&gt;create_connection()&lt;/code&gt; and connects to the &lt;code&gt;sm_app&lt;/code&gt; database.&lt;/p&gt;
&lt;h3 id=&quot;postgresql&quot;&gt;PostgreSQL&lt;/h3&gt;
&lt;p&gt;Like MySQL, there&amp;rsquo;s no default Python SQL library that you can use to interact with a PostgreSQL database. Instead, you need to install a &lt;strong&gt;third-party Python SQL driver&lt;/strong&gt; to interact with PostgreSQL. One such Python SQL driver for PostgreSQL is &lt;code&gt;psycopg2&lt;/code&gt;. Execute the following command on your terminal to install the &lt;code&gt;psycopg2&lt;/code&gt; Python SQL module:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; pip install psycopg2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Like with the SQLite and MySQL databases, you&amp;rsquo;ll define &lt;code&gt;create_connection()&lt;/code&gt; to make a connection with your PostgreSQL database:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;psycopg2&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;psycopg2&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OperationalError&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db_password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db_host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;psycopg2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db_password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db_host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Connection to PostgreSQL DB successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OperationalError&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You use &lt;code&gt;psycopg2.connect()&lt;/code&gt; to connect to a PostgreSQL server from within your Python application.&lt;/p&gt;
&lt;p&gt;You can then use &lt;code&gt;create_connection()&lt;/code&gt; to create a connection to a PostgreSQL database. First, you&amp;rsquo;ll make a connection with the default database &lt;code&gt;postgres&lt;/code&gt; by using the following string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;postgres&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;postgres&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;abc123&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;127.0.0.1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;5432&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, you have to create the database &lt;code&gt;sm_app&lt;/code&gt; inside the default &lt;code&gt;postgres&lt;/code&gt; database. You can define a function to execute any SQL query in PostgreSQL. Below, you define &lt;code&gt;create_database()&lt;/code&gt; to create a new database in the PostgreSQL database server:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;autocommit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Query executed successfully&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OperationalError&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;create_database_query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;CREATE DATABASE sm_app&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;create_database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_database_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once you run the script above, you&amp;rsquo;ll see the &lt;code&gt;sm_app&lt;/code&gt; database in your PostgreSQL database server.&lt;/p&gt;
&lt;p&gt;Before you execute queries on the &lt;code&gt;sm_app&lt;/code&gt; database, you need to connect to it:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;sm_app&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;postgres&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;abc123&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;127.0.0.1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;5432&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once you execute the above script, a connection will be established with the &lt;code&gt;sm_app&lt;/code&gt; database located in the &lt;code&gt;postgres&lt;/code&gt; database server. Here, &lt;code&gt;127.0.0.1&lt;/code&gt; refers to the database server host IP address, and &lt;code&gt;5432&lt;/code&gt; refers to the port number of the database server.&lt;/p&gt;
&lt;h2 id=&quot;creating-tables&quot;&gt;Creating Tables&lt;/h2&gt;
&lt;p&gt;In the previous section, you saw how to connect to SQLite, MySQL, and PostgreSQL database servers using different Python SQL libraries. You created the &lt;code&gt;sm_app&lt;/code&gt; database on all three database servers. In this section, you&amp;rsquo;ll see how to &lt;strong&gt;create tables&lt;/strong&gt; inside these three databases.&lt;/p&gt;
&lt;p&gt;As discussed earlier, you&amp;rsquo;ll create four tables:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;users&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;posts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;comments&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;likes&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You&amp;rsquo;ll start with SQLite.&lt;/p&gt;
&lt;h3 id=&quot;sqlite_1&quot;&gt;SQLite&lt;/h3&gt;
&lt;p&gt;To execute queries in SQLite, use &lt;code&gt;cursor.execute()&lt;/code&gt;. In this section, you&amp;rsquo;ll define a function &lt;code&gt;execute_query()&lt;/code&gt; that uses this method. Your function will accept the &lt;code&gt;connection&lt;/code&gt; object and a query string, which you&amp;rsquo;ll pass to &lt;code&gt;cursor.execute()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.execute()&lt;/code&gt; can execute any query passed to it in the form of string. You&amp;rsquo;ll use this method to create tables in this section. In the upcoming sections, you&amp;rsquo;ll use this same method to execute update and delete queries as well.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This script should be executed in the same file where you created the connection for your SQLite database.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Here&amp;rsquo;s your function definition:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Query executed successfully&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This code tries to execute the given &lt;code&gt;query&lt;/code&gt; and prints an error message if necessary.&lt;/p&gt;
&lt;p&gt;Next, write your &lt;strong&gt;query&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_users_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;CREATE TABLE IF NOT EXISTS users (&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  id INTEGER PRIMARY KEY AUTOINCREMENT,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  name TEXT NOT NULL,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  age INTEGER,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  gender TEXT,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  nationality TEXT&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This says to create a table &lt;code&gt;users&lt;/code&gt; with the following five columns:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;age&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gender&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nationality&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finally, you&amp;rsquo;ll call &lt;code&gt;execute_query()&lt;/code&gt; to create the table. You&amp;rsquo;ll pass in the &lt;code&gt;connection&lt;/code&gt; object that you created in the previous section, along with the &lt;code&gt;create_users_table&lt;/code&gt; string that contains the create table query:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_users_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The following query is used to create the &lt;code&gt;posts&lt;/code&gt; table:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_posts_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;CREATE TABLE IF NOT EXISTS posts(&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  id INTEGER PRIMARY KEY AUTOINCREMENT, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  title TEXT NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  description TEXT NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  user_id INTEGER NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  FOREIGN KEY (user_id) REFERENCES users (id)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Since there&amp;rsquo;s a one-to-many relationship between &lt;code&gt;users&lt;/code&gt; and &lt;code&gt;posts&lt;/code&gt;, you can see a foreign key &lt;code&gt;user_id&lt;/code&gt; in the &lt;code&gt;posts&lt;/code&gt; table that references the &lt;code&gt;id&lt;/code&gt; column in the &lt;code&gt;users&lt;/code&gt; table. Execute the following script to create the &lt;code&gt;posts&lt;/code&gt; table:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_posts_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, you can create the &lt;code&gt;comments&lt;/code&gt; and &lt;code&gt;likes&lt;/code&gt; tables with the following script:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_comments_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;CREATE TABLE IF NOT EXISTS comments (&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  id INTEGER PRIMARY KEY AUTOINCREMENT, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  text TEXT NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  user_id INTEGER NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  post_id INTEGER NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  FOREIGN KEY (user_id) REFERENCES users (id) FOREIGN KEY (post_id) REFERENCES posts (id)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;create_likes_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;CREATE TABLE IF NOT EXISTS likes (&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  id INTEGER PRIMARY KEY AUTOINCREMENT, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  user_id INTEGER NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  post_id integer NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  FOREIGN KEY (user_id) REFERENCES users (id) FOREIGN KEY (post_id) REFERENCES posts (id)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_comments_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_likes_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;            
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can see that &lt;strong&gt;creating tables&lt;/strong&gt; in SQLite is very similar to using raw SQL. All you have to do is store the query in a string variable and then pass that variable to &lt;code&gt;cursor.execute()&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;mysql_1&quot;&gt;MySQL&lt;/h3&gt;
&lt;p&gt;You&amp;rsquo;ll use the &lt;code&gt;mysql-connector-python&lt;/code&gt; Python SQL module to create tables in MySQL. Just like with SQLite, you need to pass your query to &lt;code&gt;cursor.execute()&lt;/code&gt;, which is returned by calling &lt;code&gt;.cursor()&lt;/code&gt; on the &lt;code&gt;connection&lt;/code&gt; object. You can create another function &lt;code&gt;execute_query()&lt;/code&gt; that accepts the &lt;code&gt;connection&lt;/code&gt; and &lt;code&gt;query&lt;/code&gt; string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Query executed successfully&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In line 4, you pass the &lt;code&gt;query&lt;/code&gt; to &lt;code&gt;cursor.execute()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now you can create your &lt;code&gt;users&lt;/code&gt; table using this function:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_users_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;CREATE TABLE IF NOT EXISTS users (&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  id INT AUTO_INCREMENT, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  name TEXT NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  age INT, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  gender TEXT, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  nationality TEXT, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  PRIMARY KEY (id)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;) ENGINE = InnoDB&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_users_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The query for implementing the foreign key relation is slightly different in MySQL as compared to SQLite. What&amp;rsquo;s more, MySQL uses the &lt;code&gt;AUTO_INCREMENT&lt;/code&gt; keyword (compared to the SQLite &lt;code&gt;AUTOINCREMENT&lt;/code&gt; keyword) to create columns where the values are &lt;strong&gt;automatically incremented&lt;/strong&gt; when new records are inserted.&lt;/p&gt;
&lt;p&gt;The following script creates the &lt;code&gt;posts&lt;/code&gt; table, which contains a foreign key &lt;code&gt;user_id&lt;/code&gt; that references the &lt;code&gt;id&lt;/code&gt; column of the &lt;code&gt;users&lt;/code&gt; table:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_posts_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;CREATE TABLE IF NOT EXISTS posts (&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  id INT AUTO_INCREMENT, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  title TEXT NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  description TEXT NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  user_id INTEGER NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  FOREIGN KEY fk_user_id (user_id) REFERENCES users(id), &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  PRIMARY KEY (id)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;) ENGINE = InnoDB&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_posts_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Similarly, to create the &lt;code&gt;comments&lt;/code&gt; and &lt;code&gt;likes&lt;/code&gt; tables, you can pass the corresponding &lt;code&gt;CREATE&lt;/code&gt; queries to &lt;code&gt;execute_query()&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;postgresql_1&quot;&gt;PostgreSQL&lt;/h3&gt;
&lt;p&gt;Like with SQLite and MySQL databases, the &lt;code&gt;connection&lt;/code&gt; object that&amp;rsquo;s returned by &lt;code&gt;psycopg2.connect()&lt;/code&gt; contains a &lt;code&gt;cursor&lt;/code&gt; object. You can use &lt;code&gt;cursor.execute()&lt;/code&gt; to execute Python SQL queries on your PostgreSQL database.&lt;/p&gt;
&lt;p&gt;Define a function &lt;code&gt;execute_query()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;autocommit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Query executed successfully&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OperationalError&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can use this function to create tables, insert records, modify records, and delete records in your PostgreSQL database.&lt;/p&gt;
&lt;p&gt;Now create the &lt;code&gt;users&lt;/code&gt; table inside the &lt;code&gt;sm_app&lt;/code&gt; database:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_users_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;CREATE TABLE IF NOT EXISTS users (&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  id SERIAL PRIMARY KEY,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  name TEXT NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  age INTEGER,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  gender TEXT,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  nationality TEXT&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_users_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can see that the query to create the &lt;code&gt;users&lt;/code&gt; table in PostgreSQL is slightly different than SQLite and MySQL. Here, the keyword &lt;code&gt;SERIAL&lt;/code&gt; is used to create columns that increment automatically. Recall that MySQL uses the keyword &lt;code&gt;AUTO_INCREMENT&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In addition, foreign key referencing is also specified differently, as shown in the following script that creates the &lt;code&gt;posts&lt;/code&gt; table:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_posts_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;CREATE TABLE IF NOT EXISTS posts (&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  id SERIAL PRIMARY KEY, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  title TEXT NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  description TEXT NOT NULL, &lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  user_id INTEGER REFERENCES users(id)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_posts_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To create the &lt;code&gt;comments&lt;/code&gt; table, you&amp;rsquo;ll have to write a &lt;code&gt;CREATE&lt;/code&gt; query for the &lt;code&gt;comments&lt;/code&gt; table and pass it to &lt;code&gt;execute_query()&lt;/code&gt;. The process for creating the &lt;code&gt;likes&lt;/code&gt; table is the same. You only have to modify the &lt;code&gt;CREATE&lt;/code&gt; query to create the &lt;code&gt;likes&lt;/code&gt; table instead of the &lt;code&gt;comments&lt;/code&gt; table.&lt;/p&gt;
&lt;h2 id=&quot;inserting-records&quot;&gt;Inserting Records&lt;/h2&gt;
&lt;p&gt;In the previous section, you saw how to create tables in your SQLite, MySQL, and PostgreSQL databases by using different Python SQL modules. In this section, you&amp;rsquo;ll see how to &lt;strong&gt;insert records&lt;/strong&gt; into your tables.&lt;/p&gt;
&lt;h3 id=&quot;sqlite_2&quot;&gt;SQLite&lt;/h3&gt;
&lt;p&gt;To insert records into your SQLite database, you can use the same &lt;code&gt;execute_query()&lt;/code&gt; function that you used to create tables. First, you have to store your &lt;code&gt;INSERT INTO&lt;/code&gt; query in a string. Then, you can pass the &lt;code&gt;connection&lt;/code&gt; object and &lt;code&gt;query&lt;/code&gt; string to &lt;code&gt;execute_query()&lt;/code&gt;. Let&amp;rsquo;s insert five records into the &lt;code&gt;users&lt;/code&gt; table:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;INSERT INTO&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  users (name, age, gender, nationality)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;VALUES&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;James&amp;#39;, 25, &amp;#39;male&amp;#39;, &amp;#39;USA&amp;#39;),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Leila&amp;#39;, 32, &amp;#39;female&amp;#39;, &amp;#39;France&amp;#39;),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Brigitte&amp;#39;, 35, &amp;#39;female&amp;#39;, &amp;#39;England&amp;#39;),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Mike&amp;#39;, 40, &amp;#39;male&amp;#39;, &amp;#39;Denmark&amp;#39;),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Elizabeth&amp;#39;, 21, &amp;#39;female&amp;#39;, &amp;#39;Canada&amp;#39;);&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;   
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Since you set the &lt;code&gt;id&lt;/code&gt; column to auto-increment, you don&amp;rsquo;t need to specify the value of the &lt;code&gt;id&lt;/code&gt; column for these &lt;code&gt;users&lt;/code&gt;. The &lt;code&gt;users&lt;/code&gt; table will auto-populate these five records with &lt;code&gt;id&lt;/code&gt; values from &lt;code&gt;1&lt;/code&gt; to &lt;code&gt;5&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now insert six records into the &lt;code&gt;posts&lt;/code&gt; table:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_posts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;INSERT INTO&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  posts (title, description, user_id)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;VALUES&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;quot;Happy&amp;quot;, &amp;quot;I am feeling very happy today&amp;quot;, 1),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;quot;Hot Weather&amp;quot;, &amp;quot;The weather is very hot today&amp;quot;, 2),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;quot;Help&amp;quot;, &amp;quot;I need some help with my work&amp;quot;, 2),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;quot;Great News&amp;quot;, &amp;quot;I am getting married&amp;quot;, 1),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;quot;Interesting Game&amp;quot;, &amp;quot;It was a fantastic game of tennis&amp;quot;, 5),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;quot;Party&amp;quot;, &amp;quot;Anyone up for a late-night party today?&amp;quot;, 3);&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It&amp;rsquo;s important to mention that the &lt;code&gt;user_id&lt;/code&gt; column of the &lt;code&gt;posts&lt;/code&gt; table is a &lt;strong&gt;foreign key&lt;/strong&gt; that references the &lt;code&gt;id&lt;/code&gt; column of the &lt;code&gt;users&lt;/code&gt; table. This means that the &lt;code&gt;user_id&lt;/code&gt; column must contain a value that &lt;strong&gt;already exists&lt;/strong&gt; in the &lt;code&gt;id&lt;/code&gt; column of the &lt;code&gt;users&lt;/code&gt; table. If it doesn&amp;rsquo;t exist, then you&amp;rsquo;ll see an error.&lt;/p&gt;
&lt;p&gt;Similarly, the following script inserts records into the &lt;code&gt;comments&lt;/code&gt; and &lt;code&gt;likes&lt;/code&gt; tables:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_comments&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;INSERT INTO&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  comments (text, user_id, post_id)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;VALUES&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Count me in&amp;#39;, 1, 6),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;What sort of help?&amp;#39;, 5, 3),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Congrats buddy&amp;#39;, 2, 4),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;I was rooting for Nadal though&amp;#39;, 4, 5),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Help with your thesis?&amp;#39;, 2, 3),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Many congratulations&amp;#39;, 5, 4);&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;create_likes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;INSERT INTO&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  likes (user_id, post_id)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;VALUES&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (1, 6),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (2, 3),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (1, 5),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (5, 4),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (2, 4),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (4, 2),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (3, 6);&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_comments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_likes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In both cases, you store your &lt;code&gt;INSERT INTO&lt;/code&gt; query as a string and execute it with &lt;code&gt;execute_query()&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;mysql_2&quot;&gt;MySQL&lt;/h3&gt;
&lt;p&gt;There are two ways to insert records into MySQL databases from a Python application. The first approach is similar to SQLite. You can store the &lt;code&gt;INSERT INTO&lt;/code&gt; query in a string and then use &lt;code&gt;cursor.execute()&lt;/code&gt; to insert records.&lt;/p&gt;
&lt;p&gt;Earlier, you defined a wrapper function &lt;code&gt;execute_query()&lt;/code&gt; that you used to insert records. You can use this same function now to insert records into your MySQL table. The following script inserts records into the &lt;code&gt;users&lt;/code&gt; table using &lt;code&gt;execute_query()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;create_users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;INSERT INTO&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  `users` (`name`, `age`, `gender`, `nationality`)&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;VALUES&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;James&amp;#39;, 25, &amp;#39;male&amp;#39;, &amp;#39;USA&amp;#39;),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Leila&amp;#39;, 32, &amp;#39;female&amp;#39;, &amp;#39;France&amp;#39;),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Brigitte&amp;#39;, 35, &amp;#39;female&amp;#39;, &amp;#39;England&amp;#39;),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Mike&amp;#39;, 40, &amp;#39;male&amp;#39;, &amp;#39;Denmark&amp;#39;),&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  (&amp;#39;Elizabeth&amp;#39;, 21, &amp;#39;female&amp;#39;, &amp;#39;Canada&amp;#39;);&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The second approach uses &lt;code&gt;cursor.executemany()&lt;/code&gt;, which accepts two parameters:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The query&lt;/strong&gt; string containing placeholders for the records to be inserted&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &lt;a href=&quot;https://realpython.com/courses/lists-tuples-python/&quot;&gt;list&lt;/a&gt;&lt;/strong&gt; of records that you want to insert&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Look at the following example, which inserts two records into the &lt;code&gt;likes&lt;/code&gt; table:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;INSERT INTO likes ( user_id, post_id ) VALUES ( &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; )&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;executemany&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It&amp;rsquo;s up to you which approach you choose to insert records into your MySQL table. If you&amp;rsquo;re an expert in SQL, then you can use &lt;code&gt;.execute()&lt;/code&gt;. If you&amp;rsquo;re not much familiar with SQL, then it may be more straightforward for you to use &lt;code&gt;.executemany()&lt;/code&gt;. With either of the two approaches, you can successfully insert records into the &lt;code&gt;posts&lt;/code&gt;, &lt;code&gt;comments&lt;/code&gt;, and &lt;code&gt;likes&lt;/code&gt; tables.&lt;/p&gt;
&lt;h3 id=&quot;postgresql_2&quot;&gt;PostgreSQL&lt;/h3&gt;
&lt;p&gt;In the previous section, you saw two approaches for inserting records into SQLite database tables. The first uses an SQL string query, and the second uses &lt;code&gt;.executemany()&lt;/code&gt;. &lt;code&gt;psycopg2&lt;/code&gt; follows this second approach, though &lt;code&gt;.execute()&lt;/code&gt; is used to execute a placeholder-based query.&lt;/p&gt;
&lt;p&gt;You pass the SQL query with the placeholders and the list of records to &lt;code&gt;.execute()&lt;/code&gt;. Each record in the list will be a &lt;a href=&quot;https://realpython.com/python-lists-tuples/&quot;&gt;tuple&lt;/a&gt;, where tuple values correspond to the column values in the database table. Here&amp;rsquo;s how you can insert user records into the &lt;code&gt;users&lt;/code&gt; table in a PostgreSQL database:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;James&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;male&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;USA&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Leila&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;female&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;France&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Brigitte&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;female&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;England&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Mike&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;male&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Denmark&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Elizabeth&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;female&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Canada&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;user_records&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;, &amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;insert_query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;INSERT INTO users (name, age, gender, nationality) VALUES &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{user_records}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;autocommit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The script above creates a list &lt;code&gt;users&lt;/code&gt; that contains five user records in the form of tuples. Next, you create a placeholder string with five placeholder elements (&lt;code&gt;%s&lt;/code&gt;) that correspond to the five user records. The placeholder string is concatenated with the query that inserts records into the &lt;code&gt;users&lt;/code&gt; table. Finally, the query string and the user records are passed to &lt;code&gt;.execute()&lt;/code&gt;. The above script successfully inserts five records into the &lt;code&gt;users&lt;/code&gt; table.&lt;/p&gt;
&lt;p&gt;Take a look at another example of inserting records into a PostgreSQL table. The following script inserts records into the &lt;code&gt;posts&lt;/code&gt; table:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;posts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Happy&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;I am feeling very happy today&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hot Weather&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;The weather is very hot today&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Help&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;I need some help with my work&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Great News&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;I am getting married&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Interesting Game&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;It was a fantastic game of tennis&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Party&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Anyone up for a late-night party today?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;post_records&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;, &amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;insert_query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;INSERT INTO posts (title, description, user_id) VALUES &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{post_records}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;autocommit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can insert records into the &lt;code&gt;comments&lt;/code&gt; and &lt;code&gt;likes&lt;/code&gt; tables with the same approach.&lt;/p&gt;
&lt;h2 id=&quot;selecting-records&quot;&gt;Selecting Records&lt;/h2&gt;
&lt;p&gt;In this section, you&amp;rsquo;ll see how to select records from database tables using the different Python SQL modules. In particular, you&amp;rsquo;ll see how to perform &lt;code&gt;SELECT&lt;/code&gt; queries on your SQLite, MySQL, and PostgreSQL databases.&lt;/p&gt;
&lt;h3 id=&quot;sqlite_3&quot;&gt;SQLite&lt;/h3&gt;
&lt;p&gt;To select records using SQLite, you can again use &lt;code&gt;cursor.execute()&lt;/code&gt;. However, after you&amp;rsquo;ve done this, you&amp;rsquo;ll need to call &lt;code&gt;.fetchall()&lt;/code&gt;. This method returns a list of tuples where each tuple is mapped to the corresponding row in the retrieved records.&lt;/p&gt;
&lt;p&gt;To simplify the process, you can create a function &lt;code&gt;execute_read_query()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute_read_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This function accepts the &lt;code&gt;connection&lt;/code&gt; object and the &lt;code&gt;SELECT&lt;/code&gt; query and returns the selected record.&lt;/p&gt;
&lt;h4 id=&quot;select&quot;&gt;&lt;code&gt;SELECT&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Let&amp;rsquo;s now select all the records from the &lt;code&gt;users&lt;/code&gt; table:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;select_users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;SELECT * from users&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute_read_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;select_users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the above script, the &lt;code&gt;SELECT&lt;/code&gt; query selects all the users from the &lt;code&gt;users&lt;/code&gt; table. This is passed to the &lt;code&gt;execute_read_query()&lt;/code&gt;, which returns all the records from the &lt;code&gt;users&lt;/code&gt; table. The records are then traversed and printed to the console.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt; Note:&lt;/strong&gt; It&amp;rsquo;s not recommended to use &lt;code&gt;SELECT *&lt;/code&gt; on large tables since it can result in a large number of I/O operations that increase the network traffic.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The output of the above query looks like this:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(1, &amp;#39;James&amp;#39;, 25, &amp;#39;male&amp;#39;, &amp;#39;USA&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(2, &amp;#39;Leila&amp;#39;, 32, &amp;#39;female&amp;#39;, &amp;#39;France&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(3, &amp;#39;Brigitte&amp;#39;, 35, &amp;#39;female&amp;#39;, &amp;#39;England&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(4, &amp;#39;Mike&amp;#39;, 40, &amp;#39;male&amp;#39;, &amp;#39;Denmark&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(5, &amp;#39;Elizabeth&amp;#39;, 21, &amp;#39;female&amp;#39;, &amp;#39;Canada&amp;#39;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the same way, you can retrieve all the records from the &lt;code&gt;posts&lt;/code&gt; table with the below script:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;select_posts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;SELECT * FROM posts&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;posts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute_read_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;select_posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output looks like this:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(1, &amp;#39;Happy&amp;#39;, &amp;#39;I am feeling very happy today&amp;#39;, 1)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(2, &amp;#39;Hot Weather&amp;#39;, &amp;#39;The weather is very hot today&amp;#39;, 2)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(3, &amp;#39;Help&amp;#39;, &amp;#39;I need some help with my work&amp;#39;, 2)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(4, &amp;#39;Great News&amp;#39;, &amp;#39;I am getting married&amp;#39;, 1)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(5, &amp;#39;Interesting Game&amp;#39;, &amp;#39;It was a fantastic game of tennis&amp;#39;, 5)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(6, &amp;#39;Party&amp;#39;, &amp;#39;Anyone up for a late-night party today?&amp;#39;, 3)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The result shows all the records in the &lt;code&gt;posts&lt;/code&gt; table.&lt;/p&gt;
&lt;h4 id=&quot;join&quot;&gt;&lt;code&gt;JOIN&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;You can also execute complex queries involving &lt;strong&gt;&lt;code&gt;JOIN&lt;/code&gt; operations&lt;/strong&gt; to retrieve data from two related tables. For instance, the following script returns the user ids and names, along with the description of the posts that these users posted:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;select_users_posts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;SELECT&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  users.id,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  users.name,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  posts.description&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;FROM&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  posts&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  INNER JOIN users ON users.id = posts.user_id&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;users_posts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute_read_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;select_users_posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users_post&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users_posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;users_post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here&amp;rsquo;s the output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(1, &amp;#39;James&amp;#39;, &amp;#39;I am feeling very happy today&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(2, &amp;#39;Leila&amp;#39;, &amp;#39;The weather is very hot today&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(2, &amp;#39;Leila&amp;#39;, &amp;#39;I need some help with my work&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(1, &amp;#39;James&amp;#39;, &amp;#39;I am getting married&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(5, &amp;#39;Elizabeth&amp;#39;, &amp;#39;It was a fantastic game of tennis&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(3, &amp;#39;Brigitte&amp;#39;, &amp;#39;Anyone up for a late night party today?&amp;#39;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can also select data from three related tables by implementing &lt;strong&gt;multiple &lt;code&gt;JOIN&lt;/code&gt; operators&lt;/strong&gt;. The following script returns all posts, along with the comments on the posts and the names of the users who posted the comments:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;select_posts_comments_users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;SELECT&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  posts.description as post,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  text as comment,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  name&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;FROM&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  posts&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  INNER JOIN comments ON posts.id = comments.post_id&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  INNER JOIN users ON users.id = comments.user_id&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;posts_comments_users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute_read_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;select_posts_comments_users&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;posts_comments_user&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;posts_comments_users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;posts_comments_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output looks like this:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;Anyone up for a late night party today?&amp;#39;, &amp;#39;Count me in&amp;#39;, &amp;#39;James&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;I need some help with my work&amp;#39;, &amp;#39;What sort of help?&amp;#39;, &amp;#39;Elizabeth&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;I am getting married&amp;#39;, &amp;#39;Congrats buddy&amp;#39;, &amp;#39;Leila&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;It was a fantastic game of tennis&amp;#39;, &amp;#39;I was rooting for Nadal though&amp;#39;, &amp;#39;Mike&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;I need some help with my work&amp;#39;, &amp;#39;Help with your thesis?&amp;#39;, &amp;#39;Leila&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;I am getting married&amp;#39;, &amp;#39;Many congratulations&amp;#39;, &amp;#39;Elizabeth&amp;#39;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can see from the output that the column names are not being returned by &lt;code&gt;.fetchall()&lt;/code&gt;. To return column names, you can use the &lt;code&gt;.description&lt;/code&gt; attribute of the &lt;code&gt;cursor&lt;/code&gt; object. For instance, the following list returns all the column names for the above query:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select_posts_comments_users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;column_names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;column_names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output looks like this:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;[&amp;#39;post&amp;#39;, &amp;#39;comment&amp;#39;, &amp;#39;name&amp;#39;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can see the names of the columns for the given query.&lt;/p&gt;
&lt;h4 id=&quot;where&quot;&gt;&lt;code&gt;WHERE&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Now you&amp;rsquo;ll execute a &lt;code&gt;SELECT&lt;/code&gt; query that returns the post, along with the total number of likes that the post received:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;select_post_likes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;SELECT&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  description as Post,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  COUNT(likes.id) as Likes&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;FROM&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  likes,&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  posts&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;WHERE&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  posts.id = likes.post_id&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;GROUP BY&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  likes.post_id&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;post_likes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute_read_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;select_post_likes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_like&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_likes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post_like&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output is as follows:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;The weather is very hot today&amp;#39;, 1)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;I need some help with my work&amp;#39;, 1)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;I am getting married&amp;#39;, 2)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;It was a fantastic game of tennis&amp;#39;, 1)&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;Anyone up for a late night party today?&amp;#39;, 2)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By using a &lt;code&gt;WHERE&lt;/code&gt; clause, you&amp;rsquo;re able to return more specific results.&lt;/p&gt;
&lt;h3 id=&quot;mysql_3&quot;&gt;MySQL&lt;/h3&gt;
&lt;p&gt;The process of selecting records in MySQL is absolutely identical to selecting records in SQLite. You can use &lt;code&gt;cursor.execute()&lt;/code&gt; followed by &lt;code&gt;.fetchall()&lt;/code&gt;. The following script creates a wrapper function &lt;code&gt;execute_read_query()&lt;/code&gt; that you can use to select records:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute_read_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now select all the records from the &lt;code&gt;users&lt;/code&gt; table:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;select_users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;SELECT * FROM users&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute_read_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;select_users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output will be similar to what you saw with SQLite.&lt;/p&gt;
&lt;h3 id=&quot;postgresql_3&quot;&gt;PostgreSQL&lt;/h3&gt;
&lt;p&gt;The process of selecting records from a PostgreSQL table with the &lt;code&gt;psycopg2&lt;/code&gt; Python SQL module is similar to what you did with SQLite and MySQL. Again, you&amp;rsquo;ll use &lt;code&gt;cursor.execute()&lt;/code&gt; followed by &lt;code&gt;.fetchall()&lt;/code&gt; to select records from your PostgreSQL table. The following script selects all the records from the &lt;code&gt;users&lt;/code&gt; table and prints them to the console:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute_read_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OperationalError&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The error &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{e}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; occurred&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;select_users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;SELECT * FROM users&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute_read_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;select_users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Again, the output will be similar to what you&amp;rsquo;ve seen before.&lt;/p&gt;
&lt;h2 id=&quot;updating-table-records&quot;&gt;Updating Table Records&lt;/h2&gt;
&lt;p&gt;In the last section, you saw how to select records from SQLite, MySQL, and PostgreSQL databases. In this section, you&amp;rsquo;ll cover the process for &lt;strong&gt;updating records&lt;/strong&gt; using the Python SQL libraries for SQLite, PostgresSQL, and MySQL.&lt;/p&gt;
&lt;h3 id=&quot;sqlite_4&quot;&gt;SQLite&lt;/h3&gt;
&lt;p&gt;Updating records in SQLite is pretty straightforward. You can again make use of &lt;code&gt;execute_query()&lt;/code&gt;. As an example, you can update the description of the post with an &lt;code&gt;id&lt;/code&gt; of &lt;code&gt;2&lt;/code&gt;. First, &lt;code&gt;SELECT&lt;/code&gt; the description of this post:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;select_post_description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;SELECT description FROM posts WHERE id = 2&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;post_description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute_read_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;select_post_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You should see the following output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;The weather is very hot today&amp;#39;,)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The following script updates the description:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;update_post_description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;UPDATE&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  posts&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;SET&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  description = &amp;quot;The weather has become pleasant now&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;WHERE&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  id = 2&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;update_post_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, if you execute the &lt;code&gt;SELECT&lt;/code&gt; query again, you should see the following result:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(&amp;#39;The weather has become pleasant now&amp;#39;,)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output has been updated.&lt;/p&gt;
&lt;h3 id=&quot;mysql_4&quot;&gt;MySQL&lt;/h3&gt;
&lt;p&gt;The process of updating records in MySQL with &lt;code&gt;mysql-connector-python&lt;/code&gt; is also a carbon copy of the &lt;code&gt;sqlite3&lt;/code&gt; Python SQL module. You need to pass the string query to &lt;code&gt;cursor.execute()&lt;/code&gt;. For example, the following script updates the description of the post with an &lt;code&gt;id&lt;/code&gt; of &lt;code&gt;2&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;update_post_description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;UPDATE&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  posts&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;SET&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  description = &amp;quot;The weather has become pleasant now&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;WHERE&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  id = 2&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;update_post_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Again, you&amp;rsquo;ve used your wrapper function &lt;code&gt;execute_query()&lt;/code&gt; to update the post description.&lt;/p&gt;
&lt;h3 id=&quot;postgresql_4&quot;&gt;PostgreSQL&lt;/h3&gt;
&lt;p&gt;The update query for PostgreSQL is similar to what you&amp;rsquo;ve seen with SQLite and MySQL. You can use the above scripts to update records in your PostgreSQL table.&lt;/p&gt;
&lt;h2 id=&quot;deleting-table-records&quot;&gt;Deleting Table Records&lt;/h2&gt;
&lt;p&gt;In this section, you&amp;rsquo;ll see how to delete table records using the Python SQL modules for SQLite, MySQL, and PostgreSQL databases. The process of deleting records is uniform for all three databases since the &lt;strong&gt;&lt;code&gt;DELETE&lt;/code&gt;&lt;/strong&gt; query for the three databases is the same.&lt;/p&gt;
&lt;h3 id=&quot;sqlite_5&quot;&gt;SQLite&lt;/h3&gt;
&lt;p&gt;You can again use &lt;code&gt;execute_query()&lt;/code&gt; to delete records from YOUR SQLite database. All you have to do is pass the &lt;code&gt;connection&lt;/code&gt; object and the string query for the record you want to delete to &lt;code&gt;execute_query()&lt;/code&gt;. Then, &lt;code&gt;execute_query()&lt;/code&gt; will create a &lt;code&gt;cursor&lt;/code&gt; object using the &lt;code&gt;connection&lt;/code&gt; and pass the string query to &lt;code&gt;cursor.execute()&lt;/code&gt;, which will delete the records.&lt;/p&gt;
&lt;p&gt;As an example, try to delete the comment with an &lt;code&gt;id&lt;/code&gt; of &lt;code&gt;5&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;delete_comment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;DELETE FROM comments WHERE id = 5&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delete_comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, if you select all the records from the &lt;code&gt;comments&lt;/code&gt; table, you&amp;rsquo;ll see that the fifth comment has been deleted.&lt;/p&gt;
&lt;h3 id=&quot;mysql_5&quot;&gt;MySQL&lt;/h3&gt;
&lt;p&gt;The process for deletion in MySQL is also similar to SQLite, as shown in the following example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;delete_comment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;DELETE FROM comments WHERE id = 2&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;execute_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delete_comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you delete the second comment from the &lt;code&gt;sm_app&lt;/code&gt; database&amp;rsquo;s &lt;code&gt;comments&lt;/code&gt; table in your MySQL database server.&lt;/p&gt;
&lt;h3 id=&quot;postgresql_5&quot;&gt;PostgreSQL&lt;/h3&gt;
&lt;p&gt;The delete query for PostgreSQL is also similar to SQLite and MySQL. You can write a delete query string by using the &lt;code&gt;DELETE&lt;/code&gt; keyword and then passing the query and the &lt;code&gt;connection&lt;/code&gt; object to &lt;code&gt;execute_query()&lt;/code&gt;. This will delete the specified records from your PostgreSQL database.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this tutorial, you&amp;rsquo;ve learned how to use three common Python SQL libraries. &lt;code&gt;sqlite3&lt;/code&gt;, &lt;code&gt;mysql-connector-python&lt;/code&gt;, and &lt;code&gt;psycopg2&lt;/code&gt; allow you to connect a Python application to SQLite, MySQL, and PostgreSQL databases, respectively.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now you can:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Interact&lt;/strong&gt; with SQLite, MySQL, or PostgreSQL databases&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use&lt;/strong&gt; three different Python SQL modules&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Execute&lt;/strong&gt; SQL queries on various databases from within a Python application&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, this is just the tip of the iceberg! There are also Python SQL libraries for &lt;strong&gt;object-relational mapping&lt;/strong&gt;, such as SQLAlchemy and Django ORM, that automate the task of database interaction in Python. You&amp;rsquo;ll learn more about these libraries in other tutorials in our &lt;a href=&quot;https://realpython.com/tutorials/databases/&quot;&gt;Python databases&lt;/a&gt; section.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Null in Python: Understanding Python&#39;s NoneType Object</title>
      <id>https://realpython.com/null-in-python/</id>
      <link href="https://realpython.com/null-in-python/"/>
      <updated>2020-02-19T14:00:00+00:00</updated>
      <summary>In this tutorial, you&#39;ll learn about the NoneType object None, which acts as the null in Python. This object represents emptiness, and you can use it to mark default parameters and even show when you have no result. None is a tool for doing everything with nothing!</summary>
      <content type="html">
        &lt;p&gt;If you have experience with other programming languages, like &lt;a href=&quot;https://realpython.com/build-python-c-extension-module/&quot;&gt;C&lt;/a&gt; or &lt;a href=&quot;https://realpython.com/oop-in-python-vs-java/&quot;&gt;Java&lt;/a&gt;, then you&amp;rsquo;ve probably heard of the concept of &lt;strong&gt;&lt;code&gt;null&lt;/code&gt;&lt;/strong&gt;. Many languages use this to represent a pointer that doesn&amp;rsquo;t point to anything, to denote when a variable is empty, or to mark default parameters that you haven&amp;rsquo;t yet supplied. &lt;code&gt;null&lt;/code&gt; is often defined to be &lt;code&gt;0&lt;/code&gt; in those languages, but &lt;code&gt;null&lt;/code&gt; in Python is different.&lt;/p&gt;
&lt;p&gt;Python uses the keyword &lt;code&gt;None&lt;/code&gt; to define &lt;code&gt;null&lt;/code&gt; objects and variables. While &lt;code&gt;None&lt;/code&gt; does serve some of the same purposes as &lt;code&gt;null&lt;/code&gt; in other languages, it&amp;rsquo;s another beast entirely. As the &lt;code&gt;null&lt;/code&gt; in Python, &lt;code&gt;None&lt;/code&gt; is not defined to be &lt;code&gt;0&lt;/code&gt; or any other value. In Python, &lt;code&gt;None&lt;/code&gt; is an object and a first-class citizen!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this tutorial, you&amp;rsquo;ll learn:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What &lt;strong&gt;&lt;code&gt;None&lt;/code&gt;&lt;/strong&gt; is and how to test for it&lt;/li&gt;
&lt;li&gt;When and why to use &lt;code&gt;None&lt;/code&gt; as a &lt;strong&gt;default parameter&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;What &lt;code&gt;None&lt;/code&gt; and &lt;code&gt;NoneType&lt;/code&gt; mean in your &lt;a href=&quot;https://realpython.com/python-traceback/&quot; title=&quot;Understanding the Python Traceback&quot;&gt;&lt;strong&gt;traceback&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;How to use &lt;code&gt;None&lt;/code&gt; in &lt;strong&gt;type checking&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;How &lt;strong&gt;&lt;code&gt;null&lt;/code&gt; in Python&lt;/strong&gt; works under the hood&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-cheat-sheet-shortened&quot; data-focus=&quot;false&quot;&gt;Click here to get a Python Cheat Sheet&lt;/a&gt; and learn the basics of Python 3, like working with data types, dictionaries, lists, and Python functions.&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;understanding-null-in-python&quot;&gt;Understanding Null in Python&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;None&lt;/code&gt; is the value a function returns when there is no &lt;code&gt;return&lt;/code&gt; statement in the function:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;has_no_return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_no_return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_no_return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you call &lt;code&gt;has_no_return()&lt;/code&gt;, there&amp;rsquo;s no output for you to see. When you print a call to it, however, you&amp;rsquo;ll see the hidden &lt;code&gt;None&lt;/code&gt; it returns.&lt;/p&gt;
&lt;p&gt;In fact, &lt;code&gt;None&lt;/code&gt; so frequently appears as a return value that the Python &lt;a href=&quot;https://realpython.com/interacting-with-python/&quot;&gt;REPL&lt;/a&gt; won&amp;rsquo;t print &lt;code&gt;None&lt;/code&gt; unless you explicitly tell it to:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;None&lt;/code&gt; by itself has no output, but printing it displays &lt;code&gt;None&lt;/code&gt; to the console.&lt;/p&gt;
&lt;p&gt;Interestingly, &lt;code&gt;print()&lt;/code&gt; itself has no return value. If you try to print a call to &lt;code&gt;print()&lt;/code&gt;, then you&amp;rsquo;ll get &lt;code&gt;None&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Hello, World!&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It may look strange, but &lt;code&gt;print(print(&quot;...&quot;))&lt;/code&gt; shows you the &lt;code&gt;None&lt;/code&gt; that the inner &lt;code&gt;print()&lt;/code&gt; returns.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;None&lt;/code&gt; also often used as a signal for &lt;strong&gt;missing or default parameters&lt;/strong&gt;. For instance, &lt;code&gt;None&lt;/code&gt; appears twice in the docs for &lt;a href=&quot;https://docs.python.org/3/library/stdtypes.html#list.sort&quot; title=&quot;list.sort&quot;&gt;&lt;code&gt;list.sort&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Help on method_descriptor:&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;sort(...)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    L.sort(key=None, reverse=False) -&amp;gt; None -- stable sort *IN PLACE*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, &lt;code&gt;None&lt;/code&gt; is the default value for the &lt;code&gt;key&lt;/code&gt; parameter as well as the &lt;a href=&quot;https://realpython.com/courses/python-type-checking/&quot;&gt;type hint&lt;/a&gt; for the return value. The exact output of &lt;code&gt;help&lt;/code&gt; can vary from platform to platform. You may get different output when you run this command in your interpreter, but it will be similar.&lt;/p&gt;
&lt;h2 id=&quot;using-pythons-null-object-none&quot;&gt;Using Python&amp;rsquo;s Null Object &lt;code&gt;None&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Often, you&amp;rsquo;ll use &lt;code&gt;None&lt;/code&gt; as part of a comparison. One example is when you need to check and see if some result or parameter is &lt;code&gt;None&lt;/code&gt;. Take the result you get from &lt;a href=&quot;https://docs.python.org/3/library/re.html#re.match&quot; title=&quot;re.match&quot;&gt;&lt;code&gt;re.match&lt;/code&gt;&lt;/a&gt;. Did your regular expression match a given string? You&amp;rsquo;ll see one of two results:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Return a &lt;code&gt;Match&lt;/code&gt; object:&lt;/strong&gt; Your regular expression found a match.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Return a &lt;code&gt;None&lt;/code&gt; object:&lt;/strong&gt; Your regular expression did not find a match.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the code block below, you&amp;rsquo;re testing if the pattern &lt;code&gt;&quot;Goodbye&quot;&lt;/code&gt; matches a &lt;a href=&quot;https://realpython.com/python-strings/&quot;&gt;string&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;re&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Goodbye&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;It doesn&amp;#39;t match.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;It doesn&amp;#39;t match.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you use &lt;code&gt;is None&lt;/code&gt; to test if the pattern matches the string &lt;code&gt;&quot;Hello, World!&quot;&lt;/code&gt;. This code block demonstrates an important rule to keep in mind when you&amp;rsquo;re checking for &lt;code&gt;None&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Do&lt;/strong&gt; use the identity operators &lt;code&gt;is&lt;/code&gt; and &lt;code&gt;is not&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do not&lt;/strong&gt; use the equality operators &lt;code&gt;==&lt;/code&gt; and &lt;code&gt;!=&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The equality operators can be fooled when you&amp;rsquo;re comparing user-defined objects that &lt;strong&gt;override&lt;/strong&gt; them:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BrokenComparison&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fm&quot;&gt;__eq__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BrokenComparison&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Equality operator&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Identity operator&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, the equality operator &lt;code&gt;==&lt;/code&gt; returns the wrong answer. The identity operator &lt;code&gt;is&lt;/code&gt;, on the other hand, can&amp;rsquo;t be fooled because you can&amp;rsquo;t override it.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For more info on how to compare with &lt;code&gt;None&lt;/code&gt;, check out &lt;a href=&quot;https://realpython.com/lessons/dos-and-donts-python-programming-recommendations/&quot;&gt;Do&amp;rsquo;s and Dont&amp;rsquo;s: Python Programming Recommendations&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;None&lt;/code&gt; is &lt;a href=&quot;https://realpython.com/lessons/if-statements/&quot;&gt;falsy&lt;/a&gt;, which means &lt;code&gt;not None&lt;/code&gt; is &lt;code&gt;True&lt;/code&gt;. If all you want to know is whether a result is falsy, then a test like the following is sufficient:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;some_result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;some_result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Got a result!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;No result.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;No result.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output doesn&amp;rsquo;t show you that &lt;code&gt;some_result&lt;/code&gt; is exactly &lt;code&gt;None&lt;/code&gt;, only that it&amp;rsquo;s falsy. If you must know whether or not you have a &lt;code&gt;None&lt;/code&gt; object, then use &lt;code&gt;is&lt;/code&gt; and &lt;code&gt;is not&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The following objects are all falsy as well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Empty &lt;a href=&quot;https://realpython.com/courses/lists-tuples-python/&quot;&gt;lists&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Empty &lt;a href=&quot;https://realpython.com/courses/dictionaries-python/&quot;&gt;dictionaries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Empty &lt;a href=&quot;https://realpython.com/python-sets/&quot;&gt;sets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Empty &lt;a href=&quot;https://realpython.com/courses/python-strings/&quot;&gt;strings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;False&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more on comparisons, truthy, and falsy values, check out &lt;a href=&quot;https://realpython.com/python-or-operator/&quot;&gt;How to Use the Python &lt;code&gt;or&lt;/code&gt; Operator&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;declaring-null-variables-in-python&quot;&gt;Declaring Null Variables in Python&lt;/h2&gt;
&lt;p&gt;In some languages, variables come to life from a &lt;strong&gt;declaration&lt;/strong&gt;. They don&amp;rsquo;t have to have an initial value assigned to them. In those languages, the initial default value for some types of variables might be &lt;code&gt;null&lt;/code&gt;. In Python, however, variables come to life from &lt;strong&gt;assignment statements&lt;/strong&gt;. Take a look at the following code block:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;NameError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;name &amp;#39;bar&amp;#39; is not defined&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you can see that a variable with the value &lt;code&gt;None&lt;/code&gt; is different from an undefined variable. All variables in Python come into existence by assignment. A variable will only start life as &lt;code&gt;null&lt;/code&gt; in Python if you assign &lt;code&gt;None&lt;/code&gt; to it.&lt;/p&gt;
&lt;h2 id=&quot;using-none-as-a-default-parameter&quot;&gt;Using &lt;code&gt;None&lt;/code&gt; as a Default Parameter&lt;/h2&gt;
&lt;p&gt;Very often, you&amp;rsquo;ll use &lt;code&gt;None&lt;/code&gt; as the &lt;strong&gt;default value&lt;/strong&gt; for an optional parameter. There&amp;rsquo;s a very good reason for using &lt;code&gt;None&lt;/code&gt; here rather than a mutable type such as a list. Imagine a function like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bad_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;bad_function()&lt;/code&gt; contains a nasty surprise. It works fine when you call it with an existing list:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bad_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;d&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;, &amp;#39;d&amp;#39;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you add `&amp;rsquo;d&amp;rdquo; to the end of the list with no problems.&lt;/p&gt;
&lt;p&gt;But if you call this function a couple times with no &lt;code&gt;starter_list&lt;/code&gt; parameter, then you start to see incorrect behavior:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bad_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bad_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bad_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The default value for &lt;code&gt;starter_list&lt;/code&gt; evaluates only once at the time the function is defined, so the code reuses it every time you don&amp;rsquo;t pass an existing list.&lt;/p&gt;
&lt;p&gt;The right way to build this function is to use &lt;code&gt;None&lt;/code&gt; as the default value, then test for it and instantiate a new list as needed:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;good_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;good_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;e&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;, &amp;#39;d&amp;#39;, &amp;#39;e&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;good_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;good_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;[&amp;#39;b&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;good_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;[&amp;#39;c&amp;#39;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;good_function()&lt;/code&gt; behaves as you want by making a new list with each call where you don&amp;rsquo;t pass an existing list. It works because your code will execute lines 2 and 3 every time it calls the function with the default parameter.&lt;/p&gt;
&lt;h2 id=&quot;using-none-as-a-null-value-in-python&quot;&gt;Using &lt;code&gt;None&lt;/code&gt; as a Null Value in Python&lt;/h2&gt;
&lt;p&gt;What do you do when &lt;code&gt;None&lt;/code&gt; is a valid input object? For instance, what if &lt;code&gt;good_function()&lt;/code&gt; could either add an element to the list or not, and &lt;code&gt;None&lt;/code&gt; was a valid element to add? In this case, you can define a class specifically for use as a default, while being distinct from &lt;code&gt;None&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DontAppend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;good_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_elem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DontAppend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new_elem&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DontAppend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;good_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;, &amp;#39;d&amp;#39;, &amp;#39;e&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;good_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;, &amp;#39;d&amp;#39;, &amp;#39;e&amp;#39;, None]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, the class &lt;code&gt;DontAppend&lt;/code&gt; serves as the signal not to append, so you don&amp;rsquo;t need &lt;code&gt;None&lt;/code&gt; for that. That frees you to add &lt;code&gt;None&lt;/code&gt; when you want.&lt;/p&gt;
&lt;p&gt;You can use this technique when &lt;code&gt;None&lt;/code&gt; is a possibility for return values, too. For instance, &lt;a href=&quot;https://realpython.com/python-dicts/#dgetltkeygt-ltdefaultgt&quot;&gt;&lt;code&gt;dict.get&lt;/code&gt;&lt;/a&gt; returns &lt;code&gt;None&lt;/code&gt; by default if a key is not found in the dictionary. If &lt;code&gt;None&lt;/code&gt; was a valid value in your dictionary, then you could call &lt;code&gt;dict.get&lt;/code&gt; like this:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KeyNotFound&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_dict&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KeyNotFound&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KeyNotFound&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{key}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{value}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;a-&amp;gt;3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b-&amp;gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here you&amp;rsquo;ve defined a custom class &lt;code&gt;KeyNotFound&lt;/code&gt;. Now, instead of returning &lt;code&gt;None&lt;/code&gt; when a key isn&amp;rsquo;t in the dictionary, you can return &lt;code&gt;KeyNotFound&lt;/code&gt;. That frees you to return &lt;code&gt;None&lt;/code&gt; when that&amp;rsquo;s the actual value in the dictionary.&lt;/p&gt;
&lt;h2 id=&quot;deciphering-none-in-tracebacks&quot;&gt;Deciphering &lt;code&gt;None&lt;/code&gt; in Tracebacks&lt;/h2&gt;
&lt;p&gt;When &lt;code&gt;NoneType&lt;/code&gt; appears in your &lt;a href=&quot;https://realpython.com/python-traceback/&quot;&gt;traceback&lt;/a&gt;, it means that something you didn&amp;rsquo;t expect to be &lt;code&gt;None&lt;/code&gt; actually was &lt;code&gt;None&lt;/code&gt;, and you tried to use it in a way that you can&amp;rsquo;t use &lt;code&gt;None&lt;/code&gt;.  Almost always, it&amp;rsquo;s because you&amp;rsquo;re trying to call a method on it.&lt;/p&gt;
&lt;p&gt;For instance, you called &lt;code&gt;append()&lt;/code&gt; on &lt;code&gt;my_list&lt;/code&gt; many times above, but if &lt;code&gt;my_list&lt;/code&gt; somehow became anything other than a list, then &lt;code&gt;append()&lt;/code&gt; would fail:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;f&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;, &amp;#39;d&amp;#39;, &amp;#39;e&amp;#39;, None, &amp;#39;f&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;g&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;AttributeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;#39;NoneType&amp;#39; object has no attribute &amp;#39;append&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, your code raises the very common &lt;code&gt;AttributeError&lt;/code&gt; because the underlying object, &lt;code&gt;my_list&lt;/code&gt;, is not a list anymore. You&amp;rsquo;ve set it to &lt;code&gt;None&lt;/code&gt;, which doesn&amp;rsquo;t know how to &lt;code&gt;append()&lt;/code&gt;, and so the code throws an exception.&lt;/p&gt;
&lt;p&gt;When you see a &lt;a href=&quot;https://realpython.com/python-traceback/&quot;&gt;traceback&lt;/a&gt; like this in your code, look for the attribute that raised the error first. Here, it&amp;rsquo;s &lt;code&gt;append()&lt;/code&gt;. From there, you&amp;rsquo;ll see the object you tried to call it on. In this case, it&amp;rsquo;s &lt;code&gt;my_list&lt;/code&gt;, as you can tell from the code just above the traceback. Finally, figure out how that object got to be &lt;code&gt;None&lt;/code&gt; and take the necessary steps to fix your code.&lt;/p&gt;
&lt;h2 id=&quot;checking-for-null-in-python&quot;&gt;Checking for Null in Python&lt;/h2&gt;
&lt;p&gt;There are two &lt;a href=&quot;https://realpython.com/python-type-checking/&quot;&gt;type checking&lt;/a&gt; cases where you&amp;rsquo;ll care about &lt;code&gt;null&lt;/code&gt; in Python. The first case is when you&amp;rsquo;re &lt;a href=&quot;https://realpython.com/python-type-checking/#functions-without-return-values&quot;&gt;returning &lt;code&gt;None&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns_None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This case is similar to when you have no &lt;code&gt;return&lt;/code&gt; statement at all, which returns &lt;code&gt;None&lt;/code&gt; by default.&lt;/p&gt;
&lt;p&gt;The second case is a bit more challenging. It&amp;rsquo;s where you&amp;rsquo;re taking or returning a value that might be &lt;code&gt;None&lt;/code&gt;, but also might be some other (single) type. This case is like what you did with &lt;code&gt;re.match&lt;/code&gt; above, which returned either a &lt;code&gt;Match&lt;/code&gt; object or &lt;code&gt;None&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;The process is similar for parameters:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Optional&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;good_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;starter_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You modify &lt;code&gt;good_function()&lt;/code&gt; from above and import &lt;code&gt;Optional&lt;/code&gt; from &lt;code&gt;typing&lt;/code&gt; to return an &lt;code&gt;Optional[Match]&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;taking-a-look-under-the-hood&quot;&gt;Taking a Look Under the Hood&lt;/h2&gt;
&lt;p&gt;In many other languages, &lt;code&gt;null&lt;/code&gt; is just a synonym for &lt;code&gt;0&lt;/code&gt;, but &lt;code&gt;null&lt;/code&gt; in Python is a full-blown &lt;strong&gt;object&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;NoneType&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This line shows that &lt;code&gt;None&lt;/code&gt; is an object, and its type is &lt;code&gt;NoneType&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;None&lt;/code&gt; itself is built into the language as the &lt;code&gt;null&lt;/code&gt; in Python:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__builtins__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;ArithmeticError&amp;#39;, ..., &amp;#39;None&amp;#39;, ..., &amp;#39;zip&amp;#39;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you can see &lt;code&gt;None&lt;/code&gt; in the list of &lt;code&gt;__builtins__&lt;/code&gt; which is the dictionary the interpreter keeps for the &lt;a href=&quot;https://docs.python.org/3/library/builtins.html&quot;&gt;&lt;code&gt;builtins&lt;/code&gt;&lt;/a&gt; module.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;None&lt;/code&gt; is a keyword, just like &lt;code&gt;True&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt;. But because of this, you can&amp;rsquo;t reach &lt;code&gt;None&lt;/code&gt; directly from &lt;code&gt;__builtins__&lt;/code&gt; as you could, for instance, &lt;code&gt;ArithmeticError&lt;/code&gt;. However, you can get it with a &lt;a href=&quot;https://docs.python.org/3/library/functions.html#getattr&quot;&gt;&lt;code&gt;getattr()&lt;/code&gt;&lt;/a&gt; trick:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__builtins__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ArithmeticError&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;ArithmeticError&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__builtins__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;__builtins__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
                    &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;invalid syntax&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;getattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__builtins__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;None&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you use &lt;code&gt;getattr()&lt;/code&gt;, you can fetch the actual &lt;code&gt;None&lt;/code&gt; from &lt;code&gt;__builtins__&lt;/code&gt;, which you can&amp;rsquo;t do by simply asking for it with &lt;code&gt;__builtins__.None&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Even though Python prints the word &lt;code&gt;NoneType&lt;/code&gt; in many error messages, &lt;code&gt;NoneType&lt;/code&gt; is not an identifier in Python. It&amp;rsquo;s not in &lt;code&gt;builtins&lt;/code&gt;. You can only reach it with &lt;code&gt;type(None)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;None&lt;/code&gt; is a &lt;strong&gt;singleton&lt;/strong&gt;.  That is, the &lt;code&gt;NoneType&lt;/code&gt; class only ever gives you the same single instance of &lt;code&gt;None&lt;/code&gt;. There&amp;rsquo;s only one &lt;code&gt;None&lt;/code&gt; in your Python program:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_None&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)()&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Create a new instance&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_None&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Even though you try to create a new instance, you still get the existing &lt;code&gt;None&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can prove that &lt;code&gt;None&lt;/code&gt; and &lt;code&gt;my_None&lt;/code&gt; are the same object by using &lt;a href=&quot;https://docs.python.org/3.8/library/functions.html#id&quot; title=&quot;id&quot;&gt;&lt;code&gt;id()&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4465912088&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4465912088&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, the fact that &lt;code&gt;id&lt;/code&gt; outputs the same integer value for both &lt;code&gt;None&lt;/code&gt; and &lt;code&gt;my_None&lt;/code&gt; means they are, in fact, the same object.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The actual value produced by &lt;code&gt;id&lt;/code&gt; will vary across systems, and even between program executions. Under &lt;a href=&quot;https://realpython.com/cpython-source-code-guide/&quot;&gt;CPython&lt;/a&gt;, the most popular Python runtime, &lt;code&gt;id()&lt;/code&gt; does its job by reporting the memory address of an object. Two objects that live at the same memory address are the same object.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;If you try to assign to &lt;code&gt;None&lt;/code&gt;, then you&amp;rsquo;ll get a &lt;a href=&quot;https://realpython.com/invalid-syntax-python/&quot;&gt;&lt;code&gt;SyntaxError&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;can&amp;#39;t assign to keyword&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;AttributeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;#39;NoneType&amp;#39; object has no attribute &amp;#39;age&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;setattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;age&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;AttributeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;#39;NoneType&amp;#39; object has no attribute &amp;#39;age&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;setattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;age&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;can&amp;#39;t set attributes of built-in/extension type &amp;#39;NoneType&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;All the examples above show that you can&amp;rsquo;t modify &lt;code&gt;None&lt;/code&gt; or &lt;code&gt;NoneType&lt;/code&gt;. They are true constants.&lt;/p&gt;
&lt;p&gt;You can&amp;rsquo;t subclass &lt;code&gt;NoneType&lt;/code&gt;, either:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyNoneType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;type &amp;#39;NoneType&amp;#39; is not an acceptable base type&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This traceback shows that the interpreter won&amp;rsquo;t let you make a new class that inherits from &lt;code&gt;type(None)&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;None&lt;/code&gt; is a powerful tool in the Python toolbox. Like &lt;code&gt;True&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt;, &lt;code&gt;None&lt;/code&gt; is an immutable keyword. As the &lt;code&gt;null&lt;/code&gt; in Python, you use it to mark missing values and results, and even default parameters where it&amp;rsquo;s a much better choice than mutable types.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now you can:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Test for &lt;code&gt;None&lt;/code&gt; with &lt;code&gt;is&lt;/code&gt; and &lt;code&gt;is Not&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Choose when &lt;code&gt;None&lt;/code&gt; is a valid value in your code&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;None&lt;/code&gt; and its alternatives as default parameters&lt;/li&gt;
&lt;li&gt;Decipher &lt;code&gt;None&lt;/code&gt; and &lt;code&gt;NoneType&lt;/code&gt; in your tracebacks&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;None&lt;/code&gt; and &lt;code&gt;Optional&lt;/code&gt; in type hints&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How do you use the &lt;code&gt;null&lt;/code&gt; in Python? Leave a comment down in the comments section below!&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Finding the Perfect Python Code Editor</title>
      <id>https://realpython.com/courses/finding-perfect-python-code-editor/</id>
      <link href="https://realpython.com/courses/finding-perfect-python-code-editor/"/>
      <updated>2020-02-18T14:00:00+00:00</updated>
      <summary>Find your perfect Python development setup with this review of Python IDEs and code editors. Writing Python using IDLE or the Python REPL is great for simple things, but not ideal for larger programming projects. With this course you&#39;ll get an overview of the most common Python coding environments to help you make an informed decision.</summary>
      <content type="html">
        &lt;p&gt;Find your perfect Python development setup with this review of &lt;strong&gt;Python IDEs&lt;/strong&gt; and &lt;strong&gt;code editors&lt;/strong&gt;. Writing Python using IDLE or the Python REPL is great for simple things, but not ideal for larger programming projects. With this course you&amp;rsquo;ll get an overview of the most common Python coding environments to help you make an informed decision.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll know how to:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Choose the Python editing environment that&amp;rsquo;s right for you&lt;/li&gt;
&lt;li&gt;Perform common tasks like creating, running, and debugging code&lt;/li&gt;
&lt;li&gt;Dig deeper into optimizing your favorite editing setup&lt;/li&gt;
&lt;/ul&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>A Guide to the Newer Python String Format Techniques</title>
      <id>https://realpython.com/python-formatted-output/</id>
      <link href="https://realpython.com/python-formatted-output/"/>
      <updated>2020-02-17T14:00:00+00:00</updated>
      <summary>In the last tutorial in this series, you learned how to format string data using the string modulo operator.  In this tutorial, you&#39;ll see two more items to add to your Python string formatting toolkit. You&#39;ll learn about Python&#39;s string format method and the formatted string literal, or f-string.</summary>
      <content type="html">
        &lt;p&gt;In the &lt;a href=&quot;https://realpython.com/python-input-output/#the-string-modulo-operator&quot;&gt;previous tutorial&lt;/a&gt; in this introductory series, you learned how to format string data using the &lt;strong&gt;string modulo operator&lt;/strong&gt;. The string modulo operator is useful, and it&amp;rsquo;s good for you to be familiar with it because you&amp;rsquo;re likely to encounter it in older Python code. However, there are two newer ways that you can use Python to format strings that are arguably more preferable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this tutorial, you&amp;rsquo;ll learn about:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;strong&gt;string &lt;code&gt;.format()&lt;/code&gt; method&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;formatted string literal&lt;/strong&gt;, or &lt;strong&gt;f-string&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You&amp;rsquo;ll learn about these formatting techniques in detail and add them to your Python string formatting toolkit. Note that there&amp;rsquo;s a standard module called &lt;code&gt;string&lt;/code&gt; containing a class called &lt;a href=&quot;https://docs.python.org/3.4/library/string.html#template-strings&quot;&gt;&lt;code&gt;Template&lt;/code&gt;&lt;/a&gt;, which provides some string formatting through interpolation. The string modulo operator provides more or less the same functionality, so you won&amp;rsquo;t cover &lt;code&gt;string.Template&lt;/code&gt; here.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-tricks-sample&quot; data-focus=&quot;false&quot;&gt;Click here to get access to a chapter from Python Tricks: The Book&lt;/a&gt; that shows you Python&#39;s best practices with simple examples you can apply instantly to write more beautiful + Pythonic code.&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-python-string-format-method&quot;&gt;The Python String &lt;code&gt;.format()&lt;/code&gt; Method&lt;/h2&gt;
&lt;p&gt;The Python string &lt;code&gt;.format()&lt;/code&gt; method was introduced in version 2.6. It&amp;rsquo;s similar in many ways to the string modulo operator, but &lt;code&gt;.format()&lt;/code&gt; goes well beyond in versatility. The general form of a Python &lt;code&gt;.format()&lt;/code&gt; call is shown below:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;positional_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keyword_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that this is a method, not an operator. You call the method on &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;, which is a string containing &lt;strong&gt;replacement fields&lt;/strong&gt;. The &lt;code&gt;&amp;lt;positional_arguments&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;keyword_arguments&amp;gt;&lt;/code&gt; to the method specify values that are inserted into &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; in place of the replacement fields. The resulting formatted string is the method&amp;rsquo;s return value.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; string, replacement fields are enclosed in curly braces (&lt;code&gt;{}&lt;/code&gt;). Anything not contained in curly braces is literal text that&amp;rsquo;s copied directly from the template to the output. If you need to include a literal curly bracket character, like &lt;code&gt;{&lt;/code&gt; or &lt;code&gt;}&lt;/code&gt;, in the template string, then you can escape this character by doubling it:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{{ &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; }}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;{ foo }&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now the curly braces are included in your output.&lt;/p&gt;
&lt;h2 id=&quot;the-string-format-method-arguments&quot;&gt;The String &lt;code&gt;.format()&lt;/code&gt; Method: Arguments&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start with a quick example to get you acquainted before you dive into more detail on how to use this method in Python to format strings. For review, here&amp;rsquo;s the first example from the previous tutorial on the &lt;a href=&quot;https://realpython.com/python-input-output/#the-string-modulo-operator&quot;&gt;string modulo operator&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; cost $&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%.2f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bananas&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.74&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6 bananas cost $1.74&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you used the string modulo operator in Python to format the string. Now, you can use Python&amp;rsquo;s string &lt;code&gt;.format()&lt;/code&gt; method to obtain the same result, like this:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; cost $&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{2}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bananas&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.74&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6 bananas cost $1.74&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this example, &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; is the string &lt;code&gt;&#39;{0} {1} cost ${2}&#39;&lt;/code&gt;. The replacement fields are &lt;code&gt;{0}&lt;/code&gt;, &lt;code&gt;{1}&lt;/code&gt;, and &lt;code&gt;{2}&lt;/code&gt;, which contain numbers that correspond to the zero-based positional arguments &lt;code&gt;6&lt;/code&gt;, &lt;code&gt;&#39;bananas&#39;&lt;/code&gt;, and &lt;code&gt;1.74&lt;/code&gt;. Each positional argument is inserted into the template in place of its corresponding replacement field:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.e6b8525755da.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/t.e6b8525755da.png&quot; width=&quot;1623&quot; height=&quot;684&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/t.e6b8525755da.png&amp;amp;w=405&amp;amp;sig=8e0322e3d047bcfa7e5bfe78be855925e3b2c3df 405w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/t.e6b8525755da.png&amp;amp;w=811&amp;amp;sig=63cf68d8ee016bab2f7e712a04a255a54cccb3e1 811w, https://files.realpython.com/media/t.e6b8525755da.png 1623w&quot; sizes=&quot;75vw&quot; alt=&quot;Python string format, positional parameters&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Using The String .format() Method in Python to Format a String With Positional Arguments&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;The next example uses &lt;a href=&quot;https://realpython.com/python-kwargs-and-args/&quot;&gt;keyword arguments&lt;/a&gt; instead of positional parameters to produce the same result:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{quantity}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{item}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; cost $&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{price}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;quantity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bananas&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.74&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6 bananas cost $1.74&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this case, the replacement fields are &lt;code&gt;{quantity}&lt;/code&gt;, &lt;code&gt;{item}&lt;/code&gt;, and &lt;code&gt;{price}&lt;/code&gt;. These fields specify keywords that correspond to the keyword arguments &lt;code&gt;quantity=6&lt;/code&gt;, &lt;code&gt;item=&#39;bananas&#39;&lt;/code&gt;, and &lt;code&gt;price=1.74&lt;/code&gt;. Each keyword value is inserted into the template in place of its corresponding replacement field:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.53be85450e90.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/t.53be85450e90.png&quot; width=&quot;1584&quot; height=&quot;468&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/t.53be85450e90.png&amp;amp;w=396&amp;amp;sig=04e8e85bf08f258827f7bd1c953a34c1bf27f9e8 396w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/t.53be85450e90.png&amp;amp;w=792&amp;amp;sig=120118c1eff1efbe3d852ac4ae0a0dc4ad82172f 792w, https://files.realpython.com/media/t.53be85450e90.png 1584w&quot; sizes=&quot;75vw&quot; alt=&quot;Python string format and keyword parameters&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Using The String .format() Method in Python to Format a String With Keyword Arguments&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;You&amp;rsquo;ll learn more about positional and keywords arguments there in the next tutorial in this introductory series, which explores functions and argument passing. For now, the two sections that follow will show you how these are used with the Python &lt;code&gt;.format()&lt;/code&gt; method.&lt;/p&gt;
&lt;h3 id=&quot;positional-arguments&quot;&gt;Positional Arguments&lt;/h3&gt;
&lt;p&gt;Positional arguments are inserted into the template in place of &lt;strong&gt;numbered replacement fields&lt;/strong&gt;. Like &lt;a href=&quot;https://realpython.com/courses/lists-tuples-python/&quot;&gt;list&lt;/a&gt; indexing, the numbering of replacement fields is zero-based. The first positional argument is numbered &lt;code&gt;0&lt;/code&gt;, the second is numbered &lt;code&gt;1&lt;/code&gt;, and so on:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{2}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo/bar/baz&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that replacement fields don&amp;rsquo;t have to appear in the template in numerical order. They can be specified in any order, and they can appear more than once:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{2}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{2}{2}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;baz.bar.foo/foofoo.barbar.bazbaz&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you specify a replacement field number that&amp;rsquo;s out of range, you&amp;rsquo;ll get an &lt;a href=&quot;https://realpython.com/courses/python-exceptions-101/&quot;&gt;error&lt;/a&gt;. In the following example, the positional arguments are numbered &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, and &lt;code&gt;2&lt;/code&gt;, but you specify &lt;code&gt;{3}&lt;/code&gt; in the template:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{3}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#26&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{3}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;IndexError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;tuple index out of range&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This raises an &lt;code&gt;IndexError&lt;/code&gt; &lt;a href=&quot;https://realpython.com/python-exceptions/&quot;&gt;exception&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Starting with Python 3.1, you can omit the numbers in the replacement fields, in which case the interpreter assumes sequential order. This is referred to as &lt;strong&gt;automatic field numbering&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo/bar/baz&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you specify automatic field numbering, you must provide at least as many arguments as there are replacement fields:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{}{}{}{}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#27&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{}{}{}{}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;IndexError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;tuple index out of range&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this case, there are four replacement fields in the template but only three arguments, so an &lt;code&gt;IndexError&lt;/code&gt; exception occurs. On the other hand, it&amp;rsquo;s fine if the arguments outnumber the replacement fields. The excess arguments simply aren&amp;rsquo;t used:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{}{}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, the argument &lt;code&gt;&#39;baz&#39;&lt;/code&gt; is ignored.&lt;/p&gt;
&lt;p&gt;Note that you can&amp;rsquo;t intermingle these two techniques:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}{}{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#28&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}{}{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ValueError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;cannot switch from manual field specification to automatic field&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; numbering&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you use Python to format strings with positional arguments, you must choose between either automatic or explicit replacement field numbering.&lt;/p&gt;
&lt;h3 id=&quot;keyword-arguments&quot;&gt;Keyword Arguments&lt;/h3&gt;
&lt;p&gt;Keyword arguments are inserted into the template string in place of &lt;strong&gt;keyword replacement fields with the same name&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{x}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{y}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{z}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo/bar/baz&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this example, the values of the keyword arguments &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, and &lt;code&gt;z&lt;/code&gt; take the place of the replacement fields &lt;code&gt;{x}&lt;/code&gt;, &lt;code&gt;{y}&lt;/code&gt;, and &lt;code&gt;{z}&lt;/code&gt;, respectively.&lt;/p&gt;
&lt;p&gt;If you refer to a keyword argument that&amp;rsquo;s missing, then you&amp;rsquo;ll see an error:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{x}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{y}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{w}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;KeyError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;#39;w&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you specify replacement field &lt;code&gt;{w}&lt;/code&gt;, but there&amp;rsquo;s no corresponding keyword argument named &lt;code&gt;w&lt;/code&gt;. Python raises a &lt;a href=&quot;https://realpython.com/courses/python-keyerror/&quot;&gt;&lt;code&gt;KeyError&lt;/code&gt; exception&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While you have to specify positional arguments in sequential order, but you can specify keyword arguments in any arbitrary order:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{2}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo/bar/baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{2}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;bar/baz/foo&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{x}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{y}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{z}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo/bar/baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{x}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{y}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{z}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo/bar/baz&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can specify both positional and keyword arguments in one Python &lt;code&gt;.format()&lt;/code&gt; call. Just note that, if you do so, then all the &lt;strong&gt;positional arguments must appear before&lt;/strong&gt; any of the keyword arguments:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}{x}{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foobazbar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}{x}{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;positional argument follows keyword argument&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In fact, the requirement that all positional arguments appear before any keyword arguments doesn&amp;rsquo;t apply only to Python format methods. This is generally true of any function or method call. You&amp;rsquo;ll learn more about this in the next tutorial in this series, which explores functions and function calls.&lt;/p&gt;
&lt;p&gt;In all the examples shown so far, the values you passed to the Python &lt;code&gt;.format()&lt;/code&gt; method have been literal values, but you may specify variables as well:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo/bar/baz&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this case, you pass the variables &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; as positional parameter values and &lt;code&gt;z&lt;/code&gt; as a keyword parameter value.&lt;/p&gt;
&lt;h2 id=&quot;the-string-format-method-simple-replacement-fields&quot;&gt;The String &lt;code&gt;.format()&lt;/code&gt; Method: Simple Replacement Fields&lt;/h2&gt;
&lt;p&gt;As you&amp;rsquo;ve seen, when you call Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method, the &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; string contains &lt;strong&gt;replacement fields&lt;/strong&gt;. These indicate where in the template to insert the arguments to the method. A replacement field consists of three components:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;{[&amp;lt;name&amp;gt;][!&amp;lt;conversion&amp;gt;][:&amp;lt;format_spec&amp;gt;]}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These components are interpreted as follows:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies the source of the value to be formatted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;conversion&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Indicates which standard Python function to use to perform the conversion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies more detail about how the value should be converted&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Each component is optional and may be omitted. Let&amp;rsquo;s take a look at each component in more depth.&lt;/p&gt;
&lt;h3 id=&quot;the-ltnamegt-component&quot;&gt;The &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; Component&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; component is the first portion of a replacement field:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;{&lt;/code&gt;&lt;strong&gt;&lt;code&gt;[&amp;lt;name&amp;gt;]&lt;/code&gt;&lt;/strong&gt;&lt;code&gt;[!&amp;lt;conversion&amp;gt;][:&amp;lt;format_spec&amp;gt;]}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; indicates which argument from the argument list is inserted into the Python format string in the given location. It&amp;rsquo;s either a number for a positional argument or a keyword for a keyword argument. In the following example, the &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; components of the replacement fields are &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, and &lt;code&gt;baz&lt;/code&gt;, respectively:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{baz}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1, 2, 3&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If an argument is a list, then you can use indices with &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; to access the list&amp;rsquo;s elements:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0[0]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0[2]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo, baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{my_list[0]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{my_list[2]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo, baz&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Similarly, you can use a key reference with &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; if the corresponding argument is a &lt;a href=&quot;https://realpython.com/courses/dictionaries-python/&quot;&gt;dictionary&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;key1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;key2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;key1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0[key1]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;key2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{my_dict[key2]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can also reference &lt;strong&gt;object attributes&lt;/strong&gt; from within a replacement field. In the &lt;a href=&quot;https://realpython.com/python-variables/#object-references&quot;&gt;previous tutorial&lt;/a&gt; in this series, you learned that virtually every item of data in Python is an &lt;strong&gt;object&lt;/strong&gt;. Objects may have &lt;strong&gt;attributes&lt;/strong&gt; assigned to them that are accessed using dot notation:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, &lt;code&gt;obj&lt;/code&gt; is an object with an attribute named &lt;code&gt;attr&lt;/code&gt;. You use dot notation to access the object&amp;rsquo;s attribute. Let&amp;rsquo;s see an example. &lt;a href=&quot;https://realpython.com/python-data-types/#complex-numbers&quot;&gt;Complex numbers&lt;/a&gt; in Python have attributes named &lt;code&gt;.real&lt;/code&gt; and &lt;code&gt;.imag&lt;/code&gt; that represent the real and imaginary portions of the number. You can access these using dot notation as well:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;complex&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;real&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3.0&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imag&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There are several upcoming tutorials in this series on object-oriented programming, in which you&amp;rsquo;ll learn a great deal more about object attributes like these.&lt;/p&gt;
&lt;p&gt;The relevance of object attributes in this context is that you can specify them in a Python &lt;code&gt;.format()&lt;/code&gt; replacement field:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(3+5j)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;real = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0.real}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, imag = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0.imag}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;real = 3.0, imag = 5.0&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, it&amp;rsquo;s relatively straightforward in Python to format components of complex objects using the &lt;code&gt;.format()&lt;/code&gt; method.&lt;/p&gt;
&lt;h3 id=&quot;the-ltconversiongt-component&quot;&gt;The &lt;code&gt;&amp;lt;conversion&amp;gt;&lt;/code&gt; Component&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;conversion&amp;gt;&lt;/code&gt; component is the middle portion of a replacement field:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;{[&amp;lt;name&amp;gt;]&lt;/code&gt;&lt;strong&gt;&lt;code&gt;[!&amp;lt;conversion&amp;gt;]&lt;/code&gt;&lt;/strong&gt;&lt;code&gt;[:&amp;lt;format_spec&amp;gt;]}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Python can format an object as a string using three different built-in functions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;str()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;repr()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ascii()&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By default, the Python &lt;code&gt;.format()&lt;/code&gt; method uses &lt;code&gt;str()&lt;/code&gt;, but in some instances, you may want to force &lt;code&gt;.format()&lt;/code&gt; to use one of the other two. You can do this with the &lt;code&gt;&amp;lt;conversion&amp;gt;&lt;/code&gt; component of a replacement field. The possible values for &lt;code&gt;&amp;lt;conversion&amp;gt;&lt;/code&gt; are shown in the table below:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;!s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Convert with &lt;code&gt;str()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;!r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Convert with &lt;code&gt;repr()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;!a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Convert with &lt;code&gt;ascii()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;The following examples force Python to perform string conversion using &lt;code&gt;str()&lt;/code&gt;, &lt;code&gt;repr()&lt;/code&gt;, and &lt;code&gt;ascii()&lt;/code&gt;, respectively:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0!s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;42&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0!r}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;42&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0!a}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;42&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In many cases, the result is the same regardless of which conversion function you use, as you can see in the example above. That being said, you won&amp;rsquo;t often need the &lt;code&gt;&amp;lt;conversion&amp;gt;&lt;/code&gt; component, so you won&amp;rsquo;t spend a lot of time on it here. However, there are situations where it makes a difference, so it&amp;rsquo;s good to be aware that you have the capability to force a specific conversion function if you need to.&lt;/p&gt;
&lt;h3 id=&quot;the-ltformat_specgt-component&quot;&gt;The &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt; Component&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt; component is the last portion of a replacement field:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;{[&amp;lt;name&amp;gt;][!&amp;lt;conversion&amp;gt;]&lt;/code&gt;&lt;strong&gt;&lt;code&gt;[:&amp;lt;format_spec&amp;gt;]&lt;/code&gt;&lt;/strong&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt; represents the guts of the Python &lt;code&gt;.format()&lt;/code&gt; method&amp;rsquo;s functionality. It contains information that exerts fine control over how values are formatted prior to being inserted into the template string. The general form is this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;:&lt;code&gt;[[&amp;lt;fill&amp;gt;]&amp;lt;align&amp;gt;][&amp;lt;sign&amp;gt;][#][0][&amp;lt;width&amp;gt;][&amp;lt;group&amp;gt;][.&amp;lt;prec&amp;gt;][&amp;lt;type&amp;gt;]&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The ten subcomponents of &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt; are specified in the order shown. They control formatting as described in the table below:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Subcomponent&lt;/th&gt;
&lt;th&gt;Effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Separates the &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt; from the rest of the replacement field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies how to pad values that don&amp;rsquo;t occupy the entire field width&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;align&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies how to justify values that don&amp;rsquo;t occupy the entire field width&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;sign&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Controls whether a leading sign is included for numeric values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Selects an alternate output form for certain presentation types&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Causes values to be padded on the left with zeros instead of ASCII space characters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies the minimum width of the output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;group&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies a grouping character for numeric output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.&amp;lt;prec&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies the number of digits after the decimal point for floating-point presentation types, and the maximum output width for string presentations types&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;type&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies the presentation type, which is the type of conversion performed on the corresponding argument&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;These functions are analogous to the components you&amp;rsquo;ll find in the string modulo operator&amp;rsquo;s &lt;a href=&quot;https://realpython.com/python-input-output/#conversion-specifiers&quot;&gt;conversion specifier&lt;/a&gt;, but with somewhat greater capability. You&amp;rsquo;ll see their capabilities explained more fully in the following sections.&lt;/p&gt;
&lt;h4 id=&quot;the-lttypegt-subcomponent&quot;&gt;The &lt;strong&gt;&lt;code&gt;&amp;lt;type&amp;gt;&lt;/code&gt;&lt;/strong&gt; Subcomponent&lt;/h4&gt;
&lt;p&gt;Let&amp;rsquo;s start with &lt;strong&gt;&lt;code&gt;&amp;lt;type&amp;gt;&lt;/code&gt;&lt;/strong&gt;, which is the final portion of &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt;. The &lt;code&gt;&amp;lt;type&amp;gt;&lt;/code&gt; subcomponent specifies the presentation type, which is the type of conversion that&amp;rsquo;s performed on the corresponding value to produce the output. The possible values are shown below:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Presentation Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Binary integer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Single character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Decimal integer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;e&lt;/code&gt; or &lt;code&gt;E&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Exponential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;f&lt;/code&gt; or &lt;code&gt;F&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Floating point&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;g&lt;/code&gt; or &lt;code&gt;G&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Floating point or Exponential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;o&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Octal integer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;x&lt;/code&gt; or &lt;code&gt;X&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hexadecimal integer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Percentage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;These are like the &lt;a href=&quot;https://realpython.com/python-input-output/#conversion-type&quot;&gt;conversion types&lt;/a&gt; used with the string modulo operator, and in many cases, they function the same. The following examples demonstrate the similarity:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;42&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;42&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;2.100000&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:f}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;2.100000&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%x&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1f&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:x}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1f&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, there are some minor differences between some of the Python &lt;code&gt;.format()&lt;/code&gt; presentation types and the string modulo operator conversion types:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;&lt;code&gt;.format()&lt;/code&gt; Method&lt;/th&gt;
&lt;th&gt;String Modulo Operator&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;b&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Designates binary integer conversion&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;i, u&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Designates integer conversion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;c&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Designates character conversion, and the corresponding value must be an integer&lt;/td&gt;
&lt;td&gt;Designates character conversion, but the corresponding value may be either an integer or a single-character string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;g, G&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Chooses between floating point or exponential output, but the rules governing the choice are slightly more complicated&lt;/td&gt;
&lt;td&gt;Chooses between floating point or exponential output, depending on the magnitude of the exponent and the value specified for &lt;code&gt;&amp;lt;prec&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;r, a&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not supported (though the functionality is provided by the &lt;code&gt;!r&lt;/code&gt; and &lt;code&gt;!a&lt;/code&gt; conversion components in the replacement field)&lt;/td&gt;
&lt;td&gt;Designates conversion with &lt;code&gt;repr()&lt;/code&gt; or &lt;code&gt;ascii()&lt;/code&gt;, respectively&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Converts a numeric argument to a percentage&lt;/td&gt;
&lt;td&gt;Inserts a literal &lt;code&gt;&#39;%&#39;&lt;/code&gt; character into the output&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Next, you&amp;rsquo;ll see several examples illustrating these differences, as well as some of the added features of the Python &lt;code&gt;.format()&lt;/code&gt; method presentation types. The first presentation type you&amp;rsquo;ll see is &lt;code&gt;b&lt;/code&gt;, which designates &lt;strong&gt;binary integer conversion&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:b}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;257&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;100000001&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The modulo operator doesn&amp;rsquo;t support binary conversion type at all:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;%b&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;257&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ValueError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;unsupported format character &amp;#39;b&amp;#39; (0x62) at index 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, the modulo operator does allow &lt;strong&gt;decimal integer conversion&lt;/strong&gt; with any of the &lt;code&gt;d&lt;/code&gt;, &lt;code&gt;i&lt;/code&gt;, and &lt;code&gt;u&lt;/code&gt; types. Only the &lt;code&gt;d&lt;/code&gt; presentation type indicates decimal integer conversion with the Python &lt;code&gt;.format()&lt;/code&gt; method. The &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;u&lt;/code&gt; presentation types aren&amp;rsquo;t supported and aren&amp;rsquo;t really necessary.&lt;/p&gt;
&lt;p&gt;Next up is &lt;strong&gt;single character conversion&lt;/strong&gt;. The modulo operator allows either an integer or single character value with the &lt;code&gt;c&lt;/code&gt; conversion type:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%c&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;#&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%c&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;#&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;#&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On the other hand, Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method requires that the value corresponding to the &lt;code&gt;c&lt;/code&gt; presentation type be an integer:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:c}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;#&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:c}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ValueError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;Unknown format code &amp;#39;c&amp;#39; for object of type &amp;#39;str&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you try to pass a value of a different type, you&amp;rsquo;ll get a &lt;code&gt;ValueError&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For both the string modulo operator and Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method, the &lt;strong&gt;&lt;code&gt;g&lt;/code&gt; conversion type&lt;/strong&gt; chooses either floating-point or exponential output, depending on the magnitude of the exponent and the value specified for &lt;code&gt;&amp;lt;prec&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:g}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.14159&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;3.14159&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:g}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;123456789.8765&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;-1.23457e+08&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;a href=&quot;https://docs.python.org/3.4/library/string.html#format-specification-mini-language&quot;&gt;exact rules&lt;/a&gt; governing the choice are slightly more complicated with &lt;code&gt;.format()&lt;/code&gt; than they are with the modulo operator. Generally, you can trust that the choice will make sense.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;G&lt;/code&gt;&lt;/strong&gt; is identical to &lt;code&gt;g&lt;/code&gt; except for when the output is exponential, in which case the &lt;code&gt;&#39;E&#39;&lt;/code&gt; will be in uppercase:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:G}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;123456789.8765&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;-1.23457E+08&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The result is the same as in the previous example, but this time with an uppercase &lt;code&gt;&#39;E&#39;&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; There are a couple of other situations where you&amp;rsquo;ll see a difference between the &lt;code&gt;g&lt;/code&gt; and &lt;code&gt;G&lt;/code&gt; presentations types.&lt;/p&gt;
&lt;p&gt;Under some circumstances, a floating-point operation can result in a value that&amp;rsquo;s essentially &lt;strong&gt;infinite&lt;/strong&gt;. The string representation of such a number in Python is &lt;strong&gt;&lt;code&gt;&#39;inf&#39;&lt;/code&gt;&lt;/strong&gt;. It may also happen that a floating-point operation produces a value that can&amp;rsquo;t be represented as a number. Python represents this with the string &lt;code&gt;&#39;NaN&#39;&lt;/code&gt;, which stands for &lt;strong&gt;Not a Number&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;When you pass these values to Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method, the &lt;code&gt;g&lt;/code&gt; presentation type produces lowercase output, and &lt;code&gt;G&lt;/code&gt; produces uppercase output:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1e300&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1e300&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;inf&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:g}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;inf&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:g}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;nan&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:G}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;INF&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:G}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;NAN&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You&amp;rsquo;ll see similar behavior with the &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;F&lt;/code&gt; presentations types as well:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:f}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;inf&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:F}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;INF&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:f}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;nan&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:F}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;NAN&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For more information on floating-point representation, &lt;code&gt;inf&lt;/code&gt;, and &lt;code&gt;NaN&lt;/code&gt;, check out the Wikipedia page on &lt;a href=&quot;https://en.wikipedia.org/wiki/IEEE_754-1985&quot;&gt;IEEE 754-1985&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The modulo operator supports &lt;strong&gt;&lt;code&gt;r&lt;/code&gt; and &lt;code&gt;a&lt;/code&gt; conversion types&lt;/strong&gt; to force conversion by &lt;code&gt;repr()&lt;/code&gt; and &lt;code&gt;ascii()&lt;/code&gt;, respectively. Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method doesn&amp;rsquo;t support &lt;code&gt;r&lt;/code&gt; and &lt;code&gt;a&lt;/code&gt; presentation types, but you can accomplish the same thing with the &lt;code&gt;!r&lt;/code&gt; and &lt;code&gt;!a&lt;/code&gt; conversion components in the replacement field.&lt;/p&gt;
&lt;p&gt;Finally, you can use the &lt;strong&gt;&lt;code&gt;%&lt;/code&gt; conversion type&lt;/strong&gt; with the modulo operator to insert a literal &lt;code&gt;&#39;%&#39;&lt;/code&gt; character into the output:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%f%%&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;65.0&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;65.000000%&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You don&amp;rsquo;t need anything special to insert a literal &lt;code&gt;&#39;%&#39;&lt;/code&gt; character into the Python &lt;code&gt;.format()&lt;/code&gt; method&amp;rsquo;s output, so the &lt;code&gt;%&lt;/code&gt; presentation type serves a different handy purpose for &lt;strong&gt;percent output&lt;/strong&gt;. It multiplies the specified value by 100 and appends a percent sign:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:%}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;65.000000%&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The remaining parts of &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt; indicate how the chosen presentation type is formatted, in much the same way as the string modulo operator&amp;rsquo;s &lt;a href=&quot;https://realpython.com/python-input-output/#width-and-precision-specifiers&quot;&gt;width and precision specifiers&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/python-input-output/#conversion-flags&quot;&gt;conversion flags&lt;/a&gt;. These are described more fully in the following sections.&lt;/p&gt;
&lt;h4 id=&quot;the-ltfillgt-and-ltaligngt-subcomponents&quot;&gt;The &lt;strong&gt;&lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;&amp;lt;align&amp;gt;&lt;/code&gt;&lt;/strong&gt; Subcomponents&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;align&amp;gt;&lt;/code&gt; control how formatted output is padded and positioned within the specified field width. These subcomponents only have meaning when the formatted field value doesn&amp;rsquo;t occupy the entire field width, which can only happen if a minimum field width is specified with &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt;. If &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt; isn&amp;rsquo;t specified, then &lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;align&amp;gt;&lt;/code&gt; are effectively ignored. You&amp;rsquo;ll cover &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt; later on in this tutorial.&lt;/p&gt;
&lt;p&gt;Here are the possible values for the &lt;code&gt;&amp;lt;align&amp;gt;&lt;/code&gt; subcomponent:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;^&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;=&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A value using the less than sign (&lt;code&gt;&amp;lt;&lt;/code&gt;) indicates that the output is left-justified:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:&amp;lt;8s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo     &amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:&amp;lt;8d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;123     &amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This behavior is the default for string values.&lt;/p&gt;
&lt;p&gt;A value using the greater than sign (&lt;code&gt;&amp;gt;&lt;/code&gt;) indicates that the output should be right-justified:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:&amp;gt;8s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;     foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:&amp;gt;8d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;     123&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This behavior is the default for numeric values.&lt;/p&gt;
&lt;p&gt;A value using a caret (&lt;code&gt;^&lt;/code&gt;) indicates that the output should be centered in the output field:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:^8s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;  foo   &amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:^8d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;  123   &amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, you can also specify a value using the equals sign (&lt;code&gt;=&lt;/code&gt;) for the &lt;code&gt;&amp;lt;align&amp;gt;&lt;/code&gt; subcomponent. This only has meaning for numeric values, and only when a sign is included in the output.&lt;/p&gt;
&lt;p&gt;When numeric output includes a sign, it&amp;rsquo;s normally placed directly to the left of the first digit in the number, as shown above. If &lt;code&gt;&amp;lt;align&amp;gt;&lt;/code&gt; is set to the equals sign (&lt;code&gt;=&lt;/code&gt;), then the sign appears at the left edge of the output field, and padding is placed in between the sign and the number:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:+8d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;    +123&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:=+8d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;+    123&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:+8d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;    -123&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:=+8d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;-    123&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You&amp;rsquo;ll cover the &lt;code&gt;&amp;lt;sign&amp;gt;&lt;/code&gt; component in detail in the next section.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt; specifies how to fill in extra space when the formatted value doesn&amp;rsquo;t completely fill the output width. It can be any character except for curly braces (&lt;code&gt;{}&lt;/code&gt;). (If you really feel compelled to pad a field with curly braces, then you&amp;rsquo;ll just have to find another way!)&lt;/p&gt;
&lt;p&gt;Some examples of the use of &lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt; are shown below:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:-&amp;gt;8s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;-----foo&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:#&amp;lt;8d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;123#####&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:*^8s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;**foo***&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you specify a value for &lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt;, then you should also include a value for &lt;code&gt;&amp;lt;align&amp;gt;&lt;/code&gt; as well.&lt;/p&gt;
&lt;h4 id=&quot;the-ltsigngt-subcomponent&quot;&gt;The &lt;strong&gt;&lt;code&gt;&amp;lt;sign&amp;gt;&lt;/code&gt;&lt;/strong&gt; Subcomponent&lt;/h4&gt;
&lt;p&gt;You can control whether a &lt;strong&gt;sign&lt;/strong&gt; appears in numeric output with the &lt;code&gt;&amp;lt;sign&amp;gt;&lt;/code&gt; component. For example, in the following, the plus sign (&lt;code&gt;+&lt;/code&gt;) specified in the &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt; indicates that the value should always be displayed with a leading sign:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:+6d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;  +123&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:+6d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;  -123&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you use the plus sign (&lt;code&gt;+&lt;/code&gt;), so a sign will always be included for both positive and negative values. If you use the minus sign (&lt;code&gt;-&lt;/code&gt;), then only negative numeric values will include a leading sign, and positive values won&amp;rsquo;t:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:-6d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;   123&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:-6d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;  -123&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you use a single space (&lt;code&gt;&#39; &#39;&lt;/code&gt;), it means a sign is included for negative values, and an ASCII space character for positive values:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:*&amp;gt; 6d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;** 123&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:*&amp;gt;6d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;***123&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:*&amp;gt; 6d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;**-123&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Since the space character is the default fill character, you&amp;rsquo;d only notice the effect of this if an alternate &lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt; character is specified.&lt;/p&gt;
&lt;p&gt;Lastly, recall from above that when you specify the equals sign (&lt;code&gt;=&lt;/code&gt;) for &lt;code&gt;&amp;lt;align&amp;gt;&lt;/code&gt; and you include a &lt;code&gt;&amp;lt;sign&amp;gt;&lt;/code&gt; specifier, the padding goes between the sign and the value, rather than to the left of the sign.&lt;/p&gt;
&lt;h4 id=&quot;the-subcomponent&quot;&gt;The &lt;strong&gt;&lt;code&gt;#&lt;/code&gt;&lt;/strong&gt; Subcomponent&lt;/h4&gt;
&lt;p&gt;When you specify a hash character (&lt;code&gt;#&lt;/code&gt;) in &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt;, Python will select an alternate output form for certain presentation types. This is analogous to the &lt;code&gt;#&lt;/code&gt; conversion flag for the string modulo operator. For binary, octal, and hexadecimal presentation types, the hash character (&lt;code&gt;#&lt;/code&gt;) causes inclusion of an explicit base indicator to the left of the value:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:b}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:#b}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;10000, 0b10000&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:o}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:#o}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;20, 0o20&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:x}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:#x}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;10, 0x10&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, the base indicator can be &lt;code&gt;0b&lt;/code&gt;, &lt;code&gt;0o&lt;/code&gt;, or &lt;code&gt;0x&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For floating-point or exponential presentation types, the hash character forces the output to contain a decimal point, even if the output consists of a whole number:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:.0f}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:#.0f}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;123, 123.&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:.0e}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:#.0e}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1e+02, 1.e+02&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For any presentation type other than those shown above, the hash character (&lt;code&gt;#&lt;/code&gt;) has no effect.&lt;/p&gt;
&lt;h4 id=&quot;the-0-subcomponent&quot;&gt;The &lt;strong&gt;&lt;code&gt;0&lt;/code&gt;&lt;/strong&gt; Subcomponent&lt;/h4&gt;
&lt;p&gt;If output is smaller than the indicated field width and you specify the digit zero (&lt;code&gt;0&lt;/code&gt;) in &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt;, then values will be padded on the left with zeros instead of ASCII space characters:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:05d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;00123&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:08.1f}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;12.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;000012.3&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You&amp;rsquo;ll typically use this for numeric values, as shown above. However, it works for string values as well:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:&amp;gt;06s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;000foo&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you specify both &lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;align&amp;gt;&lt;/code&gt;, then &lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt; overrides &lt;code&gt;0&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:*&amp;gt;05d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;**123&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt; and &lt;code&gt;0&lt;/code&gt; essentially control the same thing, so there really isn&amp;rsquo;t any need to specify both. In fact, &lt;code&gt;0&lt;/code&gt; is really superfluous, and was probably included as a convenience for developers who are familiar with the string modulo operator&amp;rsquo;s similar &lt;code&gt;0&lt;/code&gt; conversion flag.&lt;/p&gt;
&lt;h4 id=&quot;the-ltwidthgt-subcomponent&quot;&gt;The &lt;strong&gt;&lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt;&lt;/strong&gt; Subcomponent&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt; specifies the minimum width of the output field:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:8s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo     &amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:8d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;     123&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that this is a &lt;strong&gt;minimum field width&lt;/strong&gt;. Suppose you specify a value that&amp;rsquo;s longer than the minimum:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:2s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this case, &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt; is effectively ignored.&lt;/p&gt;
&lt;h4 id=&quot;the-ltgroupgt-subcomponent&quot;&gt;The &lt;strong&gt;&lt;code&gt;&amp;lt;group&amp;gt;&lt;/code&gt;&lt;/strong&gt; Subcomponent&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;group&amp;gt;&lt;/code&gt; allows you to include a &lt;strong&gt;grouping separator character&lt;/strong&gt; in numeric output. For decimal and floating-point presentation types, &lt;code&gt;&amp;lt;group&amp;gt;&lt;/code&gt; may be specified as either a comma character (&lt;code&gt;,&lt;/code&gt;) or an underscore character (&lt;code&gt;_&lt;/code&gt;). That character then separates each group of three digits in the output:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:,d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1234567&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1,234,567&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{0:_d}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1234567&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1_234_567&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:,.2f}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1234567.89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1,234,567.89&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{0:_.2f}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1234567.89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1_234_567.89&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A &lt;code&gt;&amp;lt;group&amp;gt;&lt;/code&gt; value using an underscore (&lt;code&gt;_&lt;/code&gt;) may also be specified with the binary, octal, and hexadecimal presentation types. In that case, each group of four digits is separated by an underscore character in the output:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{0:_b}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mb&quot;&gt;0b111010100001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1110_1010_0001&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{0:#_b}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mb&quot;&gt;0b111010100001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0b1110_1010_0001&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{0:_x}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xae123fcc8ab2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;ae12_3fcc_8ab2&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{0:#_x}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xae123fcc8ab2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0xae12_3fcc_8ab2&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you try to specify &lt;code&gt;&amp;lt;group&amp;gt;&lt;/code&gt; with any presentation type other than those listed above, then your code will raise an exception.&lt;/p&gt;
&lt;h4 id=&quot;the-ltprecgt-subcomponent&quot;&gt;The &lt;strong&gt;&lt;code&gt;.&amp;lt;prec&amp;gt;&lt;/code&gt;&lt;/strong&gt; Subcomponent&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;.&amp;lt;prec&amp;gt;&lt;/code&gt; specifies the number of digits after the decimal point for floating point presentation types:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:8.2f}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1234.5678&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39; 1234.57&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:8.4f}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;  1.2300&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:8.2e}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1234.5678&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1.23e+03&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:8.4e}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1.2300e+00&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For string types, &lt;code&gt;.&amp;lt;prec&amp;gt;&lt;/code&gt; specifies the maximum width of the converted output:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:.4s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foob&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the output would be longer than the value specified, then it will be truncated.&lt;/p&gt;
&lt;h2 id=&quot;the-string-format-method-nested-replacement-fields&quot;&gt;The String &lt;code&gt;.format()&lt;/code&gt; Method: Nested Replacement Fields&lt;/h2&gt;
&lt;p&gt;Recall that you can &lt;a href=&quot;https://realpython.com/python-input-output/#width-and-precision-specifiers&quot;&gt;specify&lt;/a&gt; either &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;prec&amp;gt;&lt;/code&gt; by an asterisk with the string modulo operator:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%*.*f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;123.456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Width is 10, precision is 2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;    123.46&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The associated values are then taken from the argument list. This allows &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;prec&amp;gt;&lt;/code&gt; to be evaluated dynamically at run-time, as shown in the example above. Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method provides similar capability using &lt;strong&gt;nested replacement fields&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Inside a replacement field, you can specify a nested set of curly braces (&lt;code&gt;{}&lt;/code&gt;) that contains a name or number referring to one of the method&amp;rsquo;s positional or keyword arguments. That portion of the replacement field will then be evaluated at run-time and replaced using the corresponding argument. You can accomplish the same effect as the above string modulo operator example with nested replacement fields:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{2:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;f}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;123.456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;    123.46&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, the &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; component of the replacement field is &lt;code&gt;2&lt;/code&gt;, which indicates the third positional parameter whose value is &lt;code&gt;123.456&lt;/code&gt;. This is the value to be formatted. The nested replacement fields &lt;code&gt;{0}&lt;/code&gt; and &lt;code&gt;{1}&lt;/code&gt; correspond to the first and second positional parameters, &lt;code&gt;w&lt;/code&gt; and &lt;code&gt;p&lt;/code&gt;. These occupy the &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;prec&amp;gt;&lt;/code&gt; locations in &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt; and allow field width and precision to be evaluated at run-time.&lt;/p&gt;
&lt;p&gt;You can use &lt;strong&gt;keyword arguments with nested replacement fields&lt;/strong&gt; as well. This example is functionally equivalent to the previous one:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{val:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{wid}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{pr}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;f}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;123.456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;    123.46&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In either case, the values of &lt;code&gt;w&lt;/code&gt; and &lt;code&gt;p&lt;/code&gt; are evaluated at run-time and used to modify the &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt;. The result is effectively the same as this:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:10.2f}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;123.456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;    123.46&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The string modulo operator only allows &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;prec&amp;gt;&lt;/code&gt; to be evaluated at run-time in this way. By contrast, with Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method you can specify any portion of &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt; using nested replacement fields.&lt;/p&gt;
&lt;p&gt;In the following example, the presentation type &lt;code&gt;&amp;lt;type&amp;gt;&lt;/code&gt; is specified by a nested replacement field and determined dynamically:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;oct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;0b1010&amp;#39;, &amp;#39;0o12&amp;#39;, &amp;#39;0xa&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;o&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;x&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{0:#&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{type}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0b1010&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0o12&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0xa&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, the grouping character &lt;code&gt;&amp;lt;group&amp;gt;&lt;/code&gt; is nested:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{0:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{grp}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;d}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123456789&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;_&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;123_456_789&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{0:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{grp}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;d}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123456789&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;123,456,789&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Whew! That was an adventure. The specification of the template string is virtually a language unto itself!&lt;/p&gt;
&lt;p&gt;As you can see, string formatting can be very finely tuned when you use Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method. Next, you&amp;rsquo;ll see one more technique for string and output formatting that affords all the advantages of &lt;code&gt;.format()&lt;/code&gt;, but with more direct syntax.&lt;/p&gt;
&lt;h2 id=&quot;the-python-formatted-string-literal-f-string&quot;&gt;The Python Formatted String Literal (f-String)&lt;/h2&gt;
&lt;p&gt;In version 3.6, a new Python string formatting syntax was introduced, called the &lt;strong&gt;formatted string literal.&lt;/strong&gt; These are also informally called &lt;strong&gt;f-strings&lt;/strong&gt;, a term that was initially coined in &lt;a href=&quot;https://www.python.org/dev/peps/pep-0498&quot;&gt;PEP 498&lt;/a&gt;, where they were first proposed.&lt;/p&gt;
&lt;h3 id=&quot;f-string-syntax&quot;&gt;f-String Syntax&lt;/h3&gt;
&lt;p&gt;An &lt;a href=&quot;https://realpython.com/courses/python-3-f-strings-improved-string-formatting-syntax/&quot;&gt;f-string&lt;/a&gt; looks very much like a typical Python string except that it&amp;rsquo;s prepended by the character &lt;code&gt;f&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo bar baz&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can also use an uppercase &lt;code&gt;F&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;qux quux&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;qux quux&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The effect is exactly the same. Just like with any other type of string, you can use single, double, or triple quotes to define an f-string:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&amp;#39;baz&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The magic of f-strings is that you can embed Python expressions directly inside them. Any portion of an f-string that&amp;rsquo;s enclosed in curly braces (&lt;code&gt;{}&lt;/code&gt;) is treated as an &lt;strong&gt;expression&lt;/strong&gt;. The expression is evaluated and converted to string representation, and the result is interpolated into the original string in that location:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo.&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;.baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foo.bar.baz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The interpreter treats the remainder of the f-string&amp;mdash;anything not inside curly braces&amp;mdash;just as it would an ordinary string. For example, escape sequences are processed as expected:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{s}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foo&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bar&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;baz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here&amp;rsquo;s the example from earlier using an f-string:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quantity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bananas&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.74&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{quantity}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{item}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; cost $&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{price}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6 bananas cost $1.74&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is equivalent to the following:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quantity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bananas&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.74&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; cost $&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{2}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quantity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6 bananas cost $1.74&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Expressions embedded in f-strings can be almost arbitrarily complex. The examples below show some of the possibilities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Variables:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quantity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bananas&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.74&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{quantity}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{item}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; cost $&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{price}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;&amp;#39;6 bananas cost $1.74&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Arithmetic expressions:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quantity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bananas&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.74&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Price per item is ${price/quantity}&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Price per item is $0.29&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{x}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; cubed is {x**3}&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;6 cubed is 216&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Objects of composite types:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{a}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; | d = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;a = [&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;] | d = {&amp;#39;foo&amp;#39;: 1, &amp;#39;bar&amp;#39;: 2}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Indexing, slicing, and key references:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;First item in list a = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{a[0]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;First item in list a = foo&lt;/span&gt;

&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Last two items in list a = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{a[-2:]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Last two items in list a = [&amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;List a reversed = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{a[::-1]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;List a reversed = [&amp;#39;baz&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;foo&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Dict value for key &amp;#39;bar&amp;#39; is &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{d[&amp;#39;bar&amp;#39;]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Dict value for key &amp;#39;bar&amp;#39; is 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Function and method calls:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;List a has {len(a)} items&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;List a has 5 items&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;--- {s.upper()} ---&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;&amp;#39;--- FOOBAR ---&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Dict value for key &amp;#39;bar&amp;#39; is {d.get(&amp;#39;bar&amp;#39;)}&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Dict value for key &amp;#39;bar&amp;#39; is 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Conditional expressions:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;The larger of &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{x}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; and &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{y}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; is {x if x &amp;gt; y else y}&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;The larger of 3 and 7 is 7&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;I am {&amp;quot;a minor&amp;quot; if age &amp;lt; 18 else &amp;quot;an adult&amp;quot;}.&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;&amp;#39;I am a minor.&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Object attributes:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(3+5j)&lt;/span&gt;

&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;real = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{z.real}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, imag = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{z.imag}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;real = 3.0, imag = 5.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To include a literal curly brace in an f-string, escape it by doubling it, the same as you would in a template string for Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{{ &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{z[::-1]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; }}&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;{ raboof }&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You may prefix an f-string with &lt;code&gt;&#39;r&#39;&lt;/code&gt; or &lt;code&gt;&#39;R&#39;&lt;/code&gt; to indicate that it is a &lt;strong&gt;raw f-string&lt;/strong&gt;. In that case, backslash sequences are left intact, just like with an ordinary string:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{z}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foo&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bar&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;baz&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;rf&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo\n&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{z}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;\nbaz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;foo\nbar\nbaz&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;fr&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo\n&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{z}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;\nbaz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;foo\nbar\nbaz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that you can specify the &lt;code&gt;&#39;r&#39;&lt;/code&gt; first and then the &lt;code&gt;&#39;f&#39;&lt;/code&gt;, or vice-versa.&lt;/p&gt;
&lt;h3 id=&quot;f-string-expression-limitations&quot;&gt;f-String Expression Limitations&lt;/h3&gt;
&lt;p&gt;There are a few minor &lt;strong&gt;restrictions&lt;/strong&gt; on f-string expression. These aren&amp;rsquo;t too limiting, but you should know what they are. First, an f-string expression &lt;strong&gt;can&amp;rsquo;t be empty&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;f-string: empty expression not allowed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It isn&amp;rsquo;t obvious why you&amp;rsquo;d want to do this. But if you feel compelled to try, then just know that it won&amp;rsquo;t work.&lt;/p&gt;
&lt;p&gt;Additionally, an f-string expression &lt;strong&gt;can&amp;rsquo;t contain a backslash (&lt;code&gt;\&lt;/code&gt;) character&lt;/strong&gt;. Among other things, that means you can&amp;rsquo;t use a backslash escape sequence in an f-string expression:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo{&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;}bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;f-string expression part cannot include a backslash&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo{&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;}bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;f-string expression part cannot include a backslash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can get around this limitation by creating a temporary variable that contains the escape sequence you want to insert:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{nl}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foo&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bar&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quote&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{quote}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foo&amp;#39;bar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Lastly, an expression in an f-string that is triple-quoted &lt;strong&gt;can&amp;rsquo;t contain comments&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&amp;#39;foo{&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;z&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;}baz&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foobarbaz&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&amp;#39;foo{&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;z    # Comment&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;}&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;f-string expression part cannot include &amp;#39;#&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note, however, that the multiline f-string may contain embedded newlines.&lt;/p&gt;
&lt;h3 id=&quot;f-string-formatting&quot;&gt;f-String Formatting&lt;/h3&gt;
&lt;p&gt;Like Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method, f-strings support extensive &lt;strong&gt;modifiers&lt;/strong&gt; that control the final appearance of the output string. There&amp;rsquo;s more good news, too. If you&amp;rsquo;ve mastered the Python &lt;code&gt;.format()&lt;/code&gt; method, then &lt;strong&gt;you already know how to use Python to format f-strings!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Expressions in f-strings can be modified by a &lt;code&gt;&amp;lt;conversion&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt;, just like replacement fields used in the &lt;code&gt;.format()&lt;/code&gt; template. The syntax is identical. In fact, in both cases Python will format the replacement field using the same internal function. In the following example, &lt;code&gt;!r&lt;/code&gt; is specified as a &lt;code&gt;&amp;lt;conversion&amp;gt;&lt;/code&gt; component in the &lt;code&gt;.format()&lt;/code&gt; template string:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0!r}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;quot;&amp;#39;foo&amp;#39;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This forces conversion to be performed by &lt;code&gt;repr()&lt;/code&gt;. You can get essentially the same code using an f-string instead:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{s!r}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;quot;&amp;#39;foo&amp;#39;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;All the &lt;code&gt;&amp;lt;format_spec&amp;gt;&lt;/code&gt; components that work with &lt;code&gt;.format()&lt;/code&gt; also work with f-strings:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:=+8}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;+    123&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{n:=+8}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;+    123&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:*^8}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;**foo***&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{s:*^8}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;**foo***&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mb&quot;&gt;0b111010100001&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{0:#_b}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0b1110_1010_0001&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{n:#_b}&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0b1110_1010_0001&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Nesting&lt;/strong&gt; works as well, like nested replacement fields with Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{len(a):0&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{w}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;d}&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0005&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;123456789&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;_&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{(n * n):&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sep}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;d}&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;15_241_578_750_190_521&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This means formatting items can be evaluated at run-time.&lt;/p&gt;
&lt;p&gt;f-strings and Python&amp;rsquo;s &lt;code&gt;.format()&lt;/code&gt; method are, more or less, two different ways of doing the same thing, with f-strings being a more concise shorthand. The following expressions are essentially the same:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{&amp;lt;expr&amp;gt;!&amp;lt;conversion&amp;gt;:&amp;lt;format_spec&amp;gt;}&amp;#39;&lt;/span&gt;

&lt;span class=&quot;s1&quot;&gt;&amp;#39;{0!&amp;lt;conversion&amp;gt;:&amp;lt;format_spec&amp;gt;}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you want to explore f-strings further, then check out &lt;a href=&quot;https://realpython.com/courses/python-3-f-strings-improved-string-formatting-syntax&quot;&gt;Python 3&amp;rsquo;s f-Strings: An Improved String Formatting Syntax (Course)&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this tutorial, you mastered two additional techniques that you can use in Python to format string data. You should now have all the tools you need to prepare string data for output or display!&lt;/p&gt;
&lt;p&gt;You might be wondering which Python formatting technique you should use. Under what circumstances would you choose &lt;strong&gt;&lt;code&gt;.format()&lt;/code&gt;&lt;/strong&gt; over the &lt;strong&gt;f-string&lt;/strong&gt;? See &lt;a href=&quot;https://realpython.com/python-string-formatting/#which-string-formatting-method-should-you-use&quot;&gt;Python String Formatting Best Practices&lt;/a&gt; for some considerations to take into account.&lt;/p&gt;
&lt;p&gt;In the next tutorial, you&amp;rsquo;re going to learn more about &lt;strong&gt;functions&lt;/strong&gt; in Python. Throughout this tutorial series, you&amp;rsquo;ve seen many examples of Python&amp;rsquo;s &lt;strong&gt;built-in functions&lt;/strong&gt;. In Python, as in most programming languages, you can define your own custom &lt;strong&gt;user-defined functions&lt;/strong&gt; as well. If you can&amp;rsquo;t wait to learn how then continue on to the next tutorial!&lt;/p&gt;
&lt;!-- &lt;div class=&quot;container py-3 series-nav mb-3&quot;&gt;
  &lt;div class=&quot;row justify-content-between&quot;&gt;
    &lt;div class=&quot;col-12 col-md-3 text-left text-muted ml-1&quot;&gt;&lt;a href=&quot;https://realpython.com/python-input-output/&quot;&gt; «&amp;nbsp;Basic Input and Output in Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-center text-muted&quot;&gt;&lt;a href=&quot;#&quot;&gt;Formatted Output in Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-right text-muted mr-1&quot;&gt;&lt;a href=&quot;https://realpython.com/python-functions/&quot;&gt;Functions in Python&amp;nbsp;»&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
 --&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python Community Interview With Brett Slatkin</title>
      <id>https://realpython.com/interview-brett-slatkin/</id>
      <link href="https://realpython.com/interview-brett-slatkin/"/>
      <updated>2020-02-12T14:00:00+00:00</updated>
      <summary>Brett Slatkin is a principal software engineer at Google and the author of the Python programming book Effective Python. Join us as we discuss Brett&#39;s experience working with Python at Google, refactoring, and the challenges he faced when writing the second edition of his book.</summary>
      <content type="html">
        &lt;p&gt;Today I&amp;rsquo;m speaking to &lt;a href=&quot;https://twitter.com/haxor&quot;&gt;&lt;strong&gt;Brett Slatkin&lt;/strong&gt;&lt;/a&gt;, a principal software engineer at Google and the author of the Python programming book &lt;a href=&quot;https://realpython.com/asins/0134853989/&quot;&gt;&lt;em&gt;Effective Python&lt;/em&gt;&lt;/a&gt;. Join us as we discuss Brett&amp;rsquo;s experience working with Python at Google, refactoring, and the challenges he faced when writing the second edition of his book. Without any further ado, let&amp;rsquo;s get into it!&lt;/p&gt;
&lt;p class=&quot;mt-5&quot;&gt;&lt;strong&gt;Ricky:&lt;/strong&gt; &lt;em&gt;Welcome to&lt;/em&gt; Real Python, &lt;em&gt;Brett. I&amp;rsquo;m glad you could join me for this interview. Let&amp;rsquo;s start the same way we do with all our guests. How&amp;rsquo;d you get into programming, and when did you start using Python?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid w-25 float-right ml-3 rounded-circle&quot; src=&quot;https://files.realpython.com/media/bslatkin_square.5499b94f9504.jpg&quot; width=&quot;600&quot; height=&quot;600&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/bslatkin_square.5499b94f9504.jpg&amp;amp;w=150&amp;amp;sig=727ebbb17d8a217d1f67ffb392ff2e3cc2d00844 150w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/bslatkin_square.5499b94f9504.jpg&amp;amp;w=300&amp;amp;sig=8bdb9c3d144c4d0a5a737368734bfcc80baf44db 300w, https://files.realpython.com/media/bslatkin_square.5499b94f9504.jpg 600w&quot; sizes=&quot;75vw&quot; alt=&quot;Brett Slatkin&quot;/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Brett:&lt;/strong&gt; Thanks for having me! My path to programming was long and varied. Python was a surprising twist at the end of my education. It was something that I never expected, but it was a blessing. Once I learned the language, I fell in love with it.&lt;/p&gt;
&lt;p&gt;When I was growing up, my family had computers in our house, which was an enormous privilege. I always loved taking things apart to see how they worked, and I don&amp;rsquo;t remember a time when I wasn&amp;rsquo;t using computers and trying to figure them out. One of my late grandfather&amp;rsquo;s favorite stories was about the time he was having a printing problem and I fixed it for him. (I was 3 years old.)&lt;/p&gt;
&lt;p&gt;In the 5th grade, my whole class went to a computer lab one day and programmed with &lt;a href=&quot;https://en.wikipedia.org/wiki/Logo_(programming_language)&quot;&gt;Logo&lt;/a&gt; on an &lt;a href=&quot;https://en.wikipedia.org/wiki/Apple_IIGS&quot;&gt;Apple IIgs&lt;/a&gt;. I&amp;rsquo;m lucky that my mom encouraged my interest in programming after that by buying me books and enrolling me in nerdy summer camps. I used &lt;a href=&quot;http://lukazi.blogspot.com/2014/07/lego-legos-first-programmable-product.html&quot;&gt;Lego Technic Control Center&lt;/a&gt; kits to program small machines. These were the precursor to today&amp;rsquo;s &lt;a href=&quot;https://en.wikipedia.org/wiki/Lego_Mindstorms&quot;&gt;Lego Mindstorms&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;I also used &lt;a href=&quot;https://en.wikipedia.org/wiki/Delphi_(software)&quot;&gt;Borland Delphi&lt;/a&gt; to build simple GUI apps, like guess the number games. Then, the staff at my local internet cafe showed me Unix, Linux, and C, which blew my mind. That&amp;rsquo;s when I knew I wanted to be a programmer when I grew up.&lt;/p&gt;
&lt;p&gt;During high school, I took free classes at my local community college and studied &lt;a href=&quot;https://realpython.com/build-python-c-extension-module/&quot;&gt;C&lt;/a&gt;, C++, x86 assembly, and &lt;a href=&quot;https://realpython.com/pygame-a-primer/&quot;&gt;game development&lt;/a&gt;. I read &lt;a href=&quot;https://en.wikipedia.org/wiki/Scott_Meyers&quot;&gt;Scott Meyers&amp;rsquo;&lt;/a&gt; second edition of &lt;em&gt;Effective C++&lt;/em&gt; and became a huge fan of C++ and all of its arcane features. One summer, I had an unpaid internship with a dot-com bubble startup where I wrote web apps in &lt;a href=&quot;https://en.wikipedia.org/wiki/Active_Server_Pages&quot;&gt;ASP&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/VBScript&quot;&gt;VBScript&lt;/a&gt;. I was most excited about network programming and tried to build my own versions of &lt;a href=&quot;https://en.wikipedia.org/wiki/DikuMUD&quot;&gt;DikuMUD&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Hotline_Communications&quot;&gt;Hotline&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In college, I majored in computer engineering because I wanted to understand how computers worked at the transistor level. Most of my coursework was electrical engineering, where I used programming tools like &lt;a href=&quot;https://en.wikipedia.org/wiki/SPICE&quot;&gt;SPICE&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/VHDL&quot;&gt;VHDL&lt;/a&gt;, and &lt;a href=&quot;https://realpython.com/matlab-vs-python/&quot;&gt;MATLAB&lt;/a&gt;. For computer science classes, I learned LISP and wrote a lot of &lt;a href=&quot;https://realpython.com/oop-in-python-vs-java/&quot;&gt;Java&lt;/a&gt;. I was a teaching assistant for a variety of classes and really enjoyed teaching others. &lt;/p&gt;
&lt;p&gt;Finally, my first encounter with Python was in 2003 when I was looking into how the &lt;a href=&quot;https://en.wikipedia.org/wiki/BitTorrent_(software)&quot;&gt;BitTorrent&lt;/a&gt; client worked. (It was open source back then.) I thought the code was ugly because of all the &lt;code&gt;__dunder__&lt;/code&gt; special methods, and I ignored the language for all of my projects!&lt;/p&gt;
&lt;p&gt;I went to Google in 2005 after graduating from college because it seemed like the best place to learn more about network programming. But in those earlier days of the company, you didn&amp;rsquo;t get to pick what you worked on as a new hire. You were just assigned to a team. &lt;/p&gt;
&lt;p&gt;On my first day, my boss gave me a copy of the book &lt;em&gt;Python in a Nutshell&lt;/em&gt; and told me to go fix a ~25KLOC codebase that was broken. I thought that in the job I would be writing C++ for networked systems, but I ended up having to do something completely different. What made matters worse was that I was on my own because the original programmer had gone on mandatory vacation due to burnout!&lt;/p&gt;
&lt;p&gt;Luckily, &lt;a href=&quot;https://en.wikipedia.org/wiki/Alex_Martelli&quot;&gt;Alex Martelli&lt;/a&gt; was a colleague on the team I joined. He was the author of the book &lt;em&gt;Python in a Nutshell&lt;/em&gt; and he helped me learn the language. I was able to rewrite most of the codebase I inherited, fix its fundamental issues, and scale it to Google&amp;rsquo;s entire production fleet of machines. Believe it or not, this code is still in use today, nearly 15 years later. &lt;/p&gt;
&lt;p&gt;The productivity I gained from using Python was dramatic compared to my experience with C++ and Java. My perspective on programming and languages had completely changed. I was now excited about Python!&lt;/p&gt;
&lt;p class=&quot;mt-5&quot;&gt;&lt;strong&gt;Ricky:&lt;/strong&gt; &lt;em&gt;You&amp;rsquo;ve already touched on using Python at Google, where you&amp;rsquo;re now a principal software engineer, but in your tenure, you launched Google&amp;rsquo;s first cloud product, the App Engine. Now you&amp;rsquo;re the technical lead on Google Surveys, among other projects. How instrumental was Python in helping you develop these, and what does the future of Python look like at Google?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Brett:&lt;/strong&gt; There&amp;rsquo;s no doubt that I owe my career at Google to Python, but there&amp;rsquo;s more to the story. As background, it&amp;rsquo;s important for you to know that the five engineers who founded App Engine were originally using JavaScript, similar to Netscape&amp;rsquo;s &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Archive/Web/Server-Side_JavaScript&quot;&gt;Livewire&lt;/a&gt; server from 1995. However, this was before the release of Chrome and the large performance improvements of &lt;a href=&quot;https://en.wikipedia.org/wiki/V8_(JavaScript_engine)&quot;&gt;V8&lt;/a&gt;, which led to NodeJS. &lt;/p&gt;
&lt;p&gt;The founders were concerned that server-side JavaScript would make the system seem too niche. They wanted to provide the &lt;a href=&quot;https://en.wikipedia.org/wiki/LAMP_(software_bundle)&quot;&gt;LAMP&lt;/a&gt; stack, which was very popular at the time. The &amp;ldquo;P&amp;rdquo; in LAMP stood for Perl, PHP, or Python. Perl was generally on its way out of style, and PHP wasn&amp;rsquo;t a language Google used internally. But Python was, thanks to &lt;a href=&quot;https://norvig.com/&quot;&gt;Peter Norvig&lt;/a&gt;, and so it was the natural choice.&lt;/p&gt;
&lt;p&gt;I started on the App Engine team with a 20% project in late 2006 when I implemented the &lt;a href=&quot;https://cloud.google.com/appengine/docs/standard/python3/testing-and-deploying-your-app#local-dev-server&quot;&gt;dev_appserver&lt;/a&gt; in Python. Before that, there was no way to locally run an app before deploying it. I was so excited by the product&amp;rsquo;s potential and its use of Python that I moved over to work on it full-time shortly after. &lt;/p&gt;
&lt;p&gt;Guido van Rossum, who also worked at Google then, soon joined us. I had the exciting privilege of doing the &lt;a href=&quot;https://youtu.be/tcbpTQXNwac&quot;&gt;live demo&lt;/a&gt; during the launch event in 2008, where I wrote a web app in Python from scratch and deployed it in just a few minutes. I collaborated with Guido on a variety of projects over the years, the most interesting of which was &lt;a href=&quot;https://cloud.google.com/appengine/docs/standard/python/ndb/async&quot;&gt;ndb&lt;/a&gt; (the precursor to &lt;a href=&quot;https://docs.python.org/3/library/asyncio.html&quot;&gt;asyncio&lt;/a&gt;) that I beta tested extensively.&lt;/p&gt;
&lt;p&gt;What I enjoyed the most was writing full applications with Python in the App Engine environment to push the product&amp;rsquo;s limits. I would frequently break the system with my demo apps by hitting new barriers that we didn&amp;rsquo;t realize we had. This would lead us to build infrastructure improvements to ensure that the next app that needed to scale, such as &lt;a href=&quot;https://www.businessinsider.com/snapchat-is-built-on-googles-cloud-2014-1&quot;&gt;Snapchat&lt;/a&gt;, wouldn&amp;rsquo;t hit the same issues.&lt;/p&gt;
&lt;p&gt;My favorite demo app was the &lt;a href=&quot;https://en.wikipedia.org/wiki/WebSub&quot;&gt;PubSubHubbub&lt;/a&gt; protocol and hub that &lt;a href=&quot;http://bradfitz.com/&quot;&gt;Brad Fitzpatrick&lt;/a&gt; and I developed together. The protocol turned RSS feeds into real-time streams. It brought the liveliness of services like Twitter to the open web. &lt;/p&gt;
&lt;p&gt;At its height, our hub app was processing millions of feeds and thousands of requests per second, all using Python on App Engine. Since then, the hub has been integrated into Google&amp;rsquo;s standard web crawling infrastructure. PubSubHubbub (now called &lt;a href=&quot;https://www.w3.org/TR/websub/&quot;&gt;WebSub&lt;/a&gt;) became part of a larger group of specifications that made up &lt;a href=&quot;https://en.wikipedia.org/wiki/OStatus&quot;&gt;OStatus&lt;/a&gt;, which helped get &lt;a href=&quot;https://blog.joinmastodon.org/2017/09/mastodon-and-the-w3c/&quot;&gt;Mastadon&lt;/a&gt; off the ground.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://research.google/pubs/pub46243/&quot;&gt;Google Surveys&lt;/a&gt; started as another Python demo app on App Engine. I prototyped the whole system end-to-end in just a few weeks. My co-founder and I had the chance to show it off to Larry Page, and he greenlit the project. We launched a year later with a lean team, thanks to the leverage that Python provides. &lt;/p&gt;
&lt;p&gt;Our services now handle 500K+ requests per second and impact the majority of Google&amp;rsquo;s users and revenue. The codebase has grown from ~10KLOC to over 1MLOC, with the majority of it being in Python. We&amp;rsquo;ve had to migrate some services over to Go, C++, and Java as we&amp;rsquo;ve hit various CPU cost and latency constraints, but Python is still at the core of everything we do.&lt;/p&gt;
&lt;p&gt;Python has found its place at Google primarily as the tool for &lt;a href=&quot;https://colab.research.google.com/notebooks/welcome.ipynb&quot;&gt;data science&lt;/a&gt;, &lt;a href=&quot;https://developers.google.com/machine-learning/crash-course&quot;&gt;machine learning&lt;/a&gt;, and &lt;a href=&quot;https://landing.google.com/sre/sre-book/chapters/release-engineering/&quot;&gt;DevOps / SRE&lt;/a&gt;. Right now, engineers across the company are working towards deprecating Python 2 and moving the whole &lt;a href=&quot;https://ai.google/research/pubs/pub45424/&quot;&gt;monorepo&lt;/a&gt; over to Python 3 to stay in line with the Python community and open source packages.&lt;/p&gt;
&lt;p class=&quot;mt-5&quot;&gt;&lt;strong&gt;Ricky:&lt;/strong&gt; &lt;em&gt;On top of what you just talked about, you&amp;rsquo;re also an author of the popular Python programming book,&lt;/em&gt; &lt;a href=&quot;https://realpython.com/asins/0134853989/&quot;&gt;Effective Python&lt;/a&gt;, &lt;em&gt;which we previously reviewed in &lt;a href=&quot;https://realpython.com/best-python-books/&quot;&gt;The Best Python Books&lt;/a&gt;. You&amp;rsquo;ve recently published a second edition, which has substantial updates. What do the updates include, and what&amp;rsquo;s changed since the first edition?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Brett:&lt;/strong&gt; Thanks for considering my book one of the best! The response to the first edition has been wonderful. It was even translated into eight languages! There&amp;rsquo;s a lot of info about the new book on the &lt;a href=&quot;https://effectivepython.com&quot;&gt;official website&lt;/a&gt;, including the full table of contents with all of the item titles, a variety of samples, and the example code.&lt;/p&gt;
&lt;p&gt;The second edition of &lt;em&gt;Effective Python&lt;/em&gt; is nearly twice the length of the original and significantly revises all of the items of advice, in addition to providing 30+ new ones. The first edition of the book was written back in 2014 with Python 2.7 and Python 3.4 in mind. So much has been added in Python 3.5 through &lt;a href=&quot;https://realpython.com/courses/cool-new-features-python-38/&quot;&gt;Python 3.8&lt;/a&gt; over the past 5 years, so there was a lot to write about! The general style is the same and it still includes multi-color syntax highlighting.&lt;/p&gt;
&lt;p&gt;The new book covers the walrus operator, &lt;a href=&quot;https://realpython.com/courses/python-3-f-strings-improved-string-formatting-syntax/&quot;&gt;f-strings&lt;/a&gt;, best practices for &lt;a href=&quot;https://realpython.com/python-dicts/&quot;&gt;dictionaries&lt;/a&gt;, class &lt;a href=&quot;https://realpython.com/courses/python-decorators-101/&quot;&gt;decorators&lt;/a&gt;, and all of the important features of functions (including &lt;a href=&quot;https://realpython.com/python-async-features/&quot;&gt;asynchronous&lt;/a&gt; execution). I get into the details of unpacking generalizations, customized sorting, testing facilities, and algorithmic performance in the standard library. I also explain how to leverage more advanced tools such as the &lt;a href=&quot;https://realpython.com/python-type-checking/&quot;&gt;typing&lt;/a&gt; module and the &lt;code&gt;memoryview&lt;/code&gt; type.&lt;/p&gt;
&lt;p&gt;In this new edition, my advice about metaclasses has completely changed, thanks to the addition of &lt;code&gt;__init_subclass__&lt;/code&gt; and &lt;code&gt;__set_name__&lt;/code&gt; to the language. My recommendation for advanced generator usage with &lt;code&gt;send()&lt;/code&gt; and &lt;code&gt;throw()&lt;/code&gt; is now the opposite of what it was in the first edition. (Now I say to avoid them.) I compare the benefits of &lt;a href=&quot;https://realpython.com/courses/python-3-concurrency-asyncio-module/&quot;&gt;asyncio&lt;/a&gt; to threads and processes, which was entirely missing before. I provide guidance on how to convert synchronous code to asynchronous code, as well as how to mix asyncio with threads.&lt;/p&gt;
&lt;p&gt;Anyone out there who reads the book, please feel free to &lt;a href=&quot;http://a.quil.la/FVZ3PMZC&quot;&gt;send me questions or feedback!&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;mt-5&quot;&gt;&lt;strong&gt;Ricky:&lt;/strong&gt; &lt;em&gt;At PyCon 2016, you gave a talk titled &lt;a href=&quot;https://youtu.be/D_6ybDcU5gc&quot;&gt;Refactoring Python: Why and How to Restructure Your Code&lt;/a&gt;, which made our &lt;a href=&quot;https://realpython.com/must-watch-pycon-talks/&quot;&gt;Top 10 Must-Watch PyCon Talks&lt;/a&gt; list, too. I&amp;rsquo;m curious to know your motivations for giving the talk. What was it about refactoring (or the lack thereof) that inspired you to give a talk about it? Do people seem to struggle with refactoring? Are they falling for the same common pitfalls?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Brett:&lt;/strong&gt; Thanks for including my talk in your top ten list!&lt;/p&gt;
&lt;p&gt;When I put this talk together, I had been working in the same codebase for about six years. Any code of that age needs to be refactored constantly and updated to prevent it from rotting and becoming unusable. &lt;/p&gt;
&lt;p&gt;The rot I&amp;rsquo;m talking about happens when dependencies change in backward-incompatible ways, when the underlying infrastructure shifts to have different performance characteristics, or when product decisions break a large number of prior assumptions. So, refactoring was an ongoing necessity and it was on my mind frequently. This experience gave me a new appreciation for how crucial the skill of refactoring is. &lt;/p&gt;
&lt;p&gt;People often talk about how testing, tooling, and frameworks make them more effective programmers. But I believe refactoring is the big underappreciated fundamental skill that every programmer needs to focus on improving. Why? In my view, the best code is code that doesn&amp;rsquo;t exist and has been deleted or was never written. The best program you can have is an empty &lt;code&gt;.py&lt;/code&gt; file. The question is how do you get from where you are in a project to closer to that ideal? By refactoring.&lt;/p&gt;
&lt;p&gt;I wanted to help the other programmers on my team learn how to become better at refactoring, but the book &lt;em&gt;Refactoring&lt;/em&gt; by Martin Fowler hadn&amp;rsquo;t been updated since 1999. So I was considering writing a Python-specific version of the book to modernize it into something my colleagues could read. However, I put that on hold when I learned that Fowler was working on the second edition of &lt;em&gt;Refactoring&lt;/em&gt;, which has since been released and uses JavaScript as the implementation language. &lt;/p&gt;
&lt;p&gt;Unfortunately, it still falls short of what I need. I would love to see a Python-specific refactoring book, or a set of workable examples, that take advantage of everything the language has to offer.&lt;/p&gt;
&lt;p class=&quot;mt-5&quot;&gt;&lt;strong&gt;Ricky:&lt;/strong&gt; &lt;em&gt;Now for my last few questions. What else do you get up to in your spare time? What other hobbies and interests do you have, aside from Python and programming?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Brett:&lt;/strong&gt; We have two very young children at home, so my wife and I spend a lot of time with them. Singing songs and playing music (piano primarily, but sometimes guitar, ukulele, xylophone, and harmonica) have been the best ways to enjoy our time together. I&amp;rsquo;m terrible at all of these instruments, and not a great singer either, but we still have a lot of nice times.&lt;/p&gt;
&lt;p&gt;I like to be outside every day, either walking the hills of San Francisco or going for a run (usually while pushing a stroller). I love to surf when I get a chance. I enjoy reading, especially long-form journalism, but in reality, it&amp;rsquo;s mostly &lt;a href=&quot;https://www.reddit.com/r/programming/&quot;&gt;reddit&lt;/a&gt; and &lt;a href=&quot;https://lobste.rs/&quot;&gt;Lobsters&lt;/a&gt;. I&amp;rsquo;d like to be a better cook and find the right balance between laziness and deliciousness. I&amp;rsquo;m also trying to teach myself how to build statistical models using Bayesian methods. If I&amp;rsquo;ve learned anything over the years, it&amp;rsquo;s that nothing is for certain.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Thank you, Brett, for joining me this week! You can find Brett on &lt;a href=&quot;https://twitter.com/haxor&quot;&gt;Twitter&lt;/a&gt; or &lt;a href=&quot;https://github.com/bslatkin&quot;&gt;GitHub&lt;/a&gt;, and learn more about the second edition of Effective Python at &lt;a href=&quot;https://effectivepython.com&quot;&gt;effectivepython.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If there&amp;rsquo;s someone you&amp;rsquo;d like me to interview in the future, then reach out to me in the comments below, or &lt;a href=&quot;https://twitter.com/endlesstrax&quot;&gt;send me a message on Twitter&lt;/a&gt;. Happy coding!&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Playing and Recording Sound in Python</title>
      <id>https://realpython.com/courses/playing-and-recording-sound-python/</id>
      <link href="https://realpython.com/courses/playing-and-recording-sound-python/"/>
      <updated>2020-02-11T14:00:00+00:00</updated>
      <summary>In this course, you&#39;ll learn about libraries that can be used for playing and recording sound in Python, such as PyAudio and python-sounddevice. You&#39;ll also see code snippets for playing and recording sound files and arrays, as well as for converting between different sound file formats.</summary>
      <content type="html">
        &lt;p&gt;In this course, you&amp;rsquo;ll learn how to play and record &lt;strong&gt;sound&lt;/strong&gt; in &lt;strong&gt;Python&lt;/strong&gt; using some of the most popular audio libraries. You&amp;rsquo;ll learn about the most straightforward methods for playing and recording sound first, and then you&amp;rsquo;ll learn about some libraries that offer some more functionality in exchange for a few extra lines of code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll know how to:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Play MP3 and WAV files, as well as a range of other audio formats&lt;/li&gt;
&lt;li&gt;Play NumPy and Python arrays containing sound&lt;/li&gt;
&lt;li&gt;Record sound using Python&lt;/li&gt;
&lt;li&gt;Save your recordings or audio files in a range of different file formats&lt;/li&gt;
&lt;/ul&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Implementing an Interface in Python</title>
      <id>https://realpython.com/python-interface/</id>
      <link href="https://realpython.com/python-interface/"/>
      <updated>2020-02-10T14:00:00+00:00</updated>
      <summary>In this tutorial, you&#39;ll explore how to use a Python interface. You&#39;ll come to understand why interfaces are so useful and learn how to implement formal and informal interfaces in Python. You&#39;ll also examine the differences between Python interfaces and those in other programming languages.</summary>
      <content type="html">
        &lt;p&gt;Interfaces play an important role in software engineering. As an application grows, updates and changes to the code base become more difficult to manage. More often than not, you wind up having classes that look very similar but are unrelated, which can lead to some confusion. In this tutorial, you&amp;rsquo;ll see how you can use a &lt;strong&gt;Python interface&lt;/strong&gt; to help determine what class you should use to tackle the current problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this tutorial, you&amp;rsquo;ll be able to:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Understand&lt;/strong&gt; how interfaces work and the caveats of Python interface creation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Comprehend&lt;/strong&gt; how useful interfaces are in a dynamic language like Python&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Implement&lt;/strong&gt; an informal Python interface&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use&lt;/strong&gt; &lt;code&gt;abc.ABCMeta&lt;/code&gt; and &lt;code&gt;@abc.abstractmethod&lt;/code&gt; to implement a formal Python interface&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Interfaces in Python are handled differently than in most other languages, and they can vary in their design complexity. By the end of this tutorial, you&amp;rsquo;ll have a better understanding of some aspects of Python&amp;rsquo;s data model, as well as how interfaces in Python compare to those in languages like Java, C++, and Go.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-mastery-course&quot; data-focus=&quot;false&quot;&gt;5 Thoughts On Python Mastery&lt;/a&gt;, a free course for Python developers that shows you the roadmap and the mindset you&#39;ll need to take your Python skills to the next level.&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;python-interface-overview&quot;&gt;Python Interface Overview&lt;/h2&gt;
&lt;p&gt;At a high level, an interface acts as a &lt;strong&gt;blueprint&lt;/strong&gt; for designing classes. Like classes, interfaces define methods. Unlike classes, these methods are abstract. An &lt;strong&gt;abstract method&lt;/strong&gt; is one that the interface simply defines. It doesn&amp;rsquo;t implement the methods. This is done by classes, which then &lt;strong&gt;implement&lt;/strong&gt; the interface and give concrete meaning to the interface&amp;rsquo;s abstract methods.&lt;/p&gt;
&lt;p&gt;Python&amp;rsquo;s approach to interface design is somewhat different when compared to languages like &lt;a href=&quot;https://realpython.com/oop-in-python-vs-java/&quot;&gt;Java&lt;/a&gt;, Go, and C++. These languages all have an &lt;code&gt;interface&lt;/code&gt; keyword, while Python does not. Python further deviates from other languages in one other aspect. It doesn&amp;rsquo;t require the class that&amp;rsquo;s implementing the interface to define all of the interface&amp;rsquo;s abstract methods.&lt;/p&gt;
&lt;h2 id=&quot;informal-interfaces&quot;&gt;Informal Interfaces&lt;/h2&gt;
&lt;p&gt;In certain circumstances, you may not need the strict rules of a formal Python interface. Python&amp;rsquo;s dynamic nature allows you to implement an &lt;strong&gt;informal interface&lt;/strong&gt;. An informal Python interface is a class that defines methods that can be overridden, but there&amp;rsquo;s no strict enforcement.&lt;/p&gt;
&lt;p&gt;In the following example, you&amp;rsquo;ll take the perspective of a data engineer who needs to extract text from various different unstructured file types, like PDFs and emails. You&amp;rsquo;ll create an informal interface that defines the methods that will be in both the &lt;code&gt;PdfParser&lt;/code&gt; and &lt;code&gt;EmlParser&lt;/code&gt; concrete classes:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;InformalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Load in the file for extracting text.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from the currently loaded file.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;InformalParserInterface&lt;/code&gt; defines the two methods &lt;code&gt;.load_data_source()&lt;/code&gt; and &lt;code&gt;.extract_text()&lt;/code&gt;. These methods are defined but not implemented. The implementation will occur once you create &lt;strong&gt;concrete classes&lt;/strong&gt; that inherit from &lt;code&gt;InformalParserInterface&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As you can see, &lt;code&gt;InformalParserInterface&lt;/code&gt; looks identical to a standard Python class. You rely on &lt;a href=&quot;https://realpython.com/lessons/duck-typing/&quot;&gt;duck typing&lt;/a&gt; to inform users that this is an interface and should be used accordingly.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Haven&amp;rsquo;t heard of &lt;strong&gt;duck typing&lt;/strong&gt;? This term says that if you have an object that looks like a duck, walks like a duck, and quacks like a duck, then it must be a duck! To learn more, check out &lt;a href=&quot;https://realpython.com/lessons/duck-typing/&quot;&gt;Duck Typing&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;With duck typing in mind, you define two classes that implement the &lt;code&gt;InformalParserInterface&lt;/code&gt;. To use your interface, you must create a concrete class. A &lt;strong&gt;concrete class&lt;/strong&gt; is a subclass of the interface that provides an implementation of the interface&amp;rsquo;s methods. You&amp;rsquo;ll create two concrete classes to implement your interface. The first is &lt;code&gt;PdfParser&lt;/code&gt;, which you&amp;rsquo;ll use to parse the text from PDF files:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PdfParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InformalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from a PDF&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides InformalParserInterface.load_data_source()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides InformalParserInterface.extract_text()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The concrete implementation of &lt;code&gt;InformalParserInterface&lt;/code&gt; now allows you to extract text from PDF files.&lt;/p&gt;
&lt;p&gt;The second concrete class is &lt;code&gt;EmlParser&lt;/code&gt;, which you&amp;rsquo;ll use to parse the text from emails:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmlParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InformalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from an email&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides InformalParserInterface.load_data_source()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text_from_email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A method defined only in EmlParser.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        Does not override InformalParserInterface.extract_text()&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The concrete implementation of &lt;code&gt;InformalParserInterface&lt;/code&gt; now allows you to extract text from email files.&lt;/p&gt;
&lt;p&gt;So far, you&amp;rsquo;ve defined two &lt;strong&gt;concrete implementations&lt;/strong&gt; of the &lt;code&gt;InformalPythonInterface&lt;/code&gt;. However, note that &lt;code&gt;EmlParser&lt;/code&gt; fails to properly define &lt;code&gt;.extract_text()&lt;/code&gt;. If you were to check whether &lt;code&gt;EmlParser&lt;/code&gt; implements &lt;code&gt;InformalParserInterface&lt;/code&gt;, then you&amp;rsquo;d get the following result:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Check if both PdfParser and EmlParser implement InformalParserInterface&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;issubclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PdfParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InformalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;issubclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EmlParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InformalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This would return &lt;code&gt;True&lt;/code&gt;, which poses a bit of a problem since it violates the definition of an interface!&lt;/p&gt;
&lt;p&gt;Now check the &lt;strong&gt;method resolution order (MRO)&lt;/strong&gt; of &lt;code&gt;PdfParser&lt;/code&gt; and &lt;code&gt;EmlParser&lt;/code&gt;. This tells you the superclasses of the class in question, as well as the order in which they&amp;rsquo;re searched for executing a method. You can view a class&amp;rsquo;s MRO by using the dunder method &lt;code&gt;cls.__mro__&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PdfParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__mro__&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(__main__.PdfParser, __main__.InformalParserInterface, object)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EmlParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__mro__&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(__main__.EmlParser, __main__.InformalParserInterface, object)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Such informal interfaces are fine for small projects where only a few developers are working on the source code. However, as projects get larger and teams grow, this could lead to developers spending countless hours looking for hard-to-find logic errors in the codebase!&lt;/p&gt;
&lt;h3 id=&quot;using-metaclasses&quot;&gt;Using Metaclasses&lt;/h3&gt;
&lt;p&gt;Ideally, you would want &lt;code&gt;issubclass(EmlParser, InformalParserInterface&lt;/code&gt; to return &lt;code&gt;False&lt;/code&gt; when the implementing class doesn&amp;rsquo;t define all of the interface&amp;rsquo;s abstract methods. To do this, you&amp;rsquo;ll create a &lt;a href=&quot;https://realpython.com/python-metaclasses/&quot;&gt;metaclass&lt;/a&gt; called &lt;code&gt;ParserMeta&lt;/code&gt;. You&amp;rsquo;ll be overriding two &lt;a href=&quot;https://dbader.org/blog/python-dunder-methods&quot;&gt;dunder&lt;/a&gt; methods:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;.__instancecheck__()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.__subclasscheck__()&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the code block below, you create a class called &lt;code&gt;UpdatedInformalParserInterface&lt;/code&gt; that builds from the &lt;code&gt;ParserMeta&lt;/code&gt; metaclass:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ParserMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A Parser metaclass that will be used for parser class creation.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fm&quot;&gt;__instancecheck__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fm&quot;&gt;__subclasscheck__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fm&quot;&gt;__subclasscheck__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;load_data_source&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;extract_text&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extract_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UpdatedInformalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metaclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ParserMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;This interface is used for concrete classes to inherit from.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    There is no need to define the ParserMeta methods as any class&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    as they are implicitly made available via .__subclasscheck__().&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that &lt;code&gt;ParserMeta&lt;/code&gt; and &lt;code&gt;UpdatedInformalParserInterface&lt;/code&gt; have been created, you can create your concrete implementations.&lt;/p&gt;
&lt;p&gt;First, create a new class for parsing PDFs called &lt;code&gt;PdfParserNew&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PdfParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from a PDF.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides UpdatedInformalParserInterface.load_data_source()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides UpdatedInformalParserInterface.extract_text()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, &lt;code&gt;PdfParserNew&lt;/code&gt; overrides &lt;code&gt;.load_data_source()&lt;/code&gt; and &lt;code&gt;.extract_text()&lt;/code&gt;, so &lt;code&gt;issubclass(PdfParserNew, UpdatedInformalParserInterface)&lt;/code&gt; should return &lt;code&gt;True&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In this next code block, you have a new implementation of the email parser called &lt;code&gt;EmlParserNew&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmlParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from an email.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides UpdatedInformalParserInterface.load_data_source()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text_from_email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A method defined only in EmlParser.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        Does not override UpdatedInformalParserInterface.extract_text()&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you have a metaclass that&amp;rsquo;s used to create &lt;code&gt;UpdatedInformalParserInterface&lt;/code&gt;. By using a metaclass, you don&amp;rsquo;t need to explicitly define the subclasses. Instead, the subclass must &lt;strong&gt;define the required methods&lt;/strong&gt;. If it doesn&amp;rsquo;t, then &lt;code&gt;issubclass(EmlParserNew, UpdatedInformalParserInterface)&lt;/code&gt; will return &lt;code&gt;False&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Running &lt;code&gt;issubclass()&lt;/code&gt; on your concrete classes will produce the following:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;issubclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PdfParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UpdatedInformalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;issubclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EmlParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UpdatedInformalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As expected, &lt;code&gt;EmlParserNew&lt;/code&gt; is not a subclass of &lt;code&gt;UpdatedInformalParserInterface&lt;/code&gt; since &lt;code&gt;.extract_text()&lt;/code&gt; wasn&amp;rsquo;t defined in &lt;code&gt;EmlParserNew&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, let&amp;rsquo;s have a look at the MRO:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PdfParserNew&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__mro__&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;lt;class &amp;#39;__main__.PdfParserNew&amp;#39;&amp;gt;, &amp;lt;class &amp;#39;object&amp;#39;&amp;gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, &lt;code&gt;UpdatedInformalParserInterface&lt;/code&gt; is a superclass of &lt;code&gt;PdfParserNew&lt;/code&gt;, but it doesn&amp;rsquo;t appear in the MRO. This unusual behavior is caused by the fact that &lt;code&gt;UpdatedInformalParserInterface&lt;/code&gt; is a &lt;strong&gt;virtual base class&lt;/strong&gt; of &lt;code&gt;PdfParserNew&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;using-virtual-base-classes&quot;&gt;Using Virtual Base Classes&lt;/h3&gt;
&lt;p&gt;In the previous example, &lt;code&gt;issubclass(EmlParserNew, UpdatedInformalParserInterface)&lt;/code&gt; returned &lt;code&gt;True&lt;/code&gt;, even though &lt;code&gt;UpdatedInformalParserInterface&lt;/code&gt; did not appear in the &lt;code&gt;EmlParserNew&lt;/code&gt; MRO. That&amp;rsquo;s because &lt;code&gt;UpdatedInformalParserInterface&lt;/code&gt; is a &lt;strong&gt;virtual base class&lt;/strong&gt; of &lt;code&gt;EmlParserNew&lt;/code&gt;.  &lt;/p&gt;
&lt;p&gt;The key difference between these and standard subclasses is that virtual base classes use the &lt;code&gt;.__subclasscheck__()&lt;/code&gt; dunder method to implicitly check if a class is a virtual subclass of the superclass. Additionally, virtual base classes don&amp;rsquo;t appear in the subclass MRO.&lt;/p&gt;
&lt;p&gt;Take a look at this code block:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PersonMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A person metaclass&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fm&quot;&gt;__instancecheck__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fm&quot;&gt;__subclasscheck__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fm&quot;&gt;__subclasscheck__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;age&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PersonSuper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A person superclass&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metaclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PersonMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Person interface built from PersonMeta metaclass.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you have the setup for creating your virtual base classes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The metaclass &lt;code&gt;PersonMeta&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The base class &lt;code&gt;PersonSuper&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The Python interface &lt;code&gt;Person&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that the setup for creating &lt;strong&gt;virtual base classes&lt;/strong&gt; is done you&amp;rsquo;ll define two concrete classes, &lt;code&gt;Employee&lt;/code&gt; and &lt;code&gt;Friend&lt;/code&gt;. The &lt;code&gt;Employee&lt;/code&gt; class inherits from &lt;code&gt;PersonSuper&lt;/code&gt;, while &lt;code&gt;Friend&lt;/code&gt; implicitly inherits from &lt;code&gt;Person&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Inheriting subclasses&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PersonSuper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Inherits from PersonSuper&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    PersonSuper will appear in Employee.__mro__&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Friend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Built implicitly from Person&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    Friend is a virtual subclass of Person since&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    both required methods exist.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    Person not in Friend.__mro__&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Although &lt;code&gt;Friend&lt;/code&gt; does not explicitly inherit from &lt;code&gt;Person&lt;/code&gt;, it implements &lt;code&gt;.name()&lt;/code&gt; and &lt;code&gt;.age()&lt;/code&gt;, so &lt;code&gt;Person&lt;/code&gt; becomes a &lt;strong&gt;virtual base class&lt;/strong&gt; of &lt;code&gt;Friend&lt;/code&gt;. When you run &lt;code&gt;issubclass(Friend, Person)&lt;/code&gt; it should return &lt;code&gt;True&lt;/code&gt;, meaning that &lt;code&gt;Friend&lt;/code&gt; is a subclass of &lt;code&gt;Person&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The following &lt;a href=&quot;https://realpython.com/inheritance-composition-python/#whats-inheritance&quot;&gt;&lt;strong&gt;UML&lt;/strong&gt;&lt;/a&gt; diagram shows what happens when you call &lt;code&gt;issubclass()&lt;/code&gt; on the &lt;code&gt;Friend&lt;/code&gt; class:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/virtual-base-class.b545144aafef.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/virtual-base-class.b545144aafef.png&quot; width=&quot;401&quot; height=&quot;241&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/virtual-base-class.b545144aafef.png&amp;amp;w=100&amp;amp;sig=11a2043e7a54364bcf7f2e8789f61a5a842a5f93 100w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/virtual-base-class.b545144aafef.png&amp;amp;w=200&amp;amp;sig=09c75593e5f83b49a6b41ae65465b333c27d73e5 200w, https://files.realpython.com/media/virtual-base-class.b545144aafef.png 401w&quot; sizes=&quot;75vw&quot; alt=&quot;virtual base class&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Taking a look at &lt;code&gt;PersonMeta&lt;/code&gt;, you&amp;rsquo;ll notice that there&amp;rsquo;s another dunder method called &lt;code&gt;.__instancecheck__()&lt;/code&gt;. This method is used to check if instances of &lt;code&gt;Friend&lt;/code&gt; are created from the &lt;code&gt;Person&lt;/code&gt; interface. Your code will call &lt;code&gt;.__instancecheck__()&lt;/code&gt; when you use &lt;code&gt;isinstance(Friend, Person)&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;formal-interfaces&quot;&gt;Formal Interfaces&lt;/h2&gt;
&lt;p&gt;Informal interfaces can be useful for projects with a small code base and a limited number of programmers. However, informal interfaces would be the wrong approach for larger applications. In order to create a &lt;strong&gt;formal Python interface&lt;/strong&gt;, you&amp;rsquo;ll need a few more tools from Python&amp;rsquo;s &lt;code&gt;abc&lt;/code&gt; module.&lt;/p&gt;
&lt;h3 id=&quot;using-abcabcmeta&quot;&gt;Using &lt;code&gt;abc.ABCMeta&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;To enforce the subclass instantiation of abstract methods, you&amp;rsquo;ll utilize Python&amp;rsquo;s builtin &lt;code&gt;ABCMeta&lt;/code&gt; from the &lt;a href=&quot;https://docs.python.org/3/library/abc.html&quot;&gt;&lt;code&gt;abc&lt;/code&gt;&lt;/a&gt; module. Going back to your &lt;code&gt;UpdatedInformalParserInterface&lt;/code&gt; interface, you created your own metaclass, &lt;code&gt;ParserMeta&lt;/code&gt;, with the overridden dunder methods &lt;code&gt;.__instancecheck__()&lt;/code&gt; and  &lt;code&gt;.__subclasscheck__()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Rather than create your own metaclass, you&amp;rsquo;ll use &lt;code&gt;abc.ABCMeta&lt;/code&gt; as the metaclass. Then, you&amp;rsquo;ll overwrite &lt;code&gt;.__subclasshook__()&lt;/code&gt; in place of &lt;code&gt;.__instancecheck__()&lt;/code&gt; and &lt;code&gt;.__subclasscheck__()&lt;/code&gt;, as it creates a more reliable implementation of these dunder methods.&lt;/p&gt;
&lt;h3 id=&quot;using-__subclasshook__&quot;&gt;Using &lt;code&gt;.__subclasshook__()&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s the implementation of &lt;code&gt;FormalParserInterface&lt;/code&gt; using &lt;code&gt;abc.ABCMeta&lt;/code&gt; as your metaclass:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;abc&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FormalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metaclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ABCMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@classmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__subclasshook__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;load_data_source&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;extract_text&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extract_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PdfParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from a PDF.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides FormalParserInterface.load_data_source()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides FormalParserInterface.extract_text()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmlParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from an email.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides FormalParserInterface.load_data_source()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text_from_email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A method defined only in EmlParser.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        Does not override FormalParserInterface.extract_text()&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you run &lt;code&gt;issubclass()&lt;/code&gt; on &lt;code&gt;PdfParserNew&lt;/code&gt; and &lt;code&gt;EmlParserNew&lt;/code&gt;, then &lt;code&gt;issubclass()&lt;/code&gt; will return &lt;code&gt;True&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt;, respectively.  &lt;/p&gt;
&lt;h3 id=&quot;using-abc-to-register-a-virtual-subclass&quot;&gt;Using &lt;code&gt;abc&lt;/code&gt; to Register a Virtual Subclass&lt;/h3&gt;
&lt;p&gt;Once you&amp;rsquo;ve imported the &lt;code&gt;abc&lt;/code&gt; module, you can directly &lt;strong&gt;register a virtual subclass&lt;/strong&gt; by using the &lt;code&gt;.register()&lt;/code&gt; metamethod. In the next example, you register the interface &lt;code&gt;Double&lt;/code&gt; as a virtual base class of the built-in &lt;code&gt;__float__&lt;/code&gt; class:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metaclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ABCMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Double precision floating point number.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can check out the effect of using &lt;code&gt;.register()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;issubclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.2345&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By using the &lt;code&gt;.register()&lt;/code&gt; meta method, you&amp;rsquo;ve successfully registered &lt;code&gt;Double&lt;/code&gt; as a virtual subclass of &lt;code&gt;float&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;ve registered &lt;code&gt;Double&lt;/code&gt;, you can use it as class &lt;a href=&quot;https://realpython.com/courses/python-decorators-101/&quot;&gt;decorator&lt;/a&gt; to set the decorated class as a virtual subclass:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Double64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A 64-bit double-precision floating-point number.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;issubclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Double64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The decorator register method helps you to create a hierarchy of custom virtual class inheritance.&lt;/p&gt;
&lt;h3 id=&quot;using-subclass-detection-with-registration&quot;&gt;Using Subclass Detection With Registration&lt;/h3&gt;
&lt;p&gt;You must be careful when you&amp;rsquo;re combining &lt;code&gt;.__subclasshook__()&lt;/code&gt; with &lt;code&gt;.register()&lt;/code&gt;, as &lt;code&gt;.__subclasshook__()&lt;/code&gt; takes precedence over virtual subclass registration. To ensure that the registered virtual subclasses are taken into consideration, you must add &lt;code&gt;NotImplemented&lt;/code&gt; to the &lt;code&gt;.__subclasshook__()&lt;/code&gt; dunder method. The &lt;code&gt;FormalParserInterface&lt;/code&gt; would be updated to the following:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FormalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metaclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ABCMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@classmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__subclasshook__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;load_data_source&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;extract_text&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extract_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; 
                &lt;span class=&quot;bp&quot;&gt;NotImplemented&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PdfParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from a PDF.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides FormalParserInterface.load_data_source()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides FormalParserInterface.extract_text()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@FormalParserInterface&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmlParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from an email.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides FormalParserInterface.load_data_source()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text_from_email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A method defined only in EmlParser.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        Does not override FormalParserInterface.extract_text()&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;issubclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PdfParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FormalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# True&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;issubclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EmlParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FormalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Since you&amp;rsquo;ve used registration, you can see that &lt;code&gt;EmlParserNew&lt;/code&gt; is considered a virtual subclass of your &lt;code&gt;FormalParserInterface&lt;/code&gt; interface. This is not what you wanted since &lt;code&gt;EmlParserNew&lt;/code&gt; doesn&amp;rsquo;t override &lt;code&gt;.extract_text()&lt;/code&gt;. &lt;strong&gt;Please use caution with virtual subclass registration!&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;using-abstract-method-declaration&quot;&gt;Using Abstract Method Declaration&lt;/h3&gt;
&lt;p&gt;An &lt;strong&gt;abstract method&lt;/strong&gt; is a method that&amp;rsquo;s declared by the Python interface, but it may not have a useful implementation. The abstract method must be overridden by the concrete class that implements the interface in question.&lt;/p&gt;
&lt;p&gt;To create abstract methods in Python, you add the &lt;code&gt;@abc.abstractmethod&lt;/code&gt; decorator to the interface&amp;rsquo;s methods. In the next example, you update the &lt;code&gt;FormalParserInterface&lt;/code&gt; to include the abstract methods &lt;code&gt;.load_data_source()&lt;/code&gt; and &lt;code&gt;.extract_text()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FormalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metaclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ABCMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@classmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__subclasshook__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;load_data_source&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;extract_text&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subclass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extract_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; 
                &lt;span class=&quot;bp&quot;&gt;NotImplemented&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@abc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abstractmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Load in the data set&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;NotImplementedError&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@abc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abstractmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from the data set&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;NotImplementedError&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PdfParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FormalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from a PDF.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides FormalParserInterface.load_data_source()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides FormalParserInterface.extract_text()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmlParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FormalParserInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Extract text from an email.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_data_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Overrides FormalParserInterface.load_data_source()&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_text_from_email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A method defined only in EmlParser.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        Does not override FormalParserInterface.extract_text()&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the above example, you&amp;rsquo;ve finally created a formal interface that will raise errors when the abstract methods aren&amp;rsquo;t overridden. The &lt;code&gt;PdfParserNew&lt;/code&gt; instance, &lt;code&gt;pdf_parser&lt;/code&gt;, won&amp;rsquo;t raise any errors, as &lt;code&gt;PdfParserNew&lt;/code&gt; is correctly overriding the &lt;code&gt;FormalParserInterface&lt;/code&gt; abstract methods. However, &lt;code&gt;EmlParserNew&lt;/code&gt; will raise an error:&lt;/p&gt;
&lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pdf_parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PdfParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eml_parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EmlParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;real_python_interfaces.py&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;53&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;eml_interface&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EmlParserNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;Can&amp;#39;t instantiate abstract class EmlParserNew with abstract methods extract_text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, the &lt;a href=&quot;https://realpython.com/python-traceback/&quot;&gt;traceback&lt;/a&gt; message tells you that you haven&amp;rsquo;t overridden all the abstract methods. This is the behavior you expect when building a formal Python interface.&lt;/p&gt;
&lt;h2 id=&quot;interfaces-in-other-languages&quot;&gt;Interfaces in Other Languages&lt;/h2&gt;
&lt;p&gt;Interfaces appear in many programming languages, and their implementation varies greatly from language to language. In the next few sections, you&amp;rsquo;ll compare interfaces in Python to Java, C++, and Go.&lt;/p&gt;
&lt;h3 id=&quot;java&quot;&gt;Java&lt;/h3&gt;
&lt;p&gt;Unlike Python, &lt;a href=&quot;https://realpython.com/oop-in-python-vs-java/&quot;&gt;Java&lt;/a&gt; contains an &lt;code&gt;interface&lt;/code&gt; keyword. Keeping with the file parser example, you declare an interface in Java like so:&lt;/p&gt;
&lt;div class=&quot;highlight java&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FileParserInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Static fields, and abstract methods go here ...&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;loadDataSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you&amp;rsquo;ll create two concrete classes, &lt;code&gt;PdfParser&lt;/code&gt; and &lt;code&gt;EmlParser&lt;/code&gt;, to implement the &lt;code&gt;FileParserInterface&lt;/code&gt;. To do so, you must use the &lt;code&gt;implements&lt;/code&gt; keyword in the class definition, like so:&lt;/p&gt;
&lt;div class=&quot;highlight java&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmlParser&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FileParserInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;loadDataSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Code to load the data set&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

     &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Code to extract the text&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Continuing with your file parsing example, a fully-functional Java interface would look something like this:&lt;/p&gt;
&lt;div class=&quot;highlight java&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.util.*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.io.*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FileParser&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IOException&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// The main entry point&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FileParserInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;HashMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_contents&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;loadDataSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PdfParser&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FileParserInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;loadDataSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Code to load the data set&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Code to extract the text&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmlParser&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FileParserInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;loadDataSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Code to load the data set&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Code to extract the text&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, a Python interface gives you much more flexibility during creation than a Java interface does.&lt;/p&gt;
&lt;h3 id=&quot;c&quot;&gt;C++&lt;/h3&gt;
&lt;p&gt;Like Python, C++ uses abstract base classes to create interfaces. When defining an interface in C++, you use the keyword &lt;code&gt;virtual&lt;/code&gt; to describe a method that should be overwritten in the concrete class:&lt;/p&gt;
&lt;div class=&quot;highlight cpp&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FileParserInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loadDataSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you want to implement the interface, you&amp;rsquo;ll give the concrete class name, followed by a colon (&lt;code&gt;:&lt;/code&gt;), and then the name of the interface. The following example demonstrates C++ interface implementation:&lt;/p&gt;
&lt;div class=&quot;highlight cpp&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PdfParser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FileParserInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loadDataSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmlParser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FileParserInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loadDataSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A Python interface and a C++ interface have some similarities in that they both make use of abstract base classes to simulate interfaces.&lt;/p&gt;
&lt;h3 id=&quot;go&quot;&gt;Go&lt;/h3&gt;
&lt;p&gt;Although Go&amp;rsquo;s syntax is reminiscent of Python, the Go programming language contains an &lt;code&gt;interface&lt;/code&gt; keyword, like Java. Let&amp;rsquo;s create the &lt;code&gt;fileParserInterface&lt;/code&gt; in Go:&lt;/p&gt;
&lt;div class=&quot;highlight go&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fileParserInterface&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;loadDataSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;full_file_path&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A big difference between Python and Go is that Go doesn&amp;rsquo;t have classes. Rather, Go is similar to &lt;a href=&quot;https://realpython.com/build-python-c-extension-module/&quot;&gt;C&lt;/a&gt; in that it uses the &lt;code&gt;struct&lt;/code&gt; keyword to create structures. A &lt;strong&gt;structure&lt;/strong&gt; is similar to a class in that a structure contains data and methods. However, unlike a class, all of the data and methods are publicly accessed. The concrete structs in Go will be used to implement the &lt;code&gt;fileParserInterface&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example of how Go uses interfaces:&lt;/p&gt;
&lt;div class=&quot;highlight go&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fileParserInterface&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;loadDataSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;full_file_path&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pdfParser&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Data goes here ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;emlParser&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Data goes here ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pdfParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;loadDataSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Method definition ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pdfParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Method definition ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;emlParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;loadDataSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Method definition ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;emlParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;extractText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Method definition ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Main entrypoint&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Unlike a Python interface, a Go interface is created using structs and the explicit keyword &lt;code&gt;interface&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Python offers great flexibility when you&amp;rsquo;re creating interfaces. An informal Python interface is useful for small projects where you&amp;rsquo;re less likely to get confused as to what the return types of the methods are. As a project grows, the need for a &lt;strong&gt;formal Python interface&lt;/strong&gt; becomes more important as it becomes more difficult to infer return types. This ensures that the concrete class, which implements the interface, overwrites the abstract methods.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now you can:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Understand &lt;strong&gt;how interfaces work&lt;/strong&gt; and the caveats of creating a Python interface&lt;/li&gt;
&lt;li&gt;Understand the &lt;strong&gt;usefulness&lt;/strong&gt; of interfaces in a dynamic language like Python&lt;/li&gt;
&lt;li&gt;Implement &lt;strong&gt;formal and informal&lt;/strong&gt; interfaces in Python&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compare Python interfaces&lt;/strong&gt; to those in languages like Java, C++, and Go&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that you&amp;rsquo;ve become familiar with how to create a Python interface, add a Python interface to your next project to see its usefulness in action!&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python Command Line Arguments</title>
      <id>https://realpython.com/python-command-line-arguments/</id>
      <link href="https://realpython.com/python-command-line-arguments/"/>
      <updated>2020-02-05T14:00:00+00:00</updated>
      <summary>Python command line arguments are the key to converting your programs into useful and enticing tools that are ready to be used in the terminal of your operating system. In this step-by-step tutorial, you&#39;ll learn their origins, standards, and basics, and how to implement them in your program.</summary>
      <content type="html">
        &lt;p&gt;Adding the capability of processing &lt;strong&gt;Python command line arguments&lt;/strong&gt; provides a user-friendly interface to your text-based command line program. It&amp;rsquo;s similar to what a graphical user interface is for a visual application that&amp;rsquo;s manipulated by graphical elements or widgets.&lt;/p&gt;
&lt;p&gt;Python exposes a mechanism to capture and extract your Python command line arguments. These values can be used to modify the behavior of a program. For example, if your program processes data read from a file, then you can pass the name of the file to your program, rather than hard-coding the value in your source code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you&amp;rsquo;ll know:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The origins&lt;/strong&gt; of Python command line arguments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The underlying support&lt;/strong&gt; for Python command line arguments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The standards&lt;/strong&gt; guiding the design of a command line interface&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The basics&lt;/strong&gt; to manually customize and handle Python command line arguments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The libraries&lt;/strong&gt; available in Python to ease the development of a complex command line interface&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want a user-friendly way to supply Python command line arguments to your program without importing a dedicated library, or if you want to better understand the common basis for the existing libraries that are dedicated to building the Python command line interface, then keep on reading!&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-mastery-course&quot; data-focus=&quot;false&quot;&gt;5 Thoughts On Python Mastery&lt;/a&gt;, a free course for Python developers that shows you the roadmap and the mindset you&#39;ll need to take your Python skills to the next level.&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-command-line-interface&quot;&gt;The Command Line Interface&lt;/h2&gt;
&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Command-line_interface&quot;&gt;&lt;strong&gt;command line interface (CLI)&lt;/strong&gt;&lt;/a&gt; provides a way for a user to interact with a program running in a text-based &lt;a href=&quot;https://en.wikipedia.org/wiki/Shell_%28computing%29&quot;&gt;shell&lt;/a&gt; interpreter. Some examples of shell interpreters are &lt;a href=&quot;https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29&quot;&gt;Bash&lt;/a&gt; on Linux or &lt;a href=&quot;https://en.wikipedia.org/wiki/Cmd.exe&quot;&gt;Command Prompt&lt;/a&gt; on Windows. A command line interface is enabled by the shell interpreter that exposes a &lt;a href=&quot;https://en.wikipedia.org/wiki/Command-line_interface#Command_prompt&quot;&gt;command prompt&lt;/a&gt;. It can be characterized by the following elements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;command&lt;/strong&gt; or program&lt;/li&gt;
&lt;li&gt;Zero or more command line &lt;strong&gt;arguments&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;output&lt;/strong&gt; representing the result of the command&lt;/li&gt;
&lt;li&gt;Textual documentation referred to as &lt;strong&gt;usage&lt;/strong&gt; or &lt;strong&gt;help&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not every command line interface may provide all these elements, but this list isn&amp;rsquo;t exhaustive, either. The complexity of the command line ranges from the ability to pass a single argument, to numerous arguments and options, much like a &lt;a href=&quot;https://en.wikipedia.org/wiki/Domain-specific_language&quot;&gt;Domain Specific Language&lt;/a&gt;. For example, some programs may launch web documentation from the command line or start an &lt;a href=&quot;https://docs.python.org/tutorial/interpreter.html#interactive-mode&quot;&gt;interactive shell interpreter&lt;/a&gt; like Python.&lt;/p&gt;
&lt;p&gt;The two following examples with the Python command illustrates the description of a command line interface:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python -c &lt;span class=&quot;s2&quot;&gt;&amp;quot;print(&amp;#39;Real Python&amp;#39;)&amp;quot;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Real Python&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this first example, the Python interpreter takes option &lt;code&gt;-c&lt;/code&gt; for &lt;strong&gt;command&lt;/strong&gt;, which says to execute the Python command line arguments following the option &lt;code&gt;-c&lt;/code&gt; as a Python program.&lt;/p&gt;
&lt;p&gt;Another example shows how to invoke Python with &lt;code&gt;-h&lt;/code&gt; to display the help:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python -h
&lt;span class=&quot;go&quot;&gt;usage: python3 [option] ... [-c cmd | -m mod | file | -] [arg] ...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Options and arguments (and corresponding environment variables):&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-b     : issue warnings about str(bytes_instance), str(bytearray_instance)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;         and comparing bytes/bytearray with str. (-bb: issue errors)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[ ... complete help text not shown ... ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Try this out in your terminal to see the complete help documentation.&lt;/p&gt;
&lt;h2 id=&quot;the-c-legacy&quot;&gt;The C Legacy&lt;/h2&gt;
&lt;p&gt;Python command line arguments directly inherit from the &lt;a href=&quot;https://realpython.com/build-python-c-extension-module/&quot;&gt;C&lt;/a&gt; programming language. As &lt;a href=&quot;https://en.wikipedia.org/wiki/Guido_van_Rossum&quot;&gt;Guido Van Rossum&lt;/a&gt; wrote in &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.4180&quot;&gt;An Introduction to Python for Unix/C Programmers&lt;/a&gt; in 1993, C had a strong influence on Python. Guido mentions the definitions of literals, identifiers, operators, and statements like &lt;code&gt;break&lt;/code&gt;, &lt;code&gt;continue&lt;/code&gt;, or &lt;code&gt;return&lt;/code&gt;. The use of Python command line arguments is also strongly influenced by the C language.&lt;/p&gt;
&lt;p&gt;To illustrate the similarities, consider the following C program:&lt;/p&gt;
&lt;div class=&quot;highlight c&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// main.c&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Arguments count: %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Argument %6d: %s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Line 4 defines &lt;a href=&quot;https://en.wikipedia.org/wiki/Entry_point#C_and_C++&quot;&gt;&lt;code&gt;main()&lt;/code&gt;&lt;/a&gt;, which is the entry point of a C program. Take good note of the parameters:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;argc&lt;/code&gt;&lt;/strong&gt; is an integer representing the number of arguments of the program.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;argv&lt;/code&gt;&lt;/strong&gt; is an array of pointers to characters containing the name of the program in the first element of the array, followed by the arguments of the program, if any, in the remaining elements of the array.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can compile the code above on Linux with &lt;code&gt;gcc -o main main.c&lt;/code&gt;, then execute with &lt;code&gt;./main&lt;/code&gt; to obtain the following:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; gcc -o main main.c
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ./main
&lt;span class=&quot;go&quot;&gt;Arguments count: 1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      0: ./main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Unless explicitly expressed at the command line with the option &lt;code&gt;-o&lt;/code&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/A.out&quot;&gt;&lt;code&gt;a.out&lt;/code&gt;&lt;/a&gt; is the default name of the executable generated by the &lt;strong&gt;gcc&lt;/strong&gt; compiler. It stands for &lt;strong&gt;assembler output&lt;/strong&gt; and is reminiscent of the executables that were generated on older UNIX systems. Observe that the name of the executable &lt;code&gt;./main&lt;/code&gt; is the sole argument.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s spice up this example by passing a few Python command line arguments to the same program:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ./main Python Command Line Arguments
&lt;span class=&quot;go&quot;&gt;Arguments count: 5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      0: ./main&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      1: Python&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      2: Command&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      3: Line&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      4: Arguments&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output shows that the number of arguments is &lt;code&gt;5&lt;/code&gt;, and the list of arguments includes the name of the program, &lt;code&gt;main&lt;/code&gt;, followed by each word of the phrase &lt;code&gt;&quot;Python Command Line Arguments&quot;&lt;/code&gt;, which you passed at the command line.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;code&gt;argc&lt;/code&gt; stands for &lt;strong&gt;argument count&lt;/strong&gt;, while &lt;code&gt;argv&lt;/code&gt; stands for &lt;strong&gt;argument vector&lt;/strong&gt;. To learn more, check out &lt;a href=&quot;https://en.wikibooks.org/wiki/A_Little_C_Primer/C_Command_Line_Arguments&quot;&gt;A Little C Primer/C Command Line Arguments&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The compilation of &lt;code&gt;main.c&lt;/code&gt; assumes that you used a Linux or a Mac OS system. On Windows, you can also compile this C program with one of the following options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux&quot;&gt;&lt;strong&gt;Windows Subsystem for Linux (WSL):&lt;/strong&gt;&lt;/a&gt; It&amp;rsquo;s available in a few Linux distributions, like &lt;a href=&quot;https://ubuntu.com/&quot;&gt;Ubuntu&lt;/a&gt;, &lt;a href=&quot;https://www.opensuse.org/&quot;&gt;OpenSUSE&lt;/a&gt;, and &lt;a href=&quot;https://www.debian.org/&quot;&gt;Debian&lt;/a&gt;, among others. You can install it from the Microsoft Store.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019&quot;&gt;&lt;strong&gt;Windows Build Tools:&lt;/strong&gt;&lt;/a&gt; This includes the Windows command line build tools, the Microsoft C/C++ compiler &lt;a href=&quot;https://docs.microsoft.com/en-us/cpp/build/walkthrough-compiling-a-cpp-cli-program-on-the-command-line?view=vs-2019&quot;&gt;&lt;code&gt;cl.exe&lt;/code&gt;&lt;/a&gt;, and a compiler front end named &lt;a href=&quot;https://en.wikipedia.org/wiki/Clang&quot;&gt;&lt;code&gt;clang.exe&lt;/code&gt;&lt;/a&gt; for C/C++.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://visualstudio.microsoft.com/downloads/&quot;&gt;&lt;strong&gt;Microsoft Visual Studio:&lt;/strong&gt;&lt;/a&gt; This is the main Microsoft integrated development environment (IDE). To learn more about IDEs that can be used for both Python and C on various operating systems, including Windows, check out &lt;a href=&quot;https://realpython.com/python-ides-code-editors-guide/&quot;&gt;Python IDEs and Code Editors (Guide)&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://mingw-w64.org&quot;&gt;&lt;strong&gt;mingw-64 project:&lt;/strong&gt;&lt;/a&gt; This supports the &lt;a href=&quot;https://gcc.gnu.org/&quot;&gt;GCC compiler&lt;/a&gt; on Windows.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;rsquo;ve installed Microsoft Visual Studio or the Windows Build Tools, then you can compile &lt;code&gt;main.c&lt;/code&gt; as follows:&lt;/p&gt;
&lt;div class=&quot;highlight doscon&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;C:/&amp;gt;&lt;/span&gt;cl main.c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You&amp;rsquo;ll obtain an executable named &lt;code&gt;main.exe&lt;/code&gt; that you can start with:&lt;/p&gt;
&lt;div class=&quot;highlight doscon&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;C:/&amp;gt;&lt;/span&gt;main
&lt;span class=&quot;go&quot;&gt;Arguments count: 1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      0: main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You could implement a Python program, &lt;code&gt;main.py&lt;/code&gt;, that&amp;rsquo;s equivalent to the C program, &lt;code&gt;main.c&lt;/code&gt;, you saw above:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# main.py&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Arguments count: {len(sys.argv)}&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Argument &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{i:&amp;gt;6}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{arg}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You don&amp;rsquo;t see an &lt;code&gt;argc&lt;/code&gt; variable like in the C code example. It doesn&amp;rsquo;t exist in Python because &lt;code&gt;sys.argv&lt;/code&gt; is sufficient. You can parse the Python command line arguments in &lt;code&gt;sys.argv&lt;/code&gt; without having to know the length of the list, and you can call the built-in &lt;a href=&quot;https://docs.python.org/library/functions.html#len&quot;&gt;&lt;code&gt;len()&lt;/code&gt;&lt;/a&gt; if the number of arguments is needed by your program.&lt;/p&gt;
&lt;p&gt;Also, note that &lt;a href=&quot;https://docs.python.org/library/functions.html#enumerate&quot;&gt;&lt;code&gt;enumerate()&lt;/code&gt;&lt;/a&gt;, when applied to an iterable, returns an &lt;code&gt;enumerate&lt;/code&gt; object that can emit pairs associating the index of an element in &lt;code&gt;sys.arg&lt;/code&gt; to its corresponding value. This allows looping through the content of &lt;code&gt;sys.argv&lt;/code&gt; without having to maintain a counter for the index in the list.&lt;/p&gt;
&lt;p&gt;Execute &lt;code&gt;main.py&lt;/code&gt; as follows:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python main.py Python Command Line Arguments
&lt;span class=&quot;go&quot;&gt;Arguments count: 5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      0: main.py&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      1: Python&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      2: Command&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      3: Line&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      4: Arguments&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;sys.argv&lt;/code&gt; contains the same information as in the C program:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The name of the program&lt;/strong&gt; &lt;code&gt;main.py&lt;/code&gt; is the first item of the list.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The arguments&lt;/strong&gt; &lt;code&gt;Python&lt;/code&gt;, &lt;code&gt;Command&lt;/code&gt;, &lt;code&gt;Line&lt;/code&gt;, and &lt;code&gt;Arguments&lt;/code&gt; are the remaining elements in the list.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this short introduction into a few arcane aspects of the C language, you&amp;rsquo;re now armed with some valuable knowledge to further grasp Python command line arguments.&lt;/p&gt;
&lt;h2 id=&quot;two-utilities-from-the-unix-world&quot;&gt;Two Utilities From the Unix World&lt;/h2&gt;
&lt;p&gt;To use Python command line arguments in this tutorial, you&amp;rsquo;ll implement some partial features of two utilities from the Unix ecosystem:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Sha1sum&quot;&gt;sha1sum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Seq_%28Unix%29&quot;&gt;seq&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You&amp;rsquo;ll gain some familiarity with these Unix tools in the following sections.&lt;/p&gt;
&lt;h3 id=&quot;sha1sum&quot;&gt;&lt;code&gt;sha1sum&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;sha1sum&lt;/code&gt; calculates &lt;a href=&quot;https://en.wikipedia.org/wiki/SHA-1&quot;&gt;SHA-1&lt;/a&gt; &lt;a href=&quot;https://en.wikipedia.org/wiki/Cryptographic_hash_function&quot;&gt;hashes&lt;/a&gt;, and it&amp;rsquo;s often used to verify the integrity of files. For a given input, a &lt;strong&gt;hash function&lt;/strong&gt; always returns the same value. Any minor changes in the input will result in a different hash value. Before you use the utility with concrete parameters, you may try to display the help:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sha1sum --help
&lt;span class=&quot;go&quot;&gt;Usage: sha1sum [OPTION]... [FILE]...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Print or check SHA1 (160-bit) checksums.&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;With no FILE, or when FILE is -, read standard input.&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;  -b, --binary         read in binary mode&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  -c, --check          read SHA1 sums from the FILEs and check them&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;      --tag            create a BSD-style checksum&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  -t, --text           read in text mode (default)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  -z, --zero           end each output line with NUL, not newline,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;                       and disable file name escaping&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[ ... complete help text not shown ... ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Displaying the help of a command line program is a common feature exposed in the command line interface.&lt;/p&gt;
&lt;p&gt;To calculate the SHA-1 hash value of the content of a file, you proceed as follows:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sha1sum main.c
&lt;span class=&quot;go&quot;&gt;125a0f900ff6f164752600550879cbfabb098bc3  main.c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The result shows the SHA-1 hash value as the first field and the name of the file as the second field. The command can take more than one file as arguments:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sha1sum main.c main.py
&lt;span class=&quot;go&quot;&gt;125a0f900ff6f164752600550879cbfabb098bc3  main.c&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;d84372fc77a90336b6bb7c5e959bcb1b24c608b4  main.py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Thanks to the wildcards expansion feature of the Unix terminal, it&amp;rsquo;s also possible to provide Python command line arguments with wildcard characters. One such a character is the asterisk or star (&lt;code&gt;*&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sha1sum main.*
&lt;span class=&quot;go&quot;&gt;3f6d5274d6317d580e2ffc1bf52beee0d94bf078  main.c&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;f41259ea5835446536d2e71e566075c1c1bfc111  main.py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The shell converts &lt;code&gt;main.*&lt;/code&gt; to &lt;code&gt;main.c&lt;/code&gt; and &lt;code&gt;main.py&lt;/code&gt;, which are the two files matching the pattern &lt;code&gt;main.*&lt;/code&gt; in the current directory, and passes them to &lt;code&gt;sha1sum&lt;/code&gt;. The program calculates the &lt;strong&gt;SHA1 hash&lt;/strong&gt; of each of the files in the argument list. You&amp;rsquo;ll see that, on Windows, the behavior is different. Windows has no wildcard expansion, so the program may have to accommodate for that. Your implementation may need to expand wildcards internally.&lt;/p&gt;
&lt;p&gt;Without any argument, &lt;code&gt;sha1sum&lt;/code&gt; reads from the standard input. You can feed data to the program by typing characters on the keyboard. The input may incorporate any characters, including the carriage return &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;. To terminate the input, you must signal the &lt;a href=&quot;https://en.wikipedia.org/wiki/End-of-file&quot;&gt;end of file&lt;/a&gt; with &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;, followed by the sequence &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-d&quot;&gt;D&lt;/kbd&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sha1sum
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Real&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Python&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;87263a73c98af453d68ee4aab61576b331f8d9d6  -&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You first enter the name of the program, &lt;code&gt;sha1sum&lt;/code&gt;, followed by &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;, and then &lt;code&gt;Real&lt;/code&gt; and &lt;code&gt;Python&lt;/code&gt;, each also followed by &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;. To close the input stream, you type &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-d&quot;&gt;D&lt;/kbd&gt;&lt;/span&gt;. The result is the value of the SHA1 hash generated for the text &lt;code&gt;Real\nPython\n&lt;/code&gt;. The name of the file is &lt;code&gt;-&lt;/code&gt;. This is a convention to indicate the standard input. The hash value is the same when you execute the following commands:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python -c &lt;span class=&quot;s2&quot;&gt;&amp;quot;print(&amp;#39;Real\nPython\n&amp;#39;, end=&amp;#39;&amp;#39;)&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; sha1sum
&lt;span class=&quot;go&quot;&gt;87263a73c98af453d68ee4aab61576b331f8d9d6  -&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python -c &lt;span class=&quot;s2&quot;&gt;&amp;quot;print(&amp;#39;Real\nPython&amp;#39;)&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; sha1sum
&lt;span class=&quot;go&quot;&gt;87263a73c98af453d68ee4aab61576b331f8d9d6  -&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Real\nPython\n&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; sha1sum
&lt;span class=&quot;go&quot;&gt;87263a73c98af453d68ee4aab61576b331f8d9d6  -&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Up next, you&amp;rsquo;ll read a short description of &lt;code&gt;seq&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;seq&quot;&gt;&lt;code&gt;seq&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Seq_%28Unix%29&quot;&gt;&lt;code&gt;seq&lt;/code&gt;&lt;/a&gt; generates a &lt;strong&gt;sequence&lt;/strong&gt; of numbers. In its most basic form, like generating the sequence from 1 to 5, you can execute the following:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; seq &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To get an overview of the possibilities exposed by &lt;code&gt;seq&lt;/code&gt;, you can display the help at the command line:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; seq --help
&lt;span class=&quot;go&quot;&gt;Usage: seq [OPTION]... LAST&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  or:  seq [OPTION]... FIRST LAST&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  or:  seq [OPTION]... FIRST INCREMENT LAST&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Print numbers from FIRST to LAST, in steps of INCREMENT.&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;Mandatory arguments to long options are mandatory for short options too.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  -f, --format=FORMAT      use printf style floating-point FORMAT&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  -s, --separator=STRING   use STRING to separate numbers (default: \n)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  -w, --equal-width        equalize width by padding with leading zeroes&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;      --help     display this help and exit&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;      --version  output version information and exit&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[ ... complete help text not shown ... ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For this tutorial, you&amp;rsquo;ll write a few simplified variants of &lt;code&gt;sha1sum&lt;/code&gt; and &lt;code&gt;seq&lt;/code&gt;. In each example, you&amp;rsquo;ll learn a different facet or combination of features about Python command line arguments.&lt;/p&gt;
&lt;p&gt;On Mac OS and Linux, &lt;code&gt;sha1sum&lt;/code&gt; and &lt;code&gt;seq&lt;/code&gt; should come pre-installed, though the features and the help information may sometimes differ slightly between systems or distributions. If you&amp;rsquo;re using Windows 10, then the most convenient method is to run &lt;code&gt;sha1sum&lt;/code&gt; and &lt;code&gt;seq&lt;/code&gt; in a Linux environment installed on the &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/wsl/install-win10&quot;&gt;WSL&lt;/a&gt;. If you don&amp;rsquo;t have access to a terminal exposing the standard Unix utilities, then you may have access to online terminals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Create&lt;/strong&gt; a free account on &lt;a href=&quot;https://www.pythonanywhere.com&quot;&gt;PythonAnywhere&lt;/a&gt; and start a Bash Console.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create&lt;/strong&gt; a temporary Bash terminal on &lt;a href=&quot;https://repl.it/languages&quot;&gt;repl.it&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are two examples, and you may find others.&lt;/p&gt;
&lt;h2 id=&quot;the-sysargv-array&quot;&gt;The &lt;code&gt;sys.argv&lt;/code&gt; Array&lt;/h2&gt;
&lt;p&gt;Before exploring some accepted conventions and discovering how to handle Python command line arguments, you need to know that the underlying support for all Python command line arguments is provided by &lt;a href=&quot;https://docs.python.org/library/sys.html?highlight=sys%20argv#sys.argv&quot;&gt;&lt;code&gt;sys.argv&lt;/code&gt;&lt;/a&gt;. The examples in the following sections show you how to handle the Python command line arguments stored in &lt;code&gt;sys.argv&lt;/code&gt; and to overcome typical issues that occur when you try to access them. You&amp;rsquo;ll learn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to &lt;strong&gt;access&lt;/strong&gt; the content of &lt;code&gt;sys.argv&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;How to &lt;strong&gt;mitigate&lt;/strong&gt; the side effects of the global nature of &lt;code&gt;sys.argv&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;How to &lt;strong&gt;process&lt;/strong&gt; whitespaces in Python command line arguments&lt;/li&gt;
&lt;li&gt;How to &lt;strong&gt;handle&lt;/strong&gt; errors while accessing Python command line arguments&lt;/li&gt;
&lt;li&gt;How to &lt;strong&gt;ingest&lt;/strong&gt; the original format of the Python command line arguments passed by bytes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s get started!&lt;/p&gt;
&lt;h3 id=&quot;displaying-arguments&quot;&gt;Displaying Arguments&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;sys&lt;/code&gt; module exposes an array named &lt;code&gt;argv&lt;/code&gt; that includes the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;argv[0]&lt;/code&gt;&lt;/strong&gt; contains the name of the current Python program.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;argv[1:]&lt;/code&gt;&lt;/strong&gt;, the rest of the list, contains any and all Python command line arguments passed to the program.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following example demonstrates the content of &lt;code&gt;sys.argv&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# argv.py&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Name of the script      : {sys.argv[0]=}&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Arguments of the script : {sys.argv[1:]=}&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here&amp;rsquo;s how this code works:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Line 2&lt;/strong&gt; imports the internal Python module &lt;a href=&quot;https://docs.python.org/library/sys.html&quot;&gt;&lt;code&gt;sys&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 4&lt;/strong&gt; extracts the name of the program by accessing the first element of the list &lt;code&gt;sys.argv&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 5&lt;/strong&gt; displays the Python command line arguments by fetching all the remaining elements of the list &lt;code&gt;sys.argv&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The &lt;a href=&quot;https://realpython.com/python-f-strings/&quot;&gt;f-string&lt;/a&gt; syntax used in &lt;code&gt;argv.py&lt;/code&gt; leverages the new debugging specifier in Python 3.8. To read more about this new f-string feature and others, check out &lt;a href=&quot;https://realpython.com/python38-new-features/&quot;&gt;Cool New Features in Python 3.8&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If your Python version is less than 3.8, then simply remove the equals sign (&lt;code&gt;=&lt;/code&gt;) in both f-strings to allow the program to execute successfully. The output will only display the value of the variables, not their names.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Execute the script &lt;code&gt;argv.py&lt;/code&gt; above with a list of arbitrary arguments as follows:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python argv.py un deux trois quatre
&lt;span class=&quot;go&quot;&gt;Name of the script      : sys.argv[0]=&amp;#39;argv.py&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Arguments of the script : sys.argv[1:]=[&amp;#39;un&amp;#39;, &amp;#39;deux&amp;#39;, &amp;#39;trois&amp;#39;, &amp;#39;quatre&amp;#39;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output confirms that the content of &lt;code&gt;sys.argv[0]&lt;/code&gt; is the Python script &lt;code&gt;argv.py&lt;/code&gt;, and that the remaining elements of the &lt;code&gt;sys.argv&lt;/code&gt; list contains the arguments of the script, &lt;code&gt;[&#39;un&#39;, &#39;deux&#39;, &#39;trois&#39;, &#39;quatre&#39;]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To summarize, &lt;code&gt;sys.argv&lt;/code&gt; contains all the &lt;code&gt;argv.py&lt;/code&gt; Python command line arguments. When the Python interpreter executes a Python program, it parses the command line and populates &lt;code&gt;sys.argv&lt;/code&gt; with the arguments.&lt;/p&gt;
&lt;h3 id=&quot;reversing-the-first-argument&quot;&gt;Reversing the First Argument&lt;/h3&gt;
&lt;p&gt;Now that you have enough background on &lt;code&gt;sys.argv&lt;/code&gt;, you&amp;rsquo;re going to operate on arguments passed at the command line. The example &lt;code&gt;reverse.py&lt;/code&gt; reverses the first argument passed at the command line:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# reverse.py&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In &lt;code&gt;reverse.py&lt;/code&gt; the process to reverse the first argument is performed with the following steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Line 5&lt;/strong&gt; fetches the first argument of the program stored at index &lt;code&gt;1&lt;/code&gt; of &lt;code&gt;sys.argv&lt;/code&gt;. Remember that the program name is stored at index &lt;code&gt;0&lt;/code&gt; of &lt;code&gt;sys.argv&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 6&lt;/strong&gt; prints the reversed string. &lt;code&gt;args[::-1]&lt;/code&gt; is a Pythonic way to use a slice operation to &lt;a href=&quot;https://stackoverflow.com/questions/3705670/best-way-to-create-a-reversed-list-in-python/3705676#3705676&quot;&gt;reverse a list&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You execute the script as follows:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python reverse.py &lt;span class=&quot;s2&quot;&gt;&amp;quot;Real Python&amp;quot;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;nohtyP laeR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As expected, &lt;code&gt;reverse.py&lt;/code&gt; operates on &lt;code&gt;&quot;Real Python&quot;&lt;/code&gt; and reverses the only argument to output &lt;code&gt;&quot;nohtyP laeR&quot;&lt;/code&gt;. Note that surrounding the multi-word string &lt;code&gt;&quot;Real Python&quot;&lt;/code&gt; with quotes ensures that the interpreter handles it as a unique argument, instead of two arguments. You&amp;rsquo;ll delve into &lt;strong&gt;argument separators&lt;/strong&gt; in a later &lt;a href=&quot;#escaping-whitespace-characters&quot;&gt;section&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;mutating-sysargv&quot;&gt;Mutating &lt;code&gt;sys.argv&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;sys.argv&lt;/code&gt; is &lt;strong&gt;globally available&lt;/strong&gt; to your running Python program. All modules imported during the execution of the process have direct access to &lt;code&gt;sys.argv&lt;/code&gt;. This global access might be convenient, but &lt;code&gt;sys.argv&lt;/code&gt; isn&amp;rsquo;t immutable. You may want to implement a more reliable mechanism to expose program arguments to different modules in your Python program, especially in a complex program with multiple files.&lt;/p&gt;
&lt;p&gt;Observe what happens if you tamper with &lt;code&gt;sys.argv&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# argv_pop.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You invoke &lt;a href=&quot;https://docs.python.org/tutorial/datastructures.html#more-on-lists&quot;&gt;&lt;code&gt;.pop()&lt;/code&gt;&lt;/a&gt; to remove and return the last item in &lt;code&gt;sys.argv&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Execute the script above:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python argv_pop.py un deux trois quatre
&lt;span class=&quot;go&quot;&gt;[&amp;#39;argv_pop.py&amp;#39;, &amp;#39;un&amp;#39;, &amp;#39;deux&amp;#39;, &amp;#39;trois&amp;#39;, &amp;#39;quatre&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;argv_pop.py&amp;#39;, &amp;#39;un&amp;#39;, &amp;#39;deux&amp;#39;, &amp;#39;trois&amp;#39;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice that the fourth argument is no longer included in &lt;code&gt;sys.argv&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In a short script, you can safely rely on the global access to &lt;code&gt;sys.argv&lt;/code&gt;, but in a larger program, you may want to store arguments in a separate variable. The previous example could be modified as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# argv_var_pop.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This time, although &lt;code&gt;sys.argv&lt;/code&gt; lost its last element, &lt;code&gt;args&lt;/code&gt; has been safely preserved. &lt;code&gt;args&lt;/code&gt; isn&amp;rsquo;t global, and you can pass it around to parse the arguments per the logic of your program. The Python package manager, &lt;code&gt;pip&lt;/code&gt;, uses this &lt;a href=&quot;https://github.com/pypa/pip/blob/ce46f8524e194ea81c47dbf8a547698f12e61329/src/pip/_internal/__init__.py#L53&quot;&gt;approach&lt;/a&gt;. Here&amp;rsquo;s a short excerpt of the &lt;code&gt;pip&lt;/code&gt; source code:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this snippet of code taken from the &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt; source code, &lt;code&gt;main()&lt;/code&gt; saves into &lt;code&gt;args&lt;/code&gt; the slice of &lt;code&gt;sys.argv&lt;/code&gt; that contains only the arguments and not the file name. &lt;code&gt;sys.argv&lt;/code&gt; remains untouched, and &lt;code&gt;args&lt;/code&gt; isn&amp;rsquo;t impacted by any inadvertent changes to &lt;code&gt;sys.argv&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;escaping-whitespace-characters&quot;&gt;Escaping Whitespace Characters&lt;/h3&gt;
&lt;p&gt;In the &lt;code&gt;reverse.py&lt;/code&gt; example you saw &lt;a href=&quot;#reversing-the-first-argument&quot;&gt;earlier&lt;/a&gt;, the first and only argument is &lt;code&gt;&quot;Real Python&quot;&lt;/code&gt;, and the result is &lt;code&gt;&quot;nohtyP laeR&quot;&lt;/code&gt;. The argument includes a whitespace separator between &lt;code&gt;&quot;Real&quot;&lt;/code&gt; and &lt;code&gt;&quot;Python&quot;&lt;/code&gt;, and it needs to be escaped.&lt;/p&gt;
&lt;p&gt;On Linux, whitespaces can be escaped by doing one of the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Surrounding&lt;/strong&gt; the arguments with single quotes (&lt;code&gt;&#39;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Surrounding&lt;/strong&gt; the arguments with double quotes (&lt;code&gt;&quot;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prefixing&lt;/strong&gt; each space with a backslash (&lt;code&gt;\&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Without one of the escape solutions, &lt;code&gt;reverse.py&lt;/code&gt; stores two arguments, &lt;code&gt;&quot;Real&quot;&lt;/code&gt; in &lt;code&gt;sys.argv[1]&lt;/code&gt; and &lt;code&gt;&quot;Python&quot;&lt;/code&gt; in &lt;code&gt;sys.argv[2]&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python reverse.py Real Python
&lt;span class=&quot;go&quot;&gt;laeR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output above shows that the script only reverses &lt;code&gt;&quot;Real&quot;&lt;/code&gt; and that &lt;code&gt;&quot;Python&quot;&lt;/code&gt; is ignored. To ensure both arguments are stored, you&amp;rsquo;d need to surround the overall string with double quotes (&lt;code&gt;&quot;&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;You can also use a backslash (&lt;code&gt;\&lt;/code&gt;) to escape the whitespace:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python reverse.py Real&lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;Python
&lt;span class=&quot;go&quot;&gt;nohtyP laeR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With the backslash (&lt;code&gt;\&lt;/code&gt;), the command shell exposes a unique argument to Python, and then to &lt;code&gt;reverse.py&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In Unix shells, the &lt;a href=&quot;https://en.wikipedia.org/wiki/Internal_field_separator&quot;&gt;internal field separator (IFS)&lt;/a&gt; defines characters used as &lt;strong&gt;delimiters&lt;/strong&gt;. The content of the shell variable, &lt;code&gt;IFS&lt;/code&gt;, can be displayed by running the following command:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;%q\n&amp;quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$IFS&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39; \t\n&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From the result above, &lt;code&gt;&#39; \t\n&#39;&lt;/code&gt;, you identify three delimiters:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Space&lt;/strong&gt; (&lt;code&gt;&#39; &#39;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tab&lt;/strong&gt; (&lt;code&gt;\t&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Newline&lt;/strong&gt; (&lt;code&gt;\n&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Prefixing a space with a backslash (&lt;code&gt;\&lt;/code&gt;) bypasses the default behavior of the space as a delimiter in the string &lt;code&gt;&quot;Real Python&quot;&lt;/code&gt;. This results in one block of text as intended, instead of two.&lt;/p&gt;
&lt;p&gt;Note that, on Windows, the whitespace interpretation can be managed by using a combination of double quotes. It&amp;rsquo;s slightly counterintuitive because, in the Windows terminal, a double quote (&lt;code&gt;&quot;&lt;/code&gt;) is interpreted as a switch to disable and subsequently to enable special characters like &lt;strong&gt;space&lt;/strong&gt;, &lt;strong&gt;tab&lt;/strong&gt;, or &lt;strong&gt;pipe&lt;/strong&gt; (&lt;code&gt;|&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;As a result, when you surround more than one string with double quotes, the Windows terminal interprets the first double quote as a command to &lt;strong&gt;ignore special characters&lt;/strong&gt; and the second double quote as one to &lt;strong&gt;interpret special characters&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;With this information in mind, it&amp;rsquo;s safe to assume that surrounding more than one string with double quotes will give you the expected behavior, which is to expose the group of strings as a single argument. To confirm this peculiar effect of the double quote on the Windows command line, observe the following two examples:&lt;/p&gt;
&lt;div class=&quot;highlight doscon&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;C:/&amp;gt;&lt;/span&gt;python reverse.py &lt;span class=&quot;s2&quot;&gt;&amp;quot;Real Python&amp;quot;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;nohtyP laeR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the example above, you can intuitively deduce that &lt;code&gt;&quot;Real Python&quot;&lt;/code&gt; is interpreted as a single argument. However, realize what occurs when you use a single double quote:&lt;/p&gt;
&lt;div class=&quot;highlight doscon&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;C:/&amp;gt;&lt;/span&gt;python reverse.py &lt;span class=&quot;s2&quot;&gt;&amp;quot;Real Python&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;nohtyP laeR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The command prompt passes the whole string &lt;code&gt;&quot;Real Python&quot;&lt;/code&gt; as a single argument, in the same manner as if the argument was &lt;code&gt;&quot;Real Python&quot;&lt;/code&gt;. In reality, the Windows command prompt sees the unique double quote as a switch to disable the behavior of the whitespaces as separators and passes anything following the double quote as a unique argument.&lt;/p&gt;
&lt;p&gt;For more information on the effects of double quotes in the Windows terminal, check out &lt;a href=&quot;http://www.windowsinspired.com/understanding-the-command-line-string-and-arguments-received-by-a-windows-program/&quot;&gt;A Better Way To Understand Quoting and Escaping of Windows Command Line Arguments&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;handling-errors&quot;&gt;Handling Errors&lt;/h3&gt;
&lt;p&gt;Python command line arguments are &lt;strong&gt;loose strings&lt;/strong&gt;. Many things can go wrong, so it&amp;rsquo;s a good idea to provide the users of your program with some guidance in the event they pass incorrect arguments at the command line. For example, &lt;code&gt;reverse.py&lt;/code&gt; expects one argument, and if you omit it, then you get an error:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python reverse.py
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;  File &amp;quot;reverse.py&amp;quot;, line 5, in &amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;    arg = sys.argv[1]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;IndexError: list index out of range&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The Python &lt;a href=&quot;https://realpython.com/python-exceptions/&quot;&gt;exception&lt;/a&gt; &lt;code&gt;IndexError&lt;/code&gt; is raised, and the corresponding &lt;a href=&quot;https://realpython.com/python-traceback/&quot;&gt;traceback&lt;/a&gt; shows that the error is caused by the expression &lt;code&gt;arg = sys.argv[1]&lt;/code&gt;. The message of the exception is &lt;code&gt;list index out of range&lt;/code&gt;. You didn&amp;rsquo;t pass an argument at the command line, so there&amp;rsquo;s nothing in the list &lt;code&gt;sys.argv&lt;/code&gt; at index &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is a common pattern that can be addressed in a few different ways. For this initial example, you&amp;rsquo;ll keep it brief by including the expression &lt;code&gt;arg = sys.argv[1]&lt;/code&gt; in a &lt;code&gt;try&lt;/code&gt; block. Modify the code as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# reverse_exc.py&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;IndexError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Usage: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sys.argv[0]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;lt;string_to_reverse&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The expression on line 4 is included in a &lt;code&gt;try&lt;/code&gt; block. Line 8 raises the built-in exception &lt;a href=&quot;https://docs.python.org/library/exceptions.html#SystemExit&quot;&gt;&lt;code&gt;SystemExit&lt;/code&gt;&lt;/a&gt;. If no argument is passed to &lt;code&gt;reverse_exc.py&lt;/code&gt;, then the process exits with a status code of &lt;code&gt;1&lt;/code&gt; after printing the usage. Note the integration of &lt;code&gt;sys.argv[0]&lt;/code&gt; in the error message. It exposes the name of the program in the usage message. Now, when you execute the same program without any Python command line arguments, you can see the following output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python reverse.py
&lt;span class=&quot;go&quot;&gt;Usage: reverse.py &amp;lt;string_to_reverse&amp;gt;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;reverse.py&lt;/code&gt; didn&amp;rsquo;t have an argument passed at the command line. As a result, the program raises &lt;code&gt;SystemExit&lt;/code&gt; with an error message. This causes the program to exit with a status of &lt;code&gt;1&lt;/code&gt;, which displays when you print the special variable &lt;a href=&quot;https://en.wikipedia.org/wiki/Bash_(Unix_shell)#Conditional_execution&quot;&gt;&lt;code&gt;$?&lt;/code&gt;&lt;/a&gt; with &lt;a href=&quot;https://en.wikipedia.org/wiki/Echo_%28command%29&quot;&gt;&lt;code&gt;echo&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;calculating-the-sha1sum&quot;&gt;Calculating the &lt;code&gt;sha1sum&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;You&amp;rsquo;ll write another script to demonstrate that, on &lt;a href=&quot;https://en.wikipedia.org/wiki/Unix-like&quot;&gt;Unix-like&lt;/a&gt; systems, Python command line arguments are passed by bytes from the OS. This script takes a string as an argument and outputs the hexadecimal &lt;a href=&quot;https://en.wikipedia.org/wiki/SHA-1&quot;&gt;SHA-1&lt;/a&gt; hash of the argument:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# sha1sum.py&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;hashlib&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hashlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is loosely inspired by &lt;code&gt;sha1sum&lt;/code&gt;, but it intentionally processes a string instead of the contents of a file. In &lt;code&gt;sha1sum.py&lt;/code&gt;, the steps to ingest the Python command line arguments and to output the result are the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Line 6&lt;/strong&gt; stores the content of the first argument in &lt;code&gt;data&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 7&lt;/strong&gt; instantiates a SHA1 algorithm.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 8&lt;/strong&gt; updates the SHA1 hash object with the content of the first program argument. Note that &lt;code&gt;hash.update&lt;/code&gt; takes a byte array as an argument, so it&amp;rsquo;s necessary to convert &lt;code&gt;data&lt;/code&gt; from a string to a bytes array.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 9&lt;/strong&gt; prints a &lt;a href=&quot;https://docs.python.org/library/hashlib.html#hashlib.hash.hexdigest&quot;&gt;hexadecimal representation&lt;/a&gt; of the SHA1 hash computed on line 8.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you run the script with an argument, you get this:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python sha1sum.py &lt;span class=&quot;s2&quot;&gt;&amp;quot;Real Python&amp;quot;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0554943d034f044c5998f55dac8ee2c03e387565&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For the sake of keeping the example short, the script &lt;code&gt;sha1sum.py&lt;/code&gt; doesn&amp;rsquo;t handle missing Python command line arguments. Error handling could be addressed in this script the same way you did it in &lt;code&gt;reverse_exc.py&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Checkout &lt;a href=&quot;https://docs.python.org/library/hashlib.html&quot;&gt;&lt;code&gt;hashlib&lt;/code&gt;&lt;/a&gt; for more details about the hash functions available in the Python standard library.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;From the &lt;code&gt;sys.argv&lt;/code&gt; &lt;a href=&quot;https://docs.python.org/library/sys.html#sys.argv&quot;&gt;documentation&lt;/a&gt;, you learn that in order to get the original bytes of the Python command line arguments, you can use &lt;a href=&quot;https://docs.python.org/library/os.html#os.fsencode&quot;&gt;&lt;code&gt;os.fsencode()&lt;/code&gt;&lt;/a&gt;. By directly obtaining the bytes from &lt;code&gt;sys.argv[1]&lt;/code&gt;, you don&amp;rsquo;t need to perform the string-to-bytes conversion of &lt;code&gt;data&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# sha1sum_bytes.py&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;hashlib&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fsencode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hashlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The main difference between &lt;code&gt;sha1sum.py&lt;/code&gt; and &lt;code&gt;sha1sum_bytes.py&lt;/code&gt; are highlighted in the following lines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Line 7&lt;/strong&gt; populates &lt;code&gt;data&lt;/code&gt; with the original bytes passed to the Python command line arguments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 9&lt;/strong&gt; passes &lt;code&gt;data&lt;/code&gt; as an argument to &lt;a href=&quot;https://docs.python.org/library/hashlib.html#hashlib.hash.update&quot;&gt;&lt;code&gt;m.update()&lt;/code&gt;&lt;/a&gt;, which receives a &lt;a href=&quot;https://docs.python.org/glossary.html#term-bytes-like-object&quot;&gt;bytes-like object&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Execute &lt;code&gt;sha1sum_bytes.py&lt;/code&gt; to compare the output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python sha1sum_bytes.py &lt;span class=&quot;s2&quot;&gt;&amp;quot;Real Python&amp;quot;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0554943d034f044c5998f55dac8ee2c03e387565&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The hexadecimal value of the SHA1 hash is the same as in the previous &lt;code&gt;sha1sum.py&lt;/code&gt; example.&lt;/p&gt;
&lt;h2 id=&quot;the-anatomy-of-python-command-line-arguments&quot;&gt;The Anatomy of Python Command Line Arguments&lt;/h2&gt;
&lt;p&gt;Now that you&amp;rsquo;ve explored a few aspects of Python command line arguments, most notably &lt;code&gt;sys.argv&lt;/code&gt;, you&amp;rsquo;re going to apply some of the standards that are regularly used by developers while implementing a command line interface.&lt;/p&gt;
&lt;p&gt;Python command line arguments are a subset of the command line interface. They can be composed of different types of arguments:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Options&lt;/strong&gt; modify the behavior of a particular command or program.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Arguments&lt;/strong&gt; represent the source or destination to be processed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Subcommands&lt;/strong&gt; allow a program to define more than one command with the respective set of options and arguments.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Before you go deeper into the different types of arguments, you&amp;rsquo;ll get an overview of the accepted standards that have been guiding the design of the command line interface and arguments. These have been refined since the advent of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Computer_terminal&quot;&gt;computer terminal&lt;/a&gt; in the mid-1960s.&lt;/p&gt;
&lt;h3 id=&quot;standards&quot;&gt;Standards&lt;/h3&gt;
&lt;p&gt;A few available &lt;strong&gt;standards&lt;/strong&gt; provide some definitions and guidelines to promote consistency for implementing commands and their arguments. These are the main UNIX standards and references:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html&quot;&gt;POSIX Utility Conventions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gnu.org/prep/standards/standards.html#Command_002dLine-Interfaces&quot;&gt;GNU Standards for Command Line Interfaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://docopt.org/&quot;&gt;docopt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The standards above define guidelines and nomenclatures for anything related to programs and Python command line arguments. The following points are examples taken from those references:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;POSIX&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;A program or utility is followed by options, option-arguments, and operands.&lt;/li&gt;
&lt;li&gt;All options should be preceded with a hyphen or minus (&lt;code&gt;-&lt;/code&gt;) delimiter character.&lt;/li&gt;
&lt;li&gt;Option-arguments should not be optional.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GNU&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;All programs should support two standard options, which are &lt;code&gt;--version&lt;/code&gt; and &lt;code&gt;--help&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Long-named options are equivalent to the single-letter Unix-style options. An example is &lt;code&gt;--debug&lt;/code&gt; and &lt;code&gt;-d&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;docopt&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;Short options can be stacked, meaning that &lt;code&gt;-abc&lt;/code&gt; is equivalent to &lt;code&gt;-a -b -c&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Long options can have arguments specified after a space or the equals sign (&lt;code&gt;=&lt;/code&gt;). The long option &lt;code&gt;--input=ARG&lt;/code&gt; is equivalent to &lt;code&gt;--input ARG&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These standards define notations that are helpful when you describe a command. A similar notation can be used to display the usage of a particular command when you invoke it with the option &lt;code&gt;-h&lt;/code&gt; or &lt;code&gt;--help&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The GNU standards are very similar to the POSIX standards but provide some modifications and extensions. Notably, they add the &lt;strong&gt;long option&lt;/strong&gt; that&amp;rsquo;s a fully named option prefixed with two hyphens (&lt;code&gt;--&lt;/code&gt;). For example, to display the help, the regular option is &lt;code&gt;-h&lt;/code&gt; and the long option is &lt;code&gt;--help&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You don&amp;rsquo;t need to follow those standards rigorously. Instead, follow the conventions that have been used successfully for years since the advent of UNIX. If you write a set of utilities for you or your team, then ensure that you &lt;strong&gt;stay consistent&lt;/strong&gt; across the different utilities.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In the following sections, you&amp;rsquo;ll learn more about each of the command line components, options, arguments, and sub-commands.&lt;/p&gt;
&lt;h3 id=&quot;options&quot;&gt;Options&lt;/h3&gt;
&lt;p&gt;An &lt;strong&gt;option&lt;/strong&gt;, sometimes called a &lt;strong&gt;flag&lt;/strong&gt; or a &lt;strong&gt;switch&lt;/strong&gt;, is intended to modify the behavior of the program. For example, the command &lt;code&gt;ls&lt;/code&gt; on Linux lists the content of a given directory. Without any arguments, it lists the files and directories in the current directory:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /dev
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ls
&lt;span class=&quot;go&quot;&gt;autofs&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;block&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bsg&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;btrfs-control&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bus&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;char&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;console&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let&amp;rsquo;s add a few options. You can combine &lt;code&gt;-l&lt;/code&gt; and &lt;code&gt;-s&lt;/code&gt; into &lt;code&gt;-ls&lt;/code&gt;, which changes the information displayed in the terminal:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /dev
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ls -ls
&lt;span class=&quot;go&quot;&gt;total 0&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0 crw-r--r--  1 root root       10,   235 Jul 14 08:10 autofs&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0 drwxr-xr-x  2 root root             260 Jul 14 08:10 block&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0 drwxr-xr-x  2 root root              60 Jul 14 08:10 bsg&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0 crw-------  1 root root       10,   234 Jul 14 08:10 btrfs-control&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0 drwxr-xr-x  3 root root              60 Jul 14 08:10 bus&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0 drwxr-xr-x  2 root root            4380 Jul 14 15:08 char&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0 crw-------  1 root root        5,     1 Jul 14 08:10 console&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;An &lt;strong&gt;option&lt;/strong&gt; can take an argument, which is called an &lt;strong&gt;option-argument&lt;/strong&gt;. See an example in action with &lt;a href=&quot;https://en.wikipedia.org/wiki/Od_%28Unix%29&quot;&gt;&lt;code&gt;od&lt;/code&gt;&lt;/a&gt; below:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; od -t x1z -N &lt;span class=&quot;m&quot;&gt;16&lt;/span&gt; main
&lt;span class=&quot;go&quot;&gt;0000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00  &amp;gt;.ELF............&amp;lt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0000020&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;od&lt;/code&gt;&lt;/strong&gt; stands for &lt;strong&gt;octal dump&lt;/strong&gt;. This utility displays data in different printable representations, like octal (which is the default), hexadecimal, decimal, and ASCII. In the example above, it takes the binary file &lt;code&gt;main&lt;/code&gt; and displays the first 16 bytes of the file in hexadecimal format. The option &lt;code&gt;-t&lt;/code&gt; expects a type as an option-argument, and &lt;code&gt;-N&lt;/code&gt; expects the number of input bytes.&lt;/p&gt;
&lt;p&gt;In the example above, &lt;code&gt;-t&lt;/code&gt; is given type &lt;code&gt;x1&lt;/code&gt;, which stands for hexadecimal and one byte per integer. This is followed by &lt;code&gt;z&lt;/code&gt; to display the printable characters at the end of the input line. &lt;code&gt;-N&lt;/code&gt; takes &lt;code&gt;16&lt;/code&gt; as an option-argument for limiting the number of input bytes to 16.&lt;/p&gt;
&lt;h3 id=&quot;arguments&quot;&gt;Arguments&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;arguments&lt;/strong&gt; are also called &lt;strong&gt;operands&lt;/strong&gt; or &lt;a href=&quot;https://en.wikipedia.org/wiki/Parameter#Computing&quot;&gt;parameters&lt;/a&gt; in the POSIX standards. The arguments represent the source or the destination of the data that the command acts on. For example, the command &lt;a href=&quot;https://en.wikipedia.org/wiki/Cp_%28Unix%29&quot;&gt;&lt;code&gt;cp&lt;/code&gt;&lt;/a&gt;, which is used to copy one or more files to a file or a directory, takes at least one source and one target:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ls main
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;main&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; cp main main2
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ls -lt
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;main&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;main2&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In line 4, &lt;code&gt;cp&lt;/code&gt; takes two arguments:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;main&lt;/code&gt;:&lt;/strong&gt; the source file&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;main2&lt;/code&gt;:&lt;/strong&gt; the target file&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It then copies the content of &lt;code&gt;main&lt;/code&gt; to a new file named &lt;code&gt;main2&lt;/code&gt;. Both &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;main2&lt;/code&gt; are arguments, or operands, of the program &lt;code&gt;cp&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;subcommands&quot;&gt;Subcommands&lt;/h3&gt;
&lt;p&gt;The concept of &lt;strong&gt;subcommands&lt;/strong&gt; isn&amp;rsquo;t documented in the POSIX or GNU standards, but it does appear in &lt;strong&gt;docopt&lt;/strong&gt;. The standard Unix utilities are small tools adhering to the &lt;a href=&quot;https://en.wikipedia.org/wiki/Unix_philosophy&quot;&gt;Unix philosophy&lt;/a&gt;. Unix programs are intended to be programs that &lt;a href=&quot;https://en.wikipedia.org/wiki/Unix_philosophy#Do_One_Thing_and_Do_It_Well&quot;&gt;do one thing and do it well&lt;/a&gt;. This means no subcommands are necessary.&lt;/p&gt;
&lt;p&gt;By contrast, a new generation of programs, including &lt;a href=&quot;https://git-scm.com/&quot;&gt;&lt;code&gt;git&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://golang.org/&quot;&gt;&lt;code&gt;go&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.docker.com/&quot;&gt;&lt;code&gt;docker&lt;/code&gt;&lt;/a&gt;, and &lt;a href=&quot;https://cloud.google.com/sdk/gcloud/&quot;&gt;&lt;code&gt;gcloud&lt;/code&gt;&lt;/a&gt;, come with a slightly different paradigm that embraces subcommands. They&amp;rsquo;re not necessarily part of the Unix landscape as they span several operating systems, and they&amp;rsquo;re deployed with a full ecosystem that requires several commands.&lt;/p&gt;
&lt;p&gt;Take &lt;code&gt;git&lt;/code&gt; as an example. It handles several commands, each possibly with their own set of options, option-arguments, and arguments. The following examples apply to the git subcommand &lt;code&gt;branch&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;git branch&lt;/code&gt;&lt;/strong&gt; displays the branches of the local git repository.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;git branch custom_python&lt;/code&gt;&lt;/strong&gt; creates a local branch &lt;code&gt;custom_python&lt;/code&gt; in a local repository.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;git branch -d custom_python&lt;/code&gt;&lt;/strong&gt; deletes the local branch &lt;code&gt;custom_python&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;git branch --help&lt;/code&gt;&lt;/strong&gt; displays the help for the &lt;code&gt;git branch&lt;/code&gt; subcommand.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the Python ecosystem, &lt;a href=&quot;https://en.wikipedia.org/wiki/Pip_%28package_manager%29&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt; has the concept of subcommands, too. Some &lt;code&gt;pip&lt;/code&gt; subcommands include &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;install&lt;/code&gt;, &lt;code&gt;freeze&lt;/code&gt;, or &lt;code&gt;uninstall&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;windows&quot;&gt;Windows&lt;/h3&gt;
&lt;p&gt;On Windows, the conventions regarding Python command line arguments are slightly different, in particular, those regarding &lt;a href=&quot;https://en.wikipedia.org/wiki/Command-line_interface#Option_conventions_in_DOS,_Windows,_OS/2&quot;&gt;command line options&lt;/a&gt;. To validate this difference, take &lt;code&gt;tasklist&lt;/code&gt;, which is a native Windows executable that displays a list of the currently running processes. It&amp;rsquo;s similar to &lt;code&gt;ps&lt;/code&gt; on Linux or macOS systems. Below is an example of how to execute &lt;code&gt;tasklist&lt;/code&gt; in a command prompt on Windows:&lt;/p&gt;
&lt;div class=&quot;highlight doscon&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;C:/&amp;gt;&lt;/span&gt;tasklist /FI &lt;span class=&quot;s2&quot;&gt;&amp;quot;IMAGENAME eq notepad.exe&amp;quot;&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;Image Name                     PID Session Name        Session#    Mem Usage&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;========================= ======== ================ =========== ============&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;notepad.exe                  13104 Console                    6     13,548 K&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;notepad.exe                   6584 Console                    6     13,696 K&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that the separator for an option is a forward slash (&lt;code&gt;/&lt;/code&gt;) instead of a hyphen (&lt;code&gt;-&lt;/code&gt;) like the conventions for Unix systems. For readability, there&amp;rsquo;s a space between the program name, &lt;code&gt;taskslist&lt;/code&gt;, and the option &lt;code&gt;/FI&lt;/code&gt;, but it&amp;rsquo;s just as correct to type &lt;code&gt;taskslist/FI&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The particular example above executes &lt;code&gt;tasklist&lt;/code&gt; with a filter to only show the Notepad processes currently running. You can see that the system has two running instances of the Notepad process. Although it&amp;rsquo;s not equivalent, this is similar to executing the following command in a terminal on a Unix-like system:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ps -ef &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; grep vi &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; grep -v grep
&lt;span class=&quot;go&quot;&gt;andre     2117     4  0 13:33 tty1     00:00:00 vi .gitignore&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;andre     2163  2134  0 13:34 tty3     00:00:00 vi main.c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;ps&lt;/code&gt; command above shows all the current running &lt;code&gt;vi&lt;/code&gt; processes. The behavior is consistent with the &lt;a href=&quot;https://en.wikipedia.org/wiki/Unix_philosophy&quot;&gt;Unix Philosophy&lt;/a&gt;, as the output of &lt;code&gt;ps&lt;/code&gt; is transformed by two &lt;code&gt;grep&lt;/code&gt; filters. The first &lt;code&gt;grep&lt;/code&gt; command selects all the occurrences of &lt;code&gt;vi&lt;/code&gt;, and the second &lt;code&gt;grep&lt;/code&gt; filters out the occurrence of &lt;code&gt;grep&lt;/code&gt; itself.&lt;/p&gt;
&lt;p&gt;With the spread of Unix tools making their appearance in the Windows ecosystem, non-Windows-specific conventions are also accepted on Windows.&lt;/p&gt;
&lt;h3 id=&quot;visuals&quot;&gt;Visuals&lt;/h3&gt;
&lt;p&gt;At the start of a Python process, Python command line arguments are split into two categories:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Python options:&lt;/strong&gt; These influence the execution of the Python interpreter. For example, adding option &lt;a href=&quot;https://docs.python.org/3/using/cmdline.html#cmdoption-o&quot;&gt;&lt;code&gt;-O&lt;/code&gt;&lt;/a&gt; is a means to optimize the execution of a Python program by removing &lt;code&gt;assert&lt;/code&gt; and &lt;code&gt;__debug__&lt;/code&gt; statements. There are other &lt;a href=&quot;https://docs.python.org/using/cmdline.html#interface-options&quot;&gt;Python options&lt;/a&gt; available at the command line.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Python program and its arguments:&lt;/strong&gt; Following the Python options (if there are any), you&amp;rsquo;ll find the Python program, which is a file name that usually has the extension &lt;code&gt;.py&lt;/code&gt;, and its arguments. By convention, those can also be composed of options and arguments.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Take the following command that&amp;rsquo;s intended to execute the program &lt;code&gt;main.py&lt;/code&gt;, which takes options and arguments. Note that, in this example, the Python interpreter also takes some options, which are &lt;a href=&quot;https://docs.python.org/using/cmdline.html#id1&quot;&gt;&lt;code&gt;-B&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://docs.python.org/using/cmdline.html#id4&quot;&gt;&lt;code&gt;-v&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python -B -v main.py --verbose --debug un deux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the command line above, the options are Python command line arguments and are organized as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The option &lt;code&gt;-B&lt;/code&gt;&lt;/strong&gt; tells Python not to write &lt;code&gt;.pyc&lt;/code&gt; files on the import of source modules. For more details about &lt;code&gt;.pyc&lt;/code&gt; files, check out the section &lt;a href=&quot;https://realpython.com/cpython-source-code-guide/#what-does-a-compiler-do&quot;&gt;What Does a Compiler Do?&lt;/a&gt; in &lt;a href=&quot;https://realpython.com/cpython-source-code-guide&quot;&gt;Your Guide to the CPython Source Code&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The option &lt;code&gt;-v&lt;/code&gt;&lt;/strong&gt; stands for &lt;strong&gt;verbose&lt;/strong&gt; and tells Python to trace all import statements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The arguments passed to &lt;code&gt;main.py&lt;/code&gt;&lt;/strong&gt; are fictitious and represent two long options (&lt;code&gt;--verbose&lt;/code&gt; and &lt;code&gt;--debug&lt;/code&gt;) and two arguments (&lt;code&gt;un&lt;/code&gt; and &lt;code&gt;deux&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This example of Python command line arguments can be illustrated graphically as follows:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/python_blue.37b9170f4345.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/python_blue.37b9170f4345.png&quot; width=&quot;623&quot; height=&quot;416&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/python_blue.37b9170f4345.png&amp;amp;w=155&amp;amp;sig=80e44a3102825cc28bbe8a827ef392b7239bd1b2 155w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/python_blue.37b9170f4345.png&amp;amp;w=311&amp;amp;sig=45ac3af85f0779d61f17b2a5b25442bf11253335 311w, https://files.realpython.com/media/python_blue.37b9170f4345.png 623w&quot; sizes=&quot;75vw&quot; alt=&quot;Anatomy of the Python Command Line Arguments&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Within the Python program &lt;code&gt;main.py&lt;/code&gt;, you only have access to the Python command line arguments inserted by Python in &lt;code&gt;sys.argv&lt;/code&gt;. The Python options may influence the behavior of the program but are not accessible in &lt;code&gt;main.py&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;a-few-methods-for-parsing-python-command-line-arguments&quot;&gt;A Few Methods for Parsing Python Command Line Arguments&lt;/h2&gt;
&lt;p&gt;Now you&amp;rsquo;re going to explore a few approaches to apprehend options, option-arguments, and operands. This is done by &lt;strong&gt;parsing&lt;/strong&gt; Python command line arguments. In this section, you&amp;rsquo;ll see some concrete aspects of Python command line arguments and techniques to handle them. First, you&amp;rsquo;ll see an example that introduces a straight approach relying on &lt;a href=&quot;https://realpython.com/list-comprehension-python/&quot;&gt;list comprehensions&lt;/a&gt; to collect and separate options from arguments. Then you will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use&lt;/strong&gt; regular expressions to extract elements of the command line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learn&lt;/strong&gt; how to handle files passed at the command line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apprehend&lt;/strong&gt; the standard input in a way that&amp;rsquo;s compatible with the Unix tools&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Differentiate&lt;/strong&gt; the regular output of the program from the errors&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Implement&lt;/strong&gt; a custom parser to read Python command line arguments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This will serve as a preparation for options involving modules in the standard libraries or from external libraries that you&amp;rsquo;ll learn about later in this tutorial.&lt;/p&gt;
&lt;p&gt;For something uncomplicated, the following pattern, which doesn&amp;rsquo;t enforce ordering and doesn&amp;rsquo;t handle option-arguments, may be enough:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# cul.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-c&amp;quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-u&amp;quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-l&amp;quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Usage: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sys.argv[0]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; (-c | -u | -l) &amp;lt;arguments&amp;gt;...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The intent of the program above is to modify the case of the Python command line arguments. Three options are available:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;-c&lt;/code&gt;&lt;/strong&gt; to capitalize the arguments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;-u&lt;/code&gt;&lt;/strong&gt; to convert the arguments to uppercase&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;-l&lt;/code&gt;&lt;/strong&gt; to convert the argument to lowercase&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The code collects and separates the different argument types using &lt;a href=&quot;https://realpython.com/list-comprehension-python/&quot;&gt;list comprehensions&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Line 5&lt;/strong&gt; collects all the &lt;strong&gt;options&lt;/strong&gt; by filtering on any Python command line arguments starting with a hyphen (&lt;code&gt;-&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 6&lt;/strong&gt; assembles the program &lt;strong&gt;arguments&lt;/strong&gt; by filtering out the options.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you execute the Python program above with a set of options and arguments, you get the following output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python cul.py -c un deux trois
&lt;span class=&quot;go&quot;&gt;Un Deux Trois&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This approach might suffice in many situations, but it would fail in the following cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the order is important, and in particular, if options should appear before the arguments&lt;/li&gt;
&lt;li&gt;If support for option-arguments is needed&lt;/li&gt;
&lt;li&gt;If some arguments are prefixed with a hyphen (&lt;code&gt;-&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can leverage other options before you resort to a library like &lt;code&gt;argparse&lt;/code&gt; or &lt;code&gt;click&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;regular-expressions&quot;&gt;Regular Expressions&lt;/h3&gt;
&lt;p&gt;You can use a &lt;a href=&quot;https://en.wikipedia.org/wiki/Regular_expression&quot;&gt;regular expression&lt;/a&gt; to enforce a certain order, specific options and option-arguments, or even the type of arguments. To illustrate the usage of a regular expression to parse Python command line arguments, you&amp;rsquo;ll implement a Python version of &lt;a href=&quot;https://en.wikipedia.org/wiki/Seq_%28Unix%29&quot;&gt;&lt;code&gt;seq&lt;/code&gt;&lt;/a&gt;, which is a program that prints a sequence of numbers. Following the docopt conventions, a specification for &lt;code&gt;seq.py&lt;/code&gt; could be this:&lt;/p&gt;
&lt;div class=&quot;highlight text&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Print integers from &amp;lt;first&amp;gt; to &amp;lt;last&amp;gt;, in steps of &amp;lt;increment&amp;gt;.

Usage:
  python seq.py --help
  python seq.py [-s SEPARATOR] &amp;lt;last&amp;gt;
  python seq.py [-s SEPARATOR] &amp;lt;first&amp;gt; &amp;lt;last&amp;gt;
  python seq.py [-s SEPARATOR] &amp;lt;first&amp;gt; &amp;lt;increment&amp;gt; &amp;lt;last&amp;gt;

Mandatory arguments to long options are mandatory for short options too.
  -s, --separator=STRING use STRING to separate numbers (default: \n)
      --help             display this help and exit

If &amp;lt;first&amp;gt; or &amp;lt;increment&amp;gt; are omitted, they default to 1. When &amp;lt;first&amp;gt; is
larger than &amp;lt;last&amp;gt;, &amp;lt;increment&amp;gt;, if not set, defaults to -1.
The sequence of numbers ends when the sum of the current number and
&amp;lt;increment&amp;gt; reaches the limit imposed by &amp;lt;last&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;First, look at a regular expression that&amp;rsquo;s intended to capture the requirements above:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args_pattern&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;    &lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;    ^&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;    (&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;        (--(?P&amp;lt;HELP&amp;gt;help).*)|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;        ((?:-s|--separator)\s(?P&amp;lt;SEP&amp;gt;.*?)\s)?&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;        ((?P&amp;lt;OP1&amp;gt;-?\d+))(\s(?P&amp;lt;OP2&amp;gt;-?\d+))?(\s(?P&amp;lt;OP3&amp;gt;-?\d+))?&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;    )&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;    $&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VERBOSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To experiment with the regular expression above, you may use the snippet recorded on &lt;a href=&quot;https://regex101.com/r/Wh2Rce/3&quot;&gt;Regular Expression 101&lt;/a&gt;. The regular expression captures and enforces a few aspects of the requirements given for &lt;code&gt;seq&lt;/code&gt;. In particular, the command may take:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;A help option&lt;/strong&gt;, in short (&lt;code&gt;-h&lt;/code&gt;) or long format (&lt;code&gt;--help&lt;/code&gt;), captured as a &lt;a href=&quot;https://www.regular-expressions.info/named.html&quot;&gt;named group&lt;/a&gt; called &lt;strong&gt;&lt;code&gt;HELP&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A separator option&lt;/strong&gt;, &lt;code&gt;-s&lt;/code&gt; or &lt;code&gt;--separator&lt;/code&gt;, taking an optional argument, and captured as named group called &lt;strong&gt;&lt;code&gt;SEP&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Up to three integer operands&lt;/strong&gt;, respectively captured as &lt;strong&gt;&lt;code&gt;OP1&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;OP2&lt;/code&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;code&gt;OP3&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For clarity, the pattern &lt;code&gt;args_pattern&lt;/code&gt; above uses the flag &lt;a href=&quot;https://docs.python.org/library/re.html#re.VERBOSE&quot;&gt;&lt;code&gt;re.VERBOSE&lt;/code&gt;&lt;/a&gt; on line 11. This allows you to spread the regular expression over a few lines to enhance readability. The pattern validates the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Argument order&lt;/strong&gt;: Options and arguments are expected to be laid out in a given order. For example, options are expected before the arguments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Option values&lt;/strong&gt;**: Only &lt;code&gt;--help&lt;/code&gt;, &lt;code&gt;-s&lt;/code&gt;, or &lt;code&gt;--separator&lt;/code&gt; are expected as options.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Argument mutual exclusivity&lt;/strong&gt;: The option &lt;code&gt;--help&lt;/code&gt; isn&amp;rsquo;t compatible with other options or arguments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Argument type&lt;/strong&gt;: Operands are expected to be positive or negative integers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the regular expression to be able to handle these things, it needs to see all Python command line arguments in one string. You can collect them using &lt;a href=&quot;https://docs.python.org/3/library/stdtypes.html#str.join&quot;&gt;str.join()&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;arg_line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This makes &lt;code&gt;arg_line&lt;/code&gt; a string that includes all arguments, except the program name, separated by a space.&lt;/p&gt;
&lt;p&gt;Given the pattern &lt;code&gt;args_pattern&lt;/code&gt; above, you can extract the Python command line arguments with the following function:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg_line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match_object&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args_pattern&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg_line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match_object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupdict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The pattern is already handling the order of the arguments, mutual exclusivity between options and arguments, and the type of the arguments. &lt;code&gt;parse()&lt;/code&gt; is applying &lt;a href=&quot;https://docs.python.org/library/re.html#re.match&quot;&gt;&lt;code&gt;re.match()&lt;/code&gt;&lt;/a&gt; to the argument line to extract the proper values and store the data in a dictionary.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://realpython.com/courses/dictionaries-python/&quot;&gt;dictionary&lt;/a&gt; includes the names of each group as keys and their respective values. For example, if the &lt;code&gt;arg_line&lt;/code&gt; value is &lt;code&gt;--help&lt;/code&gt;, then the dictionary is &lt;code&gt;{&#39;HELP&#39;: &#39;help&#39;}&lt;/code&gt;. If &lt;code&gt;arg_line&lt;/code&gt; is &lt;code&gt;-s T 10&lt;/code&gt;, then the dictionary becomes &lt;code&gt;{&#39;SEP&#39;: &#39;T&#39;, &#39;OP1&#39;: &#39;10&#39;}&lt;/code&gt;. You can expand the code block below to see an implementation of &lt;code&gt;seq&lt;/code&gt; with regular expressions.&lt;/p&gt;
&lt;div class=&quot;card mb-3&quot; id=&quot;collapse_card44723a&quot;&gt;
&lt;div class=&quot;card-header border-0&quot;&gt;&lt;p class=&quot;m-0&quot;&gt;&lt;button class=&quot;btn&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapse44723a&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapse44723a&quot;&gt;An Implementation of seq With Regular Expressions&lt;/button&gt; &lt;button class=&quot;btn btn-link float-right&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapse44723a&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapse44723a&quot;&gt;Show/Hide&lt;/button&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;collapse44723a&quot; class=&quot;collapse&quot; data-parent=&quot;#collapse_card44723a&quot;&gt;&lt;div class=&quot;card-body&quot; markdown=&quot;1&quot;&gt;

&lt;p&gt;The code below implements a limited version of &lt;strong&gt;&lt;code&gt;seq&lt;/code&gt;&lt;/strong&gt; with a regular expression to handle the command line parsing and validation:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# seq_regex.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dict&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;re&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Usage: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sys.argv[0]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; [-s &amp;lt;separator&amp;gt;] [first [increment]] last&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;args_pattern&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    ^&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    (&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        (--(?P&amp;lt;HELP&amp;gt;help).*)|&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        ((?:-s|--separator)\s(?P&amp;lt;SEP&amp;gt;.*?)\s)?&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        ((?P&amp;lt;OP1&amp;gt;-?\d+))(\s(?P&amp;lt;OP2&amp;gt;-?\d+))?(\s(?P&amp;lt;OP3&amp;gt;-?\d+))?&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    )&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    $&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VERBOSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg_line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match_object&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args_pattern&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg_line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match_object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupdict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;HELP&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;OP&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;SEP&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can execute the code above by running this command:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python seq_regex.py &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This should output the following:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Try this command with other combinations, including the &lt;code&gt;--help&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;You didn&amp;rsquo;t see a version option supplied here. This was done intentionally to reduce the length of the example. You may consider adding the version option as an extended exercise. As a hint, you could modify the regular expression by replacing the line &lt;code&gt;(--(?P&amp;lt;HELP&amp;gt;help).*)|&lt;/code&gt; with &lt;code&gt;(--(?P&amp;lt;HELP&amp;gt;help).*)|(--(?P&amp;lt;VER&amp;gt;version).*)|&lt;/code&gt;. An additional &lt;code&gt;if&lt;/code&gt; block would also be needed in &lt;code&gt;main()&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;p&gt;At this point, you know a few ways to extract options and arguments from the command line. So far, the Python command line arguments were only strings or integers. Next, you&amp;rsquo;ll learn how to handle files passed as arguments.&lt;/p&gt;
&lt;h3 id=&quot;file-handling&quot;&gt;File Handling&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s time now to experiment with Python command line arguments that are expected to be &lt;strong&gt;file names&lt;/strong&gt;. Modify &lt;code&gt;sha1sum.py&lt;/code&gt; to handle one or more files as arguments. You&amp;rsquo;ll end up with a downgraded version of the original &lt;code&gt;sha1sum&lt;/code&gt; utility, which takes one or more files as arguments and displays the hexadecimal SHA1 hash for each file, followed by the name of the file:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# sha1sum_file.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;hashlib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hashlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;rb&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;{sha1sum(arg)}  &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{arg}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;sha1sum()&lt;/code&gt; is applied to the data read from each file that you passed at the command line, rather than the string itself. Take note that &lt;code&gt;m.update()&lt;/code&gt; takes a &lt;a href=&quot;https://docs.python.org/glossary.html#term-bytes-like-object&quot;&gt;bytes-like object&lt;/a&gt; as an argument and that the result of invoking &lt;code&gt;read()&lt;/code&gt; after opening a file with the mode &lt;code&gt;rb&lt;/code&gt; will return a &lt;a href=&quot;https://docs.python.org/library/stdtypes.html#bytes&quot;&gt;&lt;code&gt;bytes&lt;/code&gt; object&lt;/a&gt;. For more information about handling file content, check out &lt;a href=&quot;https://realpython.com/read-write-files-python&quot;&gt;Reading and Writing Files in Python&lt;/a&gt;, and in particular, the section &lt;a href=&quot;https://realpython.com/read-write-files-python/#working-with-bytes&quot;&gt;Working With Bytes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The evolution of &lt;code&gt;sha1sum_file.py&lt;/code&gt; from handling strings at the command line to manipulating the content of files is getting you closer to the original implementation of &lt;code&gt;sha1sum&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sha1sum main main.c
&lt;span class=&quot;go&quot;&gt;9a6f82c245f5980082dbf6faac47e5085083c07d  main&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;125a0f900ff6f164752600550879cbfabb098bc3  main.c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The execution of the Python program with the same Python command line arguments gives this:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python sha1sum_file.py main main.c
&lt;span class=&quot;go&quot;&gt;9a6f82c245f5980082dbf6faac47e5085083c07d  main&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;125a0f900ff6f164752600550879cbfabb098bc3  main.c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Because you interact with the shell interpreter or the Windows command prompt, you also get the benefit of the wildcard expansion provided by the shell. To prove this, you can reuse &lt;code&gt;main.py&lt;/code&gt;, which displays each argument with the argument number and its value:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python main.py main.*
&lt;span class=&quot;go&quot;&gt;Arguments count: 5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      0: main.py&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      1: main.c&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      2: main.exe&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      3: main.obj&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      4: main.py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can see that the shell automatically performs wildcard expansion so that any file with a base name matching &lt;code&gt;main&lt;/code&gt;, regardless of the extension, is part of &lt;code&gt;sys.argv&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The wildcard expansion isn&amp;rsquo;t available on Windows. To obtain the same behavior, you need to implement it in your code. To refactor &lt;code&gt;main.py&lt;/code&gt; to work with wildcard expansion, you can use &lt;a href=&quot;https://docs.python.org/library/glob.html&quot;&gt;&lt;code&gt;glob&lt;/code&gt;&lt;/a&gt;. The following example works on Windows and, though it isn&amp;rsquo;t as concise as the original &lt;code&gt;main.py&lt;/code&gt;, the same code behaves similarly across platforms:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# main_win.py&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;glob&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;itertools&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;expand_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;glob_args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;glob&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;glob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itertools&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_iterable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;glob_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expand_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Arguments count: {len(args)}&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Argument &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{i:&amp;gt;6}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{arg}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In &lt;code&gt;main_win.py&lt;/code&gt;, &lt;code&gt;expand_args&lt;/code&gt; relies on &lt;a href=&quot;https://docs.python.org/library/glob.html#glob.glob&quot;&gt;&lt;code&gt;glob.glob()&lt;/code&gt;&lt;/a&gt; to process the shell-style wildcards. You can verify the result on Windows and any other operating system:&lt;/p&gt;
&lt;div class=&quot;highlight doscon&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;C:/&amp;gt;&lt;/span&gt;python main_win.py main.*
&lt;span class=&quot;go&quot;&gt;Arguments count: 5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      0: main_win.py&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      1: main.c&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      2: main.exe&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      3: main.obj&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Argument      4: main.py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This addresses the problem of handling files using wildcards like the asterisk (&lt;code&gt;*&lt;/code&gt;) or question mark (&lt;code&gt;?&lt;/code&gt;), but how about &lt;code&gt;stdin&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t pass any parameter to the original &lt;code&gt;sha1sum&lt;/code&gt; utility, then it expects to read data from the &lt;strong&gt;standard input&lt;/strong&gt;. This is the text you enter at the terminal that ends when you type &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-d&quot;&gt;D&lt;/kbd&gt;&lt;/span&gt; on Unix-like systems or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-z&quot;&gt;Z&lt;/kbd&gt;&lt;/span&gt; on Windows. These control sequences send an end of file (EOF) to the terminal, which stops reading from &lt;code&gt;stdin&lt;/code&gt; and returns the data that was entered.&lt;/p&gt;
&lt;p&gt;In the next section, you&amp;rsquo;ll add to your code the ability to read from the standard input stream.&lt;/p&gt;
&lt;h3 id=&quot;standard-input&quot;&gt;Standard Input&lt;/h3&gt;
&lt;p&gt;When you modify the previous Python implementation of &lt;code&gt;sha1sum&lt;/code&gt; to handle the standard input using &lt;a href=&quot;https://docs.python.org/library/sys.html#sys.stdin&quot;&gt;&lt;code&gt;sys.stdin&lt;/code&gt;&lt;/a&gt;, you&amp;rsquo;ll get closer to the original &lt;code&gt;sha1sum&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# sha1sum_stdin.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;hashlib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pathlib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pathlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sha1_hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hashlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sha1_hash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sha1_hash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;{sha1sum(data)}  &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{filename}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Two conventions are applied to this new &lt;code&gt;sha1sum&lt;/code&gt; version:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Without any arguments, the program expects the data to be provided in the standard input, &lt;code&gt;sys.stdin&lt;/code&gt;, which is a readable file object.&lt;/li&gt;
&lt;li&gt;When a hyphen (&lt;code&gt;-&lt;/code&gt;) is provided as a file argument at the command line, the program interprets it as reading the file from the standard input.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Try this new script without any arguments. Enter the first aphorism of &lt;a href=&quot;https://www.python.org/dev/peps/pep-0020/&quot;&gt;The Zen of Python&lt;/a&gt;, then complete the entry with the keyboard shortcut &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-d&quot;&gt;D&lt;/kbd&gt;&lt;/span&gt; on Unix-like systems or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-z&quot;&gt;Z&lt;/kbd&gt;&lt;/span&gt; on Windows:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python sha1sum_stdin.py
&lt;span class=&quot;go&quot;&gt;Beautiful is better than ugly.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;ae5705a3efd4488dfc2b4b80df85f60c67d998c4  -&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can also include one of the arguments as &lt;code&gt;stdin&lt;/code&gt; mixed with the other file arguments like so:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python sha1sum_stdin.py main.py - main.c
&lt;span class=&quot;go&quot;&gt;d84372fc77a90336b6bb7c5e959bcb1b24c608b4  main.py&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Beautiful is better than ugly.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;ae5705a3efd4488dfc2b4b80df85f60c67d998c4  -&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;125a0f900ff6f164752600550879cbfabb098bc3  main.c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Another approach on Unix-like systems is to provide &lt;code&gt;/dev/stdin&lt;/code&gt; instead of &lt;code&gt;-&lt;/code&gt; to handle the standard input:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python sha1sum_stdin.py main.py /dev/stdin main.c
&lt;span class=&quot;go&quot;&gt;d84372fc77a90336b6bb7c5e959bcb1b24c608b4  main.py&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Beautiful is better than ugly.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;ae5705a3efd4488dfc2b4b80df85f60c67d998c4  /dev/stdin&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;125a0f900ff6f164752600550879cbfabb098bc3  main.c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On Windows there&amp;rsquo;s no equivalent to &lt;code&gt;/dev/stdin&lt;/code&gt;, so using &lt;code&gt;-&lt;/code&gt; as a file argument works as expected.&lt;/p&gt;
&lt;p&gt;The script &lt;code&gt;sha1sum_stdin.py&lt;/code&gt; isn&amp;rsquo;t covering all necessary error handling, but you&amp;rsquo;ll cover some of the missing features &lt;a href=&quot;#a-few-methods-for-validating-python-command-line-arguments&quot;&gt;later in this tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;standard-output-and-standard-error&quot;&gt;Standard Output and Standard Error&lt;/h3&gt;
&lt;p&gt;Command line processing may have a direct relationship with &lt;code&gt;stdin&lt;/code&gt; to respect the conventions detailed in the previous section. The standard output, although not immediately relevant, is still a concern if you want to adhere to the &lt;a href=&quot;https://en.wikipedia.org/wiki/Unix_philosophy&quot;&gt;Unix Philosophy&lt;/a&gt;. To allow small programs to be combined, you may have to take into account the three standard streams:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;stdin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stdout&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stderr&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The output of a program becomes the input of another one, allowing you to chain small utilities. For example, if you wanted to sort the aphorisms of the Zen of Python, then you could execute the following:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python -c &lt;span class=&quot;s2&quot;&gt;&amp;quot;import this&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; sort
&lt;span class=&quot;go&quot;&gt;Although never is often better than *right* now.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Although practicality beats purity.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Although that way may not be obvious at first unless you&amp;#39;re Dutch.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output above is truncated for better readability. Now imagine that you have a program that outputs the same data but also prints some debugging information:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# zen_sort_debug.py&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;DEBUG &amp;gt;&amp;gt;&amp;gt; About to print the Zen of Python&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;this&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;DEBUG &amp;gt;&amp;gt;&amp;gt; Done printing the Zen of Python&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Executing the Python script above gives:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python zen_sort_debug.py
&lt;span class=&quot;go&quot;&gt;DEBUG &amp;gt;&amp;gt;&amp;gt; About to print the Zen of Python&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;The Zen of Python, by Tim Peters&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;Beautiful is better than ugly.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Explicit is better than implicit.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Simple is better than complex.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Complex is better than complicated.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;DEBUG &amp;gt;&amp;gt;&amp;gt; Done printing the Zen of Python&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The ellipsis (&lt;code&gt;...&lt;/code&gt;) indicates that the output was truncated to improve readability.&lt;/p&gt;
&lt;p&gt;Now, if you want to sort the list of aphorisms, then execute the command as follows:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python zen_sort_debug.py &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; sort

&lt;span class=&quot;go&quot;&gt;Although never is often better than *right* now.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Although practicality beats purity.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Although that way may not be obvious at first unless you&amp;#39;re Dutch.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Beautiful is better than ugly.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Complex is better than complicated.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;DEBUG &amp;gt;&amp;gt;&amp;gt; About to print the Zen of Python&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;DEBUG &amp;gt;&amp;gt;&amp;gt; Done printing the Zen of Python&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Errors should never pass silently.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You may realize that you didn&amp;rsquo;t intend to have the debug output as the input of the &lt;code&gt;sort&lt;/code&gt; command. To address this issue, you want to send traces to the standard errors stream, &lt;code&gt;stderr&lt;/code&gt;, instead:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# zen_sort_stderr.py&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;DEBUG &amp;gt;&amp;gt;&amp;gt; About to print the Zen of Python&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;this&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;DEBUG &amp;gt;&amp;gt;&amp;gt; Done printing the Zen of Python&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Execute &lt;code&gt;zen_sort_stderr.py&lt;/code&gt; to observe the following:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python zen_sort_stderr.py &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; sort
&lt;span class=&quot;go&quot;&gt;DEBUG &amp;gt;&amp;gt;&amp;gt; About to print the Zen of Python&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;DEBUG &amp;gt;&amp;gt;&amp;gt; Done printing the Zen of Python&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;Although never is often better than *right* now.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Although practicality beats purity.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Although that way may not be obvious at first unless you&amp;#39;re Dutch&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;....&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, the traces are displayed to the terminal, but they aren&amp;rsquo;t used as input for the &lt;code&gt;sort&lt;/code&gt; command.&lt;/p&gt;
&lt;h3 id=&quot;custom-parsers&quot;&gt;Custom Parsers&lt;/h3&gt;
&lt;p&gt;You can implement &lt;code&gt;seq&lt;/code&gt; by relying on a regular expression if the arguments aren&amp;rsquo;t too complex. Nevertheless, the regex pattern may quickly render the maintenance of the script difficult. Before you try getting help from specific libraries, another approach is to create a &lt;strong&gt;custom parser&lt;/strong&gt;. The parser is a loop that fetches each argument one after another and applies a custom logic based on the semantics of your program.&lt;/p&gt;
&lt;p&gt;A possible implementation for processing the arguments of &lt;code&gt;seq_parse.py&lt;/code&gt; could be as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;collections&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deque&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;popleft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--help&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;                &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;                &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-s&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--separator&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;                &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;popleft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;                &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ValueError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;parse()&lt;/code&gt; is given the list of arguments without the Python file name and uses &lt;a href=&quot;https://docs.python.org/library/collections.html#collections.deque&quot;&gt;&lt;code&gt;collections.deque()&lt;/code&gt;&lt;/a&gt; to get the benefit of &lt;a href=&quot;https://docs.python.org/library/collections.html#collections.deque.popleft&quot;&gt;&lt;code&gt;.popleft()&lt;/code&gt;&lt;/a&gt;, which removes the elements from the left of the collection. As the items of the arguments list unfold, you apply the logic that&amp;rsquo;s expected for your program. In &lt;code&gt;parse()&lt;/code&gt; you can observe the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;&lt;code&gt;while&lt;/code&gt;&lt;/strong&gt; loop is at the core of the function, and terminates when there are no more arguments to parse, when the help is invoked, or when an error occurs.&lt;/li&gt;
&lt;li&gt;If the &lt;strong&gt;&lt;code&gt;separator&lt;/code&gt;&lt;/strong&gt; option is detected, then the next argument is expected to be the separator.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;operands&lt;/code&gt;&lt;/strong&gt; stores the integers that are used to calculate the sequence. There should be at least one operand and at most three.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A full version of the code for &lt;code&gt;parse()&lt;/code&gt; is available below:&lt;/p&gt;
&lt;div class=&quot;card mb-3&quot; id=&quot;collapse_cardc5386a&quot;&gt;
&lt;div class=&quot;card-header border-0&quot;&gt;&lt;p class=&quot;m-0&quot;&gt;&lt;button class=&quot;btn&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapsec5386a&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapsec5386a&quot;&gt;Click to expand the full example.&lt;/button&gt; &lt;button class=&quot;btn btn-link float-right&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapsec5386a&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapsec5386a&quot;&gt;Show/Hide&lt;/button&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;collapsec5386a&quot; class=&quot;collapse&quot; data-parent=&quot;#collapse_cardc5386a&quot;&gt;&lt;div class=&quot;card-body&quot; markdown=&quot;1&quot;&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# seq_parse.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;collections&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;re&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Usage: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sys.argv[0]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;quot;&lt;/span&gt;
         &lt;span class=&quot;s2&quot;&gt;&amp;quot;[--help] | [-s &amp;lt;sep&amp;gt;] [first [incr]] last&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;collections&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deque&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;popleft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--help&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-s&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--separator&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;popleft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ValueError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that some error handling aspects are kept to a minimum so as to keep the examples relatively short.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;p&gt;This manual approach of parsing the Python command line arguments may be sufficient for a simple set of arguments. However, it becomes quickly error-prone when complexity increases due to the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A large number&lt;/strong&gt; of arguments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Complexity and interdependency&lt;/strong&gt; between arguments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validation&lt;/strong&gt; to perform against the arguments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The custom approach isn&amp;rsquo;t reusable and requires reinventing the wheel in each program. By the end of this tutorial, you&amp;rsquo;ll have improved on this hand-crafted solution and learned a few better methods.&lt;/p&gt;
&lt;h2 id=&quot;a-few-methods-for-validating-python-command-line-arguments&quot;&gt;A Few Methods for Validating Python Command Line Arguments&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ve already performed validation for Python command line arguments in a few examples like &lt;code&gt;seq_regex.py&lt;/code&gt; and &lt;code&gt;seq_parse.py&lt;/code&gt;. In the first example, you used a regular expression, and in the second example, a custom parser.&lt;/p&gt;
&lt;p&gt;Both of these examples took the same aspects into account. They considered the expected &lt;strong&gt;options&lt;/strong&gt; as short-form (&lt;code&gt;-s&lt;/code&gt;) or long-form (&lt;code&gt;--separator&lt;/code&gt;). They considered the &lt;strong&gt;order&lt;/strong&gt; of the arguments so that options would not be placed after &lt;strong&gt;operands&lt;/strong&gt;. Finally, they considered the type, integer for the operands, and the number of arguments, from one to three arguments.&lt;/p&gt;
&lt;h3 id=&quot;type-validation-with-python-data-classes&quot;&gt;Type Validation With Python Data Classes&lt;/h3&gt;
&lt;p&gt;The following is a proof of concept that attempts to validate the type of the arguments passed at the command line. In the following example, you validate the number of arguments and their respective type:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# val_type_dc.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;dataclasses&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Any&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Usage: python &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sys.argv[0]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; [--help] | firstname lastname age]&amp;quot;&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@dataclasses&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataclass&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;firstname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lastname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;check_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataclasses&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Value: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{value}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, &amp;quot;&lt;/span&gt;
            &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Expected type &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{field.type}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; for &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{field.name}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, &amp;quot;&lt;/span&gt;
            &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;got {type(value)}&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Type Error&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Type Ok&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# If passed to the command line, need to convert&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# the optional 3rd argument from string to int&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isdigit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;TypeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;check_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--help&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Unless you pass the &lt;code&gt;--help&lt;/code&gt; option at the command line, this script expects two or three arguments:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;A mandatory string:&lt;/strong&gt; &lt;code&gt;firstname&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A mandatory string:&lt;/strong&gt; &lt;code&gt;lastname&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An optional integer:&lt;/strong&gt; &lt;code&gt;age&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Because all the items in &lt;code&gt;sys.argv&lt;/code&gt; are strings, you need to convert the optional third argument to an integer if it&amp;rsquo;s composed of digits. &lt;a href=&quot;https://docs.python.org/3/library/stdtypes.html#str.isdigit&quot;&gt;&lt;code&gt;str.isdigit()&lt;/code&gt;&lt;/a&gt; validates if all the characters in a string are digits. In addition, by constructing the &lt;strong&gt;data class&lt;/strong&gt; &lt;code&gt;Arguments&lt;/code&gt; with the values of the converted arguments, you obtain two validations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;If the number of arguments&lt;/strong&gt; doesn&amp;rsquo;t correspond to the number of mandatory fields expected by &lt;code&gt;Arguments&lt;/code&gt;, then you get an error. This is a minimum of two and a maximum of three fields.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If the types after conversion&lt;/strong&gt; aren&amp;rsquo;t matching the types defined in the &lt;code&gt;Arguments&lt;/code&gt; data class definition, then you get an error.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can see this in action with the following execution:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python val_type_dc.py Guido &lt;span class=&quot;s2&quot;&gt;&amp;quot;Van Rossum&amp;quot;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;25&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Value: Guido, Expected type &amp;lt;class &amp;#39;str&amp;#39;&amp;gt; for firstname, got &amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Type Ok&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Value: Van Rossum, Expected type &amp;lt;class &amp;#39;str&amp;#39;&amp;gt; for lastname, got &amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Type Ok&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Value: 25, Expected type &amp;lt;class &amp;#39;int&amp;#39;&amp;gt; for age, got &amp;lt;class &amp;#39;int&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Type Ok&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the execution above, the number of arguments is correct and the type of each argument is also correct.&lt;/p&gt;
&lt;p&gt;Now, execute the same command but omit the third argument:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python val_type_dc.py Guido &lt;span class=&quot;s2&quot;&gt;&amp;quot;Van Rossum&amp;quot;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Value: Guido, Expected type &amp;lt;class &amp;#39;str&amp;#39;&amp;gt; for firstname, got &amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Type Ok&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Value: Van Rossum, Expected type &amp;lt;class &amp;#39;str&amp;#39;&amp;gt; for lastname, got &amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Type Ok&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Value: 0, Expected type &amp;lt;class &amp;#39;int&amp;#39;&amp;gt; for age, got &amp;lt;class &amp;#39;int&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Type Ok&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The result is also successful because the field &lt;code&gt;age&lt;/code&gt; is defined with a &lt;strong&gt;default value&lt;/strong&gt;, &lt;code&gt;0&lt;/code&gt;, so the data class &lt;code&gt;Arguments&lt;/code&gt; doesn&amp;rsquo;t require it.&lt;/p&gt;
&lt;p&gt;On the contrary, if the third argument isn&amp;rsquo;t of the proper type&amp;mdash;say, a string instead of integer&amp;mdash;then you get an error:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;python val_type_dc.py Guido Van Rossum&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Value: Guido, Expected type &amp;lt;class &amp;#39;str&amp;#39;&amp;gt; for firstname, got &amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Type Ok&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Value: Van, Expected type &amp;lt;class &amp;#39;str&amp;#39;&amp;gt; for lastname, got &amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Type Ok&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Value: Rossum, Expected type &amp;lt;class &amp;#39;int&amp;#39;&amp;gt; for age, got &amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Type Error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The expected value &lt;code&gt;Van Rossum&lt;/code&gt;, isn&amp;rsquo;t surrounded by quotes, so it&amp;rsquo;s split. The second word of the last name, &lt;code&gt;Rossum&lt;/code&gt;, is a string that&amp;rsquo;s handled as the age, which is expected to be an &lt;code&gt;int&lt;/code&gt;. The validation fails.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For more details about the usage of data classes in Python, check out &lt;a href=&quot;https://realpython.com/python-data-classes/&quot;&gt;The Ultimate Guide to Data Classes in Python 3.7&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Similarly, you could also use a &lt;a href=&quot;https://docs.python.org/3/library/typing.html#typing.NamedTuple&quot;&gt;&lt;code&gt;NamedTuple&lt;/code&gt;&lt;/a&gt; to achieve a similar validation. You&amp;rsquo;d replace the data class with a class deriving from &lt;code&gt;NamedTuple&lt;/code&gt;, and &lt;code&gt;check_type()&lt;/code&gt; would change as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NamedTuple&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NamedTuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;firstname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lastname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;check_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_asdict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Value: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{value}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, &amp;quot;&lt;/span&gt;
            &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Expected type &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{obj.__annotations__[attr]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; for &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{attr}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, &amp;quot;&lt;/span&gt;
            &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;got {type(value)}&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__annotations__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Type Error&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Type Ok&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A &lt;code&gt;NamedTuple&lt;/code&gt; exposes functions like &lt;code&gt;_asdict&lt;/code&gt; that transform the object into a dictionary that can be used for data lookup. It also exposes attributes like &lt;code&gt;__annotations__&lt;/code&gt;, which is a dictionary storing types for each field, and  For more on &lt;code&gt;__annotations__&lt;/code&gt;, check out &lt;a href=&quot;https://realpython.com/python-type-checking/#annotations&quot;&gt;Python Type Checking (Guide)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As highlighted in &lt;a href=&quot;https://realpython.com/python-type-checking/#using-types-at-runtime&quot;&gt;Python Type Checking (Guide)&lt;/a&gt;, you could also leverage existing packages like &lt;a href=&quot;https://pypi.org/project/enforce/&quot;&gt;Enforce&lt;/a&gt;, &lt;a href=&quot;https://pydantic-docs.helpmanual.io/&quot;&gt;Pydantic&lt;/a&gt;, and &lt;a href=&quot;https://pypi.org/project/pytypes/&quot;&gt;Pytypes&lt;/a&gt; for advanced validation.&lt;/p&gt;
&lt;h3 id=&quot;custom-validation&quot;&gt;Custom Validation&lt;/h3&gt;
&lt;p&gt;Not unlike what you&amp;rsquo;ve already explored &lt;a href=&quot;#custom-parsers&quot;&gt;earlier&lt;/a&gt;, detailed validation may require some custom approaches. For example, if you attempt to execute &lt;code&gt;sha1sum_stdin.py&lt;/code&gt; with an incorrect file name as an argument, then you get the following:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python sha1sum_stdin.py bad_file.txt
&lt;span class=&quot;go&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  File &amp;quot;sha1sum_stdin.py&amp;quot;, line 32, in &amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    main(sys.argv[1:])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  File &amp;quot;sha1sum_stdin.py&amp;quot;, line 29, in main&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    output_sha1sum(process_file(arg), arg)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  File &amp;quot;sha1sum_stdin.py&amp;quot;, line 9, in process_file&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    return pathlib.Path(filename).read_bytes()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  File &amp;quot;/usr/lib/python3.8/pathlib.py&amp;quot;, line 1222, in read_bytes&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    with self.open(mode=&amp;#39;rb&amp;#39;) as f:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  File &amp;quot;/usr/lib/python3.8/pathlib.py&amp;quot;, line 1215, in open&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    return io.open(self, mode, buffering, encoding, errors, newline,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  File &amp;quot;/usr/lib/python3.8/pathlib.py&amp;quot;, line 1071, in _opener&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    return self._accessor.open(self, flags, mode)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;FileNotFoundError: [Errno 2] No such file or directory: &amp;#39;bad_file.txt&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;bad_file.txt&lt;/code&gt; doesn&amp;rsquo;t exist, but the program attempts to read it.&lt;/p&gt;
&lt;p&gt;Revisit &lt;code&gt;main()&lt;/code&gt; in &lt;code&gt;sha1sum_stdin.py&lt;/code&gt; to handle non-existing files passed at the command line:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;            &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;FileNotFoundError&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sys.argv[0]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{arg}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{err.strerror}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To see the complete example with this extra validation, expand the code block below:&lt;/p&gt;
&lt;div class=&quot;card mb-3&quot; id=&quot;collapse_card5bea74&quot;&gt;
&lt;div class=&quot;card-header border-0&quot;&gt;&lt;p class=&quot;m-0&quot;&gt;&lt;button class=&quot;btn&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapse5bea74&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapse5bea74&quot;&gt;Complete Source Code of sha1sum_val.py&lt;/button&gt; &lt;button class=&quot;btn btn-link float-right&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapse5bea74&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapse5bea74&quot;&gt;Show/Hide&lt;/button&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;collapse5bea74&quot; class=&quot;collapse&quot; data-parent=&quot;#collapse_card5bea74&quot;&gt;&lt;div class=&quot;card-body&quot; markdown=&quot;1&quot;&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# sha1sum_val.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;hashlib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pathlib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pathlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hashlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;{sha1sum(data)}  &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{filename}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ne&quot;&gt;FileNotFoundError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;IsADirectoryError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sys.argv[0]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{arg}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{err.strerror}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/div&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;p&gt;When you execute this modified script, you get this:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python sha1sum_val.py bad_file.txt
&lt;span class=&quot;go&quot;&gt;sha1sum_val.py: bad_file.txt: No such file or directory&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that the error displayed to the terminal is written to &lt;code&gt;stderr&lt;/code&gt;, so it doesn&amp;rsquo;t interfere with the data expected by a command that would read the output of &lt;code&gt;sha1sum_val.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python sha1sum_val.py bad_file.txt main.py &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; cut -d &lt;span class=&quot;s2&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt; -f &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;sha1sum_val.py: bad_file.txt: No such file or directory&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;d84372fc77a90336b6bb7c5e959bcb1b24c608b4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This command pipes the output of &lt;code&gt;sha1sum_val.py&lt;/code&gt; to &lt;a href=&quot;https://en.wikipedia.org/wiki/Cut_%28Unix%29&quot;&gt;&lt;code&gt;cut&lt;/code&gt;&lt;/a&gt; to only include the first field. You can see that &lt;code&gt;cut&lt;/code&gt; ignores the error message because it only receives the data sent to &lt;code&gt;stdout&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;the-python-standard-library&quot;&gt;The Python Standard Library&lt;/h2&gt;
&lt;p&gt;Despite the different approaches you took to process Python command line arguments, any complex program might be better off &lt;strong&gt;leveraging existing libraries&lt;/strong&gt; to handle the heavy lifting required by sophisticated command line interfaces. As of Python 3.7, there are three command line parsers in the standard library:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.python.org/library/argparse.html&quot;&gt;&lt;code&gt;argparse&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.python.org/library/getopt.html&quot;&gt;&lt;code&gt;getopt&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.python.org/library/optparse.html&quot;&gt;&lt;code&gt;optparse&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The recommended module to use from the standard library is &lt;code&gt;argparse&lt;/code&gt;. The standard library also exposes &lt;code&gt;optparse&lt;/code&gt; but it&amp;rsquo;s officially deprecated and only mentioned here for your information. It was superseded by &lt;code&gt;argparse&lt;/code&gt; in Python 3.2 and you won&amp;rsquo;t see it discussed in this tutorial.&lt;/p&gt;
&lt;h3 id=&quot;argparse&quot;&gt;&lt;code&gt;argparse&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;You&amp;rsquo;re going to revisit &lt;code&gt;sha1sum_val.py&lt;/code&gt;, the most recent clone of &lt;code&gt;sha1sum&lt;/code&gt;, to introduce the benefits of &lt;code&gt;argparse&lt;/code&gt;. To this effect, you&amp;rsquo;ll modify &lt;code&gt;main()&lt;/code&gt; and add &lt;code&gt;init_argparse&lt;/code&gt; to instantiate &lt;code&gt;argparse.ArgumentParser&lt;/code&gt;:  &lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;argparse&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init_argparse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argparse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argparse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;usage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%(prog)s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; [OPTION] [FILE]...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Print or check SHA1 (160-bit) checksums.&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;-v&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--version&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{parser.prog}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; version 1.0.0&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;files&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nargs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init_argparse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;23 &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;24 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;25 &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;26 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ne&quot;&gt;FileNotFoundError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;IsADirectoryError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;27 &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sys.argv[0]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{file}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{err.strerror}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For the cost of a few more lines compared to the previous implementation, you get a clean approach to add &lt;code&gt;--help&lt;/code&gt; and &lt;code&gt;--version&lt;/code&gt; options that didn&amp;rsquo;t exist before. The expected arguments (the files to be processed) are all available in field &lt;code&gt;files&lt;/code&gt; of object &lt;a href=&quot;https://docs.python.org/library/argparse.html#argparse.Namespace&quot;&gt;&lt;code&gt;argparse.Namespace&lt;/code&gt;&lt;/a&gt;. This object is populated on line 17 by calling &lt;a href=&quot;https://docs.python.org/library/argparse.html#argparse.ArgumentParser.parse_args&quot;&gt;&lt;code&gt;parse_args()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To look at the full script with the modifications described above, expand the code block below:&lt;/p&gt;
&lt;div class=&quot;card mb-3&quot; id=&quot;collapse_card652c8e&quot;&gt;
&lt;div class=&quot;card-header border-0&quot;&gt;&lt;p class=&quot;m-0&quot;&gt;&lt;button class=&quot;btn&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapse652c8e&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapse652c8e&quot;&gt;Complete Source Code of sha1sum_argparse.py&lt;/button&gt; &lt;button class=&quot;btn btn-link float-right&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapse652c8e&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapse652c8e&quot;&gt;Show/Hide&lt;/button&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;collapse652c8e&quot; class=&quot;collapse&quot; data-parent=&quot;#collapse_card652c8e&quot;&gt;&lt;div class=&quot;card-body&quot; markdown=&quot;1&quot;&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# sha1sum_argparse.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;argparse&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;hashlib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pathlib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pathlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sha1_hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hashlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sha1_hash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sha1_hash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;{sha1sum(data)}  &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{filename}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init_argparse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argparse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argparse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;usage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%(prog)s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; [OPTION] [FILE]...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Print or check SHA1 (160-bit) checksums.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;-v&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--version&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{parser.prog}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; version 1.0.0&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;files&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nargs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init_argparse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;output_sha1sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ne&quot;&gt;FileNotFoundError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;IsADirectoryError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{parser.prog}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{file}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{err.strerror}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/div&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;p&gt;To illustrate the immediate benefit you obtain by introducing &lt;code&gt;argparse&lt;/code&gt; in this program, execute the following:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python sha1sum_argparse.py --help
&lt;span class=&quot;go&quot;&gt;usage: sha1sum_argparse.py [OPTION] [FILE]...&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;Print or check SHA1 (160-bit) checksums.&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;positional arguments:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  files&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;optional arguments:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  -h, --help     show this help message and exit&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  -v, --version  show program&amp;#39;s version number and exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To delve into the details of &lt;code&gt;argparse&lt;/code&gt;, check out &lt;a href=&quot;https://realpython.com/command-line-interfaces-python-argparse/&quot;&gt;How to Build Command Line Interfaces in Python With argparse&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;getopt&quot;&gt;&lt;code&gt;getopt&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;getopt&lt;/code&gt; finds its origins in the &lt;a href=&quot;https://en.wikipedia.org/wiki/Getopt&quot;&gt;&lt;code&gt;getopt&lt;/code&gt;&lt;/a&gt; C function. It facilitates parsing the command line and handling options, option arguments, and arguments. Revisit &lt;code&gt;parse&lt;/code&gt; from &lt;code&gt;seq_parse.py&lt;/code&gt; to use &lt;code&gt;getopt&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getopt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getopt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:],&lt;/span&gt;                      &lt;span class=&quot;c1&quot;&gt;# Arguments&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&amp;#39;vhs:&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                            &lt;span class=&quot;c1&quot;&gt;# Short option definitions&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;help&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;separator=&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Long option definitions&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-v&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--version&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VERSION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-h&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--help&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-s&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--separator&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ValueError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.python.org/library/getopt.html#getopt.getopt&quot;&gt;&lt;code&gt;getopt.getopt()&lt;/code&gt;&lt;/a&gt; takes the following arguments:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The usual arguments list minus the script name, &lt;code&gt;sys.argv[1:]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;A string defining the short options&lt;/li&gt;
&lt;li&gt;A list of strings for the long options&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that a short option followed by a colon (&lt;code&gt;:&lt;/code&gt;) expects an option argument, and that a long option trailed with an equals sign (&lt;code&gt;=&lt;/code&gt;) expects an option argument.&lt;/p&gt;
&lt;p&gt;The remaining code of &lt;code&gt;seq_getopt.py&lt;/code&gt; is the same as &lt;code&gt;seq_parse.py&lt;/code&gt; and is available in the collapsed code block below:&lt;/p&gt;
&lt;div class=&quot;card mb-3&quot; id=&quot;collapse_cardb435e9&quot;&gt;
&lt;div class=&quot;card-header border-0&quot;&gt;&lt;p class=&quot;m-0&quot;&gt;&lt;button class=&quot;btn&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapseb435e9&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapseb435e9&quot;&gt;Complete Source Code of seq_getopt.py&lt;/button&gt; &lt;button class=&quot;btn btn-link float-right&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapseb435e9&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapseb435e9&quot;&gt;Show/Hide&lt;/button&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;collapseb435e9&quot; class=&quot;collapse&quot; data-parent=&quot;#collapse_cardb435e9&quot;&gt;&lt;div class=&quot;card-body&quot; markdown=&quot;1&quot;&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# seq_getopt.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;getopt&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Usage: python &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sys.argv[0]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; [--help] | [-s &amp;lt;sep&amp;gt;] [first [incr]] last&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;VERSION&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sys.argv[0]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; version 1.0.0&amp;quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getopt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getopt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                              &lt;span class=&quot;c1&quot;&gt;# Arguments&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&amp;#39;vhs:&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                            &lt;span class=&quot;c1&quot;&gt;# Short option definitions&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;help&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;separator=&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Long option definitions&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-v&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--version&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VERSION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-h&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--help&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-s&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--separator&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/div&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;p&gt;Next, you&amp;rsquo;ll take a look at some external packages that will help you parse Python command line arguments.&lt;/p&gt;
&lt;h2 id=&quot;a-few-external-python-packages&quot;&gt;A Few External Python Packages&lt;/h2&gt;
&lt;p&gt;Building upon the existing conventions you saw in this tutorial, there are a few libraries available on the &lt;a href=&quot;https://pypi.org/&quot;&gt;Python Package Index (PyPI)&lt;/a&gt; that take many more steps to facilitate the implementation and maintenance of command line interfaces.&lt;/p&gt;
&lt;p&gt;The following sections offer a glance at &lt;a href=&quot;https://click.palletsprojects.com/en/7.x/&quot;&gt;Click&lt;/a&gt; and &lt;a href=&quot;https://python-prompt-toolkit.readthedocs.io/en/master/index.html&quot;&gt;Python Prompt Toolkit&lt;/a&gt;. You&amp;rsquo;ll only be exposed to very limited capabilities of these packages, as they both would require a full tutorial&amp;mdash;if not a whole series&amp;mdash;to do them justice!&lt;/p&gt;
&lt;h3 id=&quot;click&quot;&gt;Click&lt;/h3&gt;
&lt;p&gt;As of this writing, &lt;strong&gt;Click&lt;/strong&gt; is perhaps the most advanced library to build a sophisticated command line interface for a Python program. It&amp;rsquo;s used by several Python products, most notably &lt;a href=&quot;https://palletsprojects.com/p/flask/&quot;&gt;Flask&lt;/a&gt; and &lt;a href=&quot;https://black.readthedocs.io/en/stable/&quot;&gt;Black&lt;/a&gt;. Before you try the following example, you need to install Click in either a &lt;a href=&quot;https://docs.python.org/tutorial/venv.html&quot;&gt;Python virtual environment&lt;/a&gt; or your local environment. If you&amp;rsquo;re not familiar with the concept of virtual environments, then check out &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;Python Virtual Environments: A Primer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To install Click, proceed as follows:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python -m pip install click
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So, how could Click help you handle the Python command line arguments? Here&amp;rsquo;s a variation of the &lt;code&gt;seq&lt;/code&gt; program using Click:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# seq_click.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;click&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@click&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context_settings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ignore_unknown_options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@click&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;--separator&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-s&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Text used to separate numbers (default: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;n)&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@click&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version_option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@click&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;operands&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nargs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BadParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Invalid number of arguments&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Setting &lt;a href=&quot;https://click.palletsprojects.com/en/7.x/api/#click.Context.ignore_unknown_options&quot;&gt;&lt;code&gt;ignore_unknown_options&lt;/code&gt;&lt;/a&gt; to &lt;code&gt;True&lt;/code&gt; ensures that Click doesn&amp;rsquo;t parse negative arguments as options. Negative integers are valid &lt;code&gt;seq&lt;/code&gt; arguments.&lt;/p&gt;
&lt;p&gt;As you may have observed, you get a lot for free! A few well-carved &lt;a href=&quot;https://www.python.org/dev/peps/pep-0318/&quot;&gt;decorators&lt;/a&gt; are sufficient to bury the boilerplate code, allowing you to focus on the main code, which is the content of &lt;code&gt;seq()&lt;/code&gt; in this example.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For more about Python decorators, check out &lt;a href=&quot;https://realpython.com/primer-on-python-decorators/&quot;&gt;Primer on Python Decorators&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The only import remaining is &lt;code&gt;click&lt;/code&gt;. The declarative approach of decorating the main command, &lt;code&gt;seq()&lt;/code&gt;, eliminates repetitive code that&amp;rsquo;s otherwise necessary. This could be any of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Defining&lt;/strong&gt; a help or usage procedure&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handling&lt;/strong&gt; the version of the program&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Capturing&lt;/strong&gt; and &lt;strong&gt;setting up&lt;/strong&gt; default values for options&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validating&lt;/strong&gt; arguments, including the type&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The new &lt;code&gt;seq&lt;/code&gt; implementation barely scratches the surface. Click offers many niceties that will help you craft a very professional command line interface:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Output coloring&lt;/li&gt;
&lt;li&gt;Prompt for omitted arguments&lt;/li&gt;
&lt;li&gt;Commands and sub-commands&lt;/li&gt;
&lt;li&gt;Argument type validation&lt;/li&gt;
&lt;li&gt;Callback on options and arguments&lt;/li&gt;
&lt;li&gt;File path validation&lt;/li&gt;
&lt;li&gt;Progress bar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are many other features as well. Check out &lt;a href=&quot;https://dbader.org/blog/python-commandline-tools-with-click&quot;&gt;Writing Python Command-Line Tools With Click&lt;/a&gt; to see more concrete examples based on Click.&lt;/p&gt;
&lt;h3 id=&quot;python-prompt-toolkit&quot;&gt;Python Prompt Toolkit&lt;/h3&gt;
&lt;p&gt;There are other popular Python packages that are handling the command line interface problem, like &lt;a href=&quot;https://github.com/docopt/docopt&quot;&gt;docopt for Python&lt;/a&gt;. So, you may find the choice of the &lt;a href=&quot;https://python-prompt-toolkit.readthedocs.io/en/master/index.html&quot;&gt;Prompt Toolkit&lt;/a&gt; a bit counterintuitive.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Python Prompt Toolkit&lt;/strong&gt; provides features that may make your command line application drift away from the Unix philosophy. However, it helps to bridge the gap between an arcane command line interface and a full-fledged &lt;a href=&quot;https://realpython.com/python-gui-with-wxpython/&quot;&gt;graphical user interface&lt;/a&gt;. In other words, it may help to make your tools and programs more user-friendly.&lt;/p&gt;
&lt;p&gt;You can use this tool in addition to processing Python command line arguments as in the previous examples, but this gives you a path to a UI-like approach without you having to depend on a full &lt;a href=&quot;https://wiki.python.org/moin/GuiProgramming&quot;&gt;Python UI toolkit&lt;/a&gt;. To use &lt;code&gt;prompt_toolkit&lt;/code&gt;, you need to install it with &lt;code&gt;pip&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python -m pip install prompt_toolkit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You may find the next example a bit contrived, but the intent is to spur ideas and move you slightly away from more rigorous aspects of the command line with respect to the conventions you&amp;rsquo;ve seen in this tutorial.&lt;/p&gt;
&lt;p&gt;As you&amp;rsquo;ve already seen the core logic of this example, the code snippet below only presents the code that significantly deviates from the previous examples:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;error_dlg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;message_dialog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Error&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Ensure that you enter a number&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;seq_dlg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;FIRST&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;INCREMENT&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;LAST&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_dialog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Sequence&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Enter argument &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{labels[len(operands)]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isdigit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;error_dlg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Bye&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;        

&lt;span class=&quot;n&quot;&gt;actions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;SEQUENCE&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_dlg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HELP&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;VERSION&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;button_dialog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Sequence&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Select an action:&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;buttons&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Sequence&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;SEQUENCE&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Help&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HELP&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Version&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;VERSION&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;actions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Unexpected action&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The code above involves ways to interact and possibly guide users to enter the expected input, and to validate the input interactively using three dialog boxes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;button_dialog&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;message_dialog&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;input_dialog&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The Python Prompt Toolkit exposes many other features intended to improve interaction with users. The call to the handler in &lt;code&gt;main()&lt;/code&gt; is triggered by calling a function stored in a dictionary. Check out &lt;a href=&quot;https://realpython.com/courses/emulating-switch-case-python/&quot;&gt;Emulating switch/case Statements in Python&lt;/a&gt; if you&amp;rsquo;ve never encountered this Python idiom before.&lt;/p&gt;
&lt;p&gt;You can see the full example of the program using &lt;code&gt;prompt_toolkit&lt;/code&gt; by expanding the code block below:&lt;/p&gt;
&lt;div class=&quot;card mb-3&quot; id=&quot;collapse_card7c18ed&quot;&gt;
&lt;div class=&quot;card-header border-0&quot;&gt;&lt;p class=&quot;m-0&quot;&gt;&lt;button class=&quot;btn&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapse7c18ed&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapse7c18ed&quot;&gt;Complete Source Code for seq_prompt.py&lt;/button&gt; &lt;button class=&quot;btn btn-link float-right&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapse7c18ed&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapse7c18ed&quot;&gt;Show/Hide&lt;/button&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;collapse7c18ed&quot; class=&quot;collapse&quot; data-parent=&quot;#collapse_card7c18ed&quot;&gt;&lt;div class=&quot;card-body&quot; markdown=&quot;1&quot;&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# seq_prompt.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;prompt_toolkit.shortcuts&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;button_dialog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_dialog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message_dialog&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Version 1.0.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Print numbers from FIRST to LAST, in steps of INCREMENT.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;error_dlg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;message_dialog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Error&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Ensure that you enter a number&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;seq_dlg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;FIRST&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;INCREMENT&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;LAST&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_dialog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Sequence&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Enter argument &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{labels[len(operands)]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isdigit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;error_dlg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Bye&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;        

&lt;span class=&quot;n&quot;&gt;actions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;SEQUENCE&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_dlg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HELP&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;VERSION&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;button_dialog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Sequence&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Select an action:&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;buttons&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Sequence&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;SEQUENCE&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Help&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HELP&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Version&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;VERSION&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;actions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Unexpected action&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/div&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;p&gt;When you execute the code above, you&amp;rsquo;re greeted with a dialog prompting you for action. Then, if you choose the action &lt;em&gt;Sequence&lt;/em&gt;, another dialog box is displayed. After collecting all the necessary data, options, or arguments, the dialog box disappears, and the result is printed at the command line, as in the previous examples:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/cla_prompt_toolkit-ani.068d4b790d97.gif&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/cla_prompt_toolkit-ani.068d4b790d97.gif&quot; width=&quot;490&quot; height=&quot;278&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/cla_prompt_toolkit-ani.068d4b790d97.gif&amp;amp;w=122&amp;amp;sig=551bc29adb0727dc68bc0507cca0ba335df84126 122w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/cla_prompt_toolkit-ani.068d4b790d97.gif&amp;amp;w=245&amp;amp;sig=e3b00b83e36ab0241ebb9ccc8e18a41514870a02 245w, https://files.realpython.com/media/cla_prompt_toolkit-ani.068d4b790d97.gif 490w&quot; sizes=&quot;75vw&quot; alt=&quot;Prompt Toolkit Example&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As the command line evolves and you can see some attempts to interact with users more creatively, other packages like &lt;a href=&quot;https://github.com/CITGuru/PyInquirer&quot;&gt;PyInquirer&lt;/a&gt; also allow you to capitalize on a very interactive approach.&lt;/p&gt;
&lt;p&gt;To further explore the world of the &lt;strong&gt;Text-Based User Interface (TUI)&lt;/strong&gt;, check out &lt;a href=&quot;https://realpython.com/python-print/#building-console-user-interfaces&quot;&gt;Building Console User Interfaces&lt;/a&gt; and the &lt;a href=&quot;https://realpython.com/python-print/#third-party&quot;&gt;Third Party section&lt;/a&gt; in &lt;a href=&quot;https://realpython.com/python-print/&quot;&gt;Your Guide to the Python Print Function&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re interested in researching solutions that rely exclusively on the graphical user interface, then you may consider checking out the following resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://realpython.com/python-gui-with-wxpython/&quot;&gt;How to Build a Python GUI Application With wxPython&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://realpython.com/python-pyqt-gui-calculator/&quot;&gt;Python and PyQt: Building a GUI Desktop Calculator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://realpython.com/mobile-app-kivy-python/&quot;&gt;Build a Mobile Application With the Kivy Python Framework&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this tutorial, you&amp;rsquo;ve navigated many different aspects of Python command line arguments. You should feel prepared to apply the following skills to your code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;conventions and pseudo-standards&lt;/strong&gt; of Python command line arguments&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;origins&lt;/strong&gt; of &lt;code&gt;sys.argv&lt;/code&gt; in Python&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;usage&lt;/strong&gt; of &lt;code&gt;sys.argv&lt;/code&gt; to provide flexibility in running your Python programs&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Python standard libraries&lt;/strong&gt; like &lt;code&gt;argparse&lt;/code&gt; or &lt;code&gt;getopt&lt;/code&gt; that abstract command line processing&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;powerful Python packages&lt;/strong&gt; like &lt;code&gt;click&lt;/code&gt; and &lt;code&gt;python_toolkit&lt;/code&gt; to further improve the usability of your programs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whether you&amp;rsquo;re running a small script or a complex text-based application, when you expose a &lt;strong&gt;command line interface&lt;/strong&gt; you&amp;rsquo;ll significantly improve the user experience of your Python software. In fact, you&amp;rsquo;re probably one of those users!&lt;/p&gt;
&lt;p&gt;Next time you use your application, you&amp;rsquo;ll appreciate the documentation you supplied with the &lt;code&gt;--help&lt;/code&gt; option or the fact that you can pass options and arguments instead of modifying the source code to supply different data.&lt;/p&gt;
&lt;h2 id=&quot;additional-resources&quot;&gt;Additional Resources&lt;/h2&gt;
&lt;p&gt;To gain further insights about Python command line arguments and their many facets, you may want to check out the following resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://realpython.com/comparing-python-command-line-parsing-libraries-argparse-docopt-click/&quot;&gt;Comparing Python Command-Line Parsing Libraries – Argparse, Docopt, and Click&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://realpython.com/python-ruby-and-golang-a-command-line-application-comparison/&quot;&gt;Python, Ruby, and Golang: A Command-Line Application Comparison&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You may also want to try other Python libraries that target the same problems while providing you with different solutions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://typer.tiangolo.com/&quot;&gt;Typer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://micheles.github.io/plac/&quot;&gt;Plac&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.openstack.org/cliff/latest/&quot;&gt;Cliff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://builtoncement.com/&quot;&gt;Cement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google/python-fire/&quot;&gt;Python Fire&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Sets in Python</title>
      <id>https://realpython.com/courses/sets-python/</id>
      <link href="https://realpython.com/courses/sets-python/"/>
      <updated>2020-02-04T14:00:00+00:00</updated>
      <summary>In this course, you&#39;ll learn how to work with Python&#39;s set data type. You&#39;ll see how to define set objects in Python and discover the operations that they support. By the end of this course, you&#39;ll have a good feel for when a set is an appropriate choice in your own programs.</summary>
      <content type="html">
        &lt;p&gt;In this course, you&amp;rsquo;ll learn about &lt;strong&gt;sets&lt;/strong&gt;. They&amp;rsquo;re a useful data structure that allows you to do some complex operations more easily. They come up everywhere in the real world and are important to understand.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll know:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What a set is&lt;/li&gt;
&lt;li&gt;How to define a set in Python&lt;/li&gt;
&lt;li&gt;How to operate on a set&lt;/li&gt;
&lt;li&gt;How to modify a set&lt;/li&gt;
&lt;li&gt;When to use sets&lt;/li&gt;
&lt;li&gt;Why sets are a good choice for checking membership&lt;/li&gt;
&lt;/ul&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Use a Flask Blueprint to Architect Your Applications</title>
      <id>https://realpython.com/flask-blueprint/</id>
      <link href="https://realpython.com/flask-blueprint/"/>
      <updated>2020-02-03T14:00:00+00:00</updated>
      <summary>In this tutorial, you&#39;ll learn how to use a Flask Blueprint to help you structure your application by grouping its functionality into reusable components. You&#39;ll learn what Blueprints are, how they work, and how you can use them to organize your code.</summary>
      <content type="html">
        &lt;p&gt;&lt;a href=&quot;https://palletsprojects.com/p/flask/&quot;&gt;Flask&lt;/a&gt; is a very popular web application framework that leaves almost all design and architecture decisions up to the developer. In this tutorial, you&amp;rsquo;ll learn how a &lt;strong&gt;Flask Blueprint&lt;/strong&gt;, or &lt;strong&gt;Blueprint&lt;/strong&gt; for short, can help you structure your Flask application by grouping its functionality into reusable components.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this tutorial, you&amp;rsquo;ll learn:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What Flask Blueprints are and how they work&lt;/li&gt;
&lt;li&gt;How to create and use a Flask Blueprint to organize your code&lt;/li&gt;
&lt;li&gt;How to improve code reusability using your own or a third-party Flask Blueprint&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tutorial assumes that you have some experience using Flask and that you&amp;rsquo;ve built some applications before. If you haven&amp;rsquo;t used Flask before, then check out &lt;a href=&quot;https://realpython.com/python-web-applications-with-flask-part-i/&quot;&gt;Python Web Applications with Flask (Tutorial Series)&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/discover-flask-video-tutorial/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-discover-flask-video-tutorial&quot; data-focus=&quot;false&quot;&gt;Click here to get access to a free Flask + Python video tutorial&lt;/a&gt; that shows you how to build Flask web app, step-by-step.&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;what-a-flask-application-looks-like&quot;&gt;What a Flask Application Looks Like&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start by reviewing the structure of a small Flask application. You can create a small web application by following the steps in this section. To get started, you need to install the &lt;code&gt;Flask&lt;/code&gt; Python package. You can run the following command to install Flask using &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; pip install &lt;span class=&quot;nv&quot;&gt;Flask&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;.1.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The above command installs Flask version &lt;code&gt;1.1.1&lt;/code&gt;. This is the version you&amp;rsquo;ll use throughout this tutorial, though you can apply what you&amp;rsquo;ll learn here to other versions, as well.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For more information on how to install Flask in a virtual environment and other &lt;code&gt;pip&lt;/code&gt; options, check out &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;Python Virtual Environments: A Primer&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;What Is Pip? A Guide for New Pythonistas&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;After you install Flask, you&amp;rsquo;re ready to start implementing its functionality. Since Flask doesn&amp;rsquo;t impose any restrictions on project structure, you can organize your project&amp;rsquo;s code as you want. For your first application, you can use a very straightforward layout, as shown below. A single file will contain all the application logic:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;app/
|
└── app.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The file &lt;code&gt;app.py&lt;/code&gt; will contain the definition of the application and its views.&lt;/p&gt;
&lt;p&gt;When you create a Flask application, you start by creating a &lt;code&gt;Flask&lt;/code&gt; object that represents your application, and then you associate &lt;strong&gt;views&lt;/strong&gt; to &lt;strong&gt;routes&lt;/strong&gt;. Flask takes care of dispatching incoming requests to the correct view based on the request URL and the routes you&amp;rsquo;ve defined. &lt;/p&gt;
&lt;p&gt;In Flask, views can be any callable (like a function) that receives &lt;strong&gt;requests&lt;/strong&gt; and returns the &lt;strong&gt;response&lt;/strong&gt; for that request. Flask is responsible for sending the response back to the user.&lt;/p&gt;
&lt;p&gt;The following code block is your application&amp;rsquo;s full source code:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;This is an example app&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This code creates the object &lt;code&gt;app&lt;/code&gt;, which belongs to the &lt;code&gt;Flask&lt;/code&gt; class. The view function &lt;code&gt;index()&lt;/code&gt; is linked to the route &lt;code&gt;/&lt;/code&gt; using the &lt;code&gt;app.route&lt;/code&gt; decorator. To learn more about decorators, check out &lt;a href=&quot;https://realpython.com/primer-on-python-decorators/&quot;&gt;Primer on Python Decorators&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/courses/python-decorators-101/&quot;&gt;Python Decorators 101&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can run the application with the following command:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; flask run
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By default, Flask will run the application you defined in &lt;code&gt;app.py&lt;/code&gt; on port 5000. While the application is running, go to &lt;code&gt;http://localhost:5000&lt;/code&gt; using your web browser. You&amp;rsquo;ll see a page showing the message, &lt;code&gt;This is an example app&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The chosen project layout is great for very small applications, but it doesn&amp;rsquo;t scale well. As your code grows, it can become harder for you to maintain everything in a single file. So, when your application grows in size or complexity, you may want to &lt;strong&gt;structure&lt;/strong&gt; your code in a different way to keep it maintainable and clear to understand. Throughout this tutorial, you&amp;rsquo;ll learn how to use a Flask Blueprint to achieve this.&lt;/p&gt;
&lt;h2 id=&quot;what-a-flask-blueprint-looks-like&quot;&gt;What a Flask Blueprint Looks Like&lt;/h2&gt;
&lt;p&gt;Flask Blueprints encapsulate &lt;strong&gt;functionality&lt;/strong&gt;, such as views, templates, and other resources. To get a taste for how a Flask Blueprint would work, you can refactor the previous application by moving the &lt;code&gt;index&lt;/code&gt; view into a Flask Blueprint. To do so, you have to create a Flask Blueprint that contains the &lt;code&gt;index&lt;/code&gt; view and then use it in the application.&lt;/p&gt;
&lt;p&gt;This is what the file structure looks like for this new application:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;app/
|
├── app.py
└── example_blueprint.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;example_blueprint.py&lt;/code&gt; will contain the Flask Blueprint implementation. You&amp;rsquo;ll then modify &lt;code&gt;app.py&lt;/code&gt; to use it.&lt;/p&gt;
&lt;p&gt;The following code block shows how you can implement this Flask Blueprint in &lt;code&gt;example_blueprint.py&lt;/code&gt;. It contains a view at the route &lt;code&gt;/&lt;/code&gt; that returns the text &lt;code&gt;This is an example app&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Blueprint&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;example_blueprint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;example_blueprint&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@example_blueprint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;This is an example app&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the above code, you can see the steps common to most Flask Blueprint definitions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create&lt;/strong&gt; a &lt;code&gt;Blueprint&lt;/code&gt; object called &lt;code&gt;example_blueprint&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add&lt;/strong&gt; views to &lt;code&gt;example_blueprint&lt;/code&gt; using the &lt;code&gt;route&lt;/code&gt; decorator.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following code block shows how your application imports and uses the Flask Blueprint:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;example_blueprint&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example_blueprint&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;example_blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To use any Flask Blueprint, you have to import it and then &lt;strong&gt;register&lt;/strong&gt; it in the application using &lt;code&gt;register_blueprint()&lt;/code&gt;. When a Flask Blueprint is registered, the application is extended with its contents.&lt;/p&gt;
&lt;p&gt;You can run the application with the following command:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; flask run
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;While the application is running, go to &lt;code&gt;http://localhost:5000&lt;/code&gt; using your web browser. You&amp;rsquo;ll see a page showing the message, &lt;code&gt;This is an example app&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;how-flask-blueprints-work&quot;&gt;How Flask Blueprints Work&lt;/h2&gt;
&lt;p&gt;In this section, you&amp;rsquo;ll learn in detail how a Flask Blueprint is implemented and used. Each Flask Blueprint is an &lt;strong&gt;object&lt;/strong&gt; that works very similarly to a Flask application. They both can have resources, such as static files, templates, and views that are associated with routes.&lt;/p&gt;
&lt;p&gt;However, a Flask Blueprint is not actually an application. It needs to be registered in an application before you can run it. When you register a Flask Blueprint in an application, you&amp;rsquo;re actually &lt;strong&gt;extending&lt;/strong&gt; the application with the contents of the Blueprint.&lt;/p&gt;
&lt;p&gt;This is the key concept behind any Flask Blueprint. &lt;strong&gt;They record operations to be executed later when you register them on an application.&lt;/strong&gt; For example, when you associate a view to a route in a Flask Blueprint, it records this association to be made later in the application when the Blueprint is registered.&lt;/p&gt;
&lt;h3 id=&quot;making-a-flask-blueprint&quot;&gt;Making a Flask Blueprint&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s revisit the Flask Blueprint definition that you&amp;rsquo;ve seen previously and review it in detail. The following code shows the &lt;code&gt;Blueprint&lt;/code&gt; object creation:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Blueprint&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;example_blueprint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;example_blueprint&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that in the above code, some arguments are specified when creating the &lt;code&gt;Blueprint&lt;/code&gt; object. The first argument, &lt;code&gt;&quot;example_blueprint&quot;&lt;/code&gt;, is the Blueprint&amp;rsquo;s &lt;strong&gt;name&lt;/strong&gt;, which is used by Flask&amp;rsquo;s routing mechanism. The second argument, &lt;code&gt;__name__&lt;/code&gt;, is the Blueprint&amp;rsquo;s &lt;strong&gt;import name&lt;/strong&gt;, which Flask uses to locate the Blueprint&amp;rsquo;s resources.&lt;/p&gt;
&lt;p&gt;There are other optional arguments that you can provide to alter the Blueprint&amp;rsquo;s behavior:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;static_folder:&lt;/strong&gt; the folder where the Blueprint&amp;rsquo;s static files can be found&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;static_url_path:&lt;/strong&gt; the URL to serve static files from&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;template_folder:&lt;/strong&gt; the folder containing the Blueprint&amp;rsquo;s templates&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;url_prefix:&lt;/strong&gt; the path to prepend to all of the Blueprint&amp;rsquo;s URLs&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;subdomain:&lt;/strong&gt; the subdomain that this Blueprint&amp;rsquo;s routes will match on by default&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;url_defaults:&lt;/strong&gt; a &lt;a href=&quot;https://realpython.com/courses/dictionaries-python/&quot;&gt;dictionary&lt;/a&gt; of default values that this Blueprint&amp;rsquo;s views will receive&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;root_path:&lt;/strong&gt; the Blueprint&amp;rsquo;s root directory path, whose default value is obtained from the Blueprint&amp;rsquo;s import name&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that all paths, except &lt;code&gt;root_path&lt;/code&gt;, are relative to the Blueprint&amp;rsquo;s directory.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Blueprint&lt;/code&gt; object &lt;code&gt;example_blueprint&lt;/code&gt; has methods and decorators that allow you to record operations to be executed when registering the Flask Blueprint in an application to extend it. One of the most used decorators is &lt;code&gt;route&lt;/code&gt;. It allows you to associate a view function to a URL route. The following code block shows how this decorator is used:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@example_blueprint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;This is an example app&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You decorate &lt;code&gt;index()&lt;/code&gt; using &lt;code&gt;example_blueprint.route&lt;/code&gt; and associate the function to the URL &lt;code&gt;/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Blueprint&lt;/code&gt; objects also provide other methods that you may find useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;.errorhandler()&lt;/strong&gt; to register an error handler function&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.before_request()&lt;/strong&gt; to execute an action before every request&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.after_request()&lt;/strong&gt; to execute an action after every request&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.app_template_filter()&lt;/strong&gt; to register a template filter at the application level&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can learn more about using Blueprints and the &lt;code&gt;Blueprint&lt;/code&gt; class in the &lt;a href=&quot;https://flask.palletsprojects.com/en/1.1.x/blueprints/&quot;&gt;Flask Blueprints Documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;registering-the-blueprint-in-your-application&quot;&gt;Registering the Blueprint in Your Application&lt;/h3&gt;
&lt;p&gt;Recall that a Flask Blueprint is not actually an application. When you register the Flask Blueprint in an application, you &lt;strong&gt;extend&lt;/strong&gt; the application with its contents. The following code shows how you can register the previously-created Flask Blueprint in an application:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;example_blueprint&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example_blueprint&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;example_blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you call &lt;code&gt;.register_blueprint()&lt;/code&gt;, you apply all operations recorded in the Flask Blueprint &lt;code&gt;example_blueprint&lt;/code&gt; to &lt;code&gt;app&lt;/code&gt;. Now, requests to the app for the URL &lt;code&gt;/&lt;/code&gt; will be served using &lt;code&gt;.index()&lt;/code&gt; from the Flask Blueprint.&lt;/p&gt;
&lt;p&gt;You can customize how the Flask Blueprint extends the application by providing some parameters to &lt;code&gt;register_blueprint&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;url_prefix&lt;/strong&gt; is an optional prefix for all the Blueprint&amp;rsquo;s routes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;subdomain&lt;/strong&gt; is a subdomain that Blueprint routes will match.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;url_defaults&lt;/strong&gt; is a &lt;a href=&quot;https://realpython.com/courses/python-dictionary-iteration/&quot;&gt;dictionary&lt;/a&gt; with default values for view arguments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Being able to do some customization at registration time, instead of at creation time, is particularly useful when you&amp;rsquo;re sharing the same Flask Blueprint in different projects.&lt;/p&gt;
&lt;p&gt;In this section, you&amp;rsquo;ve seen how Flask Blueprints work and how you can create them and use them. In the following sections, you&amp;rsquo;ll learn how you can leverage a Flask Blueprint to &lt;strong&gt;architect&lt;/strong&gt; your applications, structuring them into independent components. In some cases, it&amp;rsquo;s also possible for you to reuse these components in different applications to reduce development time!&lt;/p&gt;
&lt;h2 id=&quot;how-to-use-flask-blueprints-to-architect-your-applications-code&quot;&gt;How to Use Flask Blueprints to Architect Your Application&amp;rsquo;s Code&lt;/h2&gt;
&lt;p&gt;In this section, you&amp;rsquo;re going to see how you can &lt;strong&gt;refactor&lt;/strong&gt; an example application using a Flask Blueprint. The example application is an &lt;strong&gt;e-commerce&lt;/strong&gt; site with the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Visitors can sign up, log in, and recover &lt;strong&gt;passwords&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Visitors can search for &lt;strong&gt;products&lt;/strong&gt; and view their details.&lt;/li&gt;
&lt;li&gt;Users can add products to their &lt;strong&gt;cart&lt;/strong&gt; and checkout.&lt;/li&gt;
&lt;li&gt;An API enables external systems to search and retrieve &lt;strong&gt;product information&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You don&amp;rsquo;t need to care much about the details of the implementation. Instead, you&amp;rsquo;ll focus mainly on how a Flask Blueprint can be used to improve the application&amp;rsquo;s architecture.&lt;/p&gt;
&lt;h3 id=&quot;understanding-why-project-layout-matters&quot;&gt;Understanding Why Project Layout Matters&lt;/h3&gt;
&lt;p&gt;Remember, Flask does not enforce any particular project layout. It&amp;rsquo;s completely feasible to organize this application&amp;rsquo;s code as follows:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ecommerce/
|
├── static/
|   ├── logo.png
|   ├── main.css
|   ├── generic.js
|   └── product_view.js
|
├── templates/
|   ├── login.html
|   ├── forgot_password.html
|   ├── signup.html
|   ├── checkout.html
|   ├── cart_view.html
|   ├── index.html
|   ├── products_list.html
|   └── product_view.html
|
├── app.py
├── config.py
└── models.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This application&amp;rsquo;s code is organized using these directories and files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;static/&lt;/strong&gt; contains the application&amp;rsquo;s static files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;templates/&lt;/strong&gt; contains the application&amp;rsquo;s templates.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;models.py&lt;/strong&gt; contains the definition of the application&amp;rsquo;s models.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;app.py&lt;/strong&gt; contains the application logic.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;config.py&lt;/strong&gt; contains the application configuration parameters.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is an example of how many applications begin. Although this layout is pretty straightforward, it has several drawbacks that arise as the app complexity increases. For example, it will be hard for you to reuse the application logic in other projects because all the functionality is bundled in &lt;code&gt;app.py&lt;/code&gt;. If you split this functionality into modules instead, then you could &lt;strong&gt;reuse complete modules across different projects&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Also, if you have just one file for the application logic, then you would end up with a very large &lt;code&gt;app.py&lt;/code&gt; that mixes code that&amp;rsquo;s nearly unrelated. This can make it hard for you to navigate and maintain the script. &lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s more, large code files are a source of &lt;strong&gt;conflicts&lt;/strong&gt; when you&amp;rsquo;re working in a team, since everybody will be making changes to the same file. These are just a few reasons why the previous layout is only good for very small applications.&lt;/p&gt;
&lt;h3 id=&quot;organizing-your-projects&quot;&gt;Organizing Your Projects&lt;/h3&gt;
&lt;p&gt;Instead of structuring the application using the previous layout, you can leverage a Flask Blueprint to &lt;strong&gt;split the code into different modules&lt;/strong&gt;. In this section, you&amp;rsquo;ll see how to architect the previous application to make Blueprints that encapsulate related functionality. In this layout, there are five Flask Blueprints:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;API Blueprint&lt;/strong&gt; to enable external systems to search and retrieve product information&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Authentication Blueprint&lt;/strong&gt; to enable users to log in and recover their password&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cart Blueprint&lt;/strong&gt; for cart and checkout functionality&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;General Blueprint&lt;/strong&gt; for the homepage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Products Blueprint&lt;/strong&gt; for searching and viewing products&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you use a separate directory for each Flask Blueprint and its resources, then the project layout would look as follows:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ecommerce/
|
├── api/
|   ├── __init__.py
|   └── api.py
|
├── auth/
|   ├── templates/
|   |   └── auth/
|   |       ├── login.html
|   |       ├── forgot_password.html
|   |       └── signup.html
|   |
|   ├── __init__.py
|   └── auth.py
|
├── cart/
|   ├── templates/
|   |   └── cart/
|   |       ├── checkout.html
|   |       └── view.html
|   |
|   ├── __init__.py
|   └── cart.py
|
├── general/
|   ├── templates/
|   |   └── general/
|   |       └── index.html
|   |
|   ├── __init__.py
|   └── general.py
|
├── products/
|   ├── static/
|   |   └── view.js
|   |
|   ├── templates/
|   |   └── products/
|   |       ├── list.html
|   |       └── view.html
|   |
|   ├── __init__.py
|   └── products.py
|
├── static/
|   ├── logo.png
|   ├── main.css
|   └── generic.js
|
├── app.py
├── config.py
└── models.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To organize code in this way, you move all views from &lt;code&gt;app.py&lt;/code&gt; into the corresponding Flask Blueprint. You also moved templates and non-global static files. This structure makes it easier for you to find the code and resources related to a given functionality. For example, if you want to find the application logic about products, then you can go to the Products Blueprint in &lt;code&gt;products/products.py&lt;/code&gt; instead of scrolling through &lt;code&gt;app.py&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see the Products Blueprint implementation in &lt;code&gt;products/products.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;render_template&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ecommerce.models&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Product&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;products_bp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;products_bp&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;template_folder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;templates&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;static_folder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;static&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;static_url_path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;assets&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@products_bp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;render_template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;products/list.html&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@products_bp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/view/&amp;lt;int:product_id&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;render_template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;products/view.html&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This code defines the &lt;code&gt;products_bp&lt;/code&gt; Flask Blueprint and contains only the code that&amp;rsquo;s related to product functionality. Since this Flask Blueprint has its own templates, you need to specify the &lt;code&gt;template_folder&lt;/code&gt; relative to the Blueprint&amp;rsquo;s root in the &lt;code&gt;Blueprint&lt;/code&gt; object creation. Since you specify &lt;code&gt;static_folder=&#39;static&#39;&lt;/code&gt; and &lt;code&gt;static_url_path=&#39;assets&#39;&lt;/code&gt;, files in &lt;code&gt;ecommerce/products/static/&lt;/code&gt; will be served under the &lt;code&gt;/assets/&lt;/code&gt; URL.&lt;/p&gt;
&lt;p&gt;Now you can move the rest of your code&amp;rsquo;s functionality to the corresponding Flask Blueprint. In other words, you can create Blueprints for API, authentication, cart, and general functionality. Once you&amp;rsquo;ve done so, the only code left in &lt;code&gt;app.py&lt;/code&gt; will be code that deals with application initialization and Flask Blueprint registration:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ecommmerce.api.api&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;api_bp&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ecommmerce.auth.auth&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth_bp&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ecommmerce.cart.cart&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cart_bp&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ecommmerce.general.general&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;general_bp&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ecommmerce.products.products&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;products_bp&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;api_bp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url_prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/api&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auth_bp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cart_bp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url_prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/cart&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;general_bp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products_bp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url_prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/products&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, &lt;code&gt;app.py&lt;/code&gt; simply imports and registers the Blueprints to extend the application. Since you use &lt;code&gt;url_prefix&lt;/code&gt;, you can avoid URL collisions between Flask Blueprint routes. For example, the URLs &lt;code&gt;/products/&lt;/code&gt; and &lt;code&gt;/cart/&lt;/code&gt; resolve to different endpoints defined in the &lt;code&gt;products_bp&lt;/code&gt; and &lt;code&gt;cart_bp&lt;/code&gt; Blueprints for the same route, &lt;code&gt;/&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;including-templates&quot;&gt;Including Templates&lt;/h3&gt;
&lt;p&gt;In Flask, when a view renders a template, the template file is searched in all the directories that were registered in the application&amp;rsquo;s &lt;strong&gt;template search path&lt;/strong&gt;. By default, this path is &lt;code&gt;[&quot;/templates&quot;]&lt;/code&gt;, so templates are only searched for in the &lt;code&gt;/templates&lt;/code&gt; directory inside the application&amp;rsquo;s root directory.&lt;/p&gt;
&lt;p&gt;If you set the &lt;code&gt;template_folder&lt;/code&gt; argument in a Blueprint&amp;rsquo;s creation, then its templates folder is added to the application&amp;rsquo;s template search path when the Flask Blueprint is registered. However, if there are duplicated file paths under different directories that are part of the template search path, then &lt;strong&gt;one will take precedence&lt;/strong&gt;, depending on their registration order.&lt;/p&gt;
&lt;p&gt;For example, if a view requests the template &lt;code&gt;view.html&lt;/code&gt; and there are files with this same name in different directories in the template search path, then one of these will take precedence over the other. Since it may be hard to remember the precedence order, it&amp;rsquo;s best to &lt;strong&gt;avoid having files under the same path&lt;/strong&gt; in different template directories. That&amp;rsquo;s why the following structure for the templates in the application makes sense:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ecommerce/
|
└── products/
    └── templates/
        └── products/
            ├── search.html
            └── view.html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At first, it may look redundant to have the Flask Blueprint name appear twice:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;As the Blueprint&amp;rsquo;s &lt;strong&gt;root&lt;/strong&gt; directory&lt;/li&gt;
&lt;li&gt;Inside the &lt;strong&gt;templates&lt;/strong&gt; directory&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;However, know that by doing this, you can avoid possible &lt;strong&gt;template name collisions&lt;/strong&gt; between different Blueprints. Using this directory structure, any views requiring the &lt;code&gt;view.html&lt;/code&gt; template for products can use &lt;code&gt;products/view.html&lt;/code&gt; as the template file name when calling &lt;code&gt;render_template&lt;/code&gt;. This avoids conflicts with the &lt;code&gt;view.html&lt;/code&gt; that belongs to the Cart Blueprint.&lt;/p&gt;
&lt;p&gt;As a final note, it&amp;rsquo;s important to know that templates in the application&amp;rsquo;s &lt;code&gt;template&lt;/code&gt; directory have &lt;strong&gt;greater precedence&lt;/strong&gt; than those inside the Blueprint&amp;rsquo;s template directory. This can be useful to know if you want to override Flask Blueprint templates without actually modifying the template file.&lt;/p&gt;
&lt;p&gt;For example, if you wanted to override the template &lt;code&gt;products/view.html&lt;/code&gt; in the Products Blueprint, then you can accomplish this by creating a new file &lt;code&gt;products/view.html&lt;/code&gt; in the application &lt;code&gt;templates&lt;/code&gt; directory:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ecommerce/
|
├── products/
|   └── templates/
|       └── products/
|           ├── search.html
|           └── view.html
|
└── templates/
        └── products/
            └── view.html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you do this, your program will use &lt;code&gt;templates/products/view.html&lt;/code&gt; instead of &lt;code&gt;products/templates/products/view.html&lt;/code&gt; whenever a view requires the template &lt;code&gt;products/view.html&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;providing-functionality-other-than-views&quot;&gt;Providing Functionality Other Than Views&lt;/h3&gt;
&lt;p&gt;So far, you&amp;rsquo;ve only seen Blueprints that extend applications with views, but Flask Blueprints don&amp;rsquo;t have to provide just views! They can extend applications with &lt;strong&gt;templates, static files, and template filters&lt;/strong&gt;. For example, you could create a &lt;strong&gt;Flask Blueprint&lt;/strong&gt; to provide a set of icons and use it across your applications. This would be the file structure for such a Blueprint:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;app/
|
└── icons/
    ├── static/
    |   ├── add.png
    |   ├── remove.png
    |   └── save.png
    |
    ├── __init__.py
    └── icons.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;static&lt;/code&gt; folder contains the icon files and &lt;code&gt;icons.py&lt;/code&gt; is the Flask Blueprint definition.&lt;/p&gt;
&lt;p&gt;This is how &lt;code&gt;icons.py&lt;/code&gt; might look:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Blueprint&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;icons_bp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Blueprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;icons_bp&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;static_folder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;static&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;static_url_path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;icons&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This code defines the &lt;code&gt;icons_bp&lt;/code&gt; Flask Blueprint that exposes the files in the static directory under the &lt;code&gt;/icons/&lt;/code&gt; URL. Note that this Blueprint does not define any route.&lt;/p&gt;
&lt;p&gt;When you can create Blueprints that package views and other types of content, you make your code and assets more reusable across your applications. You&amp;rsquo;ll learn more about Flask Blueprint reusability in the following section.&lt;/p&gt;
&lt;h2 id=&quot;how-to-use-flask-blueprints-to-improve-code-reuse&quot;&gt;How to Use Flask Blueprints to Improve Code Reuse&lt;/h2&gt;
&lt;p&gt;Besides code organization, there&amp;rsquo;s another advantage to structuring your Flask application as a &lt;strong&gt;collection of independent components&lt;/strong&gt;. You can reuse these components even across different applications! For example, if you created a Flask Blueprint that provides functionality for a contact form, then you can reuse it in all your applications.&lt;/p&gt;
&lt;p&gt;You can also leverage Blueprints created by other developers to accelerate your work. While there&amp;rsquo;s no centralized repository for existing Flask Blueprints, you can find them using the &lt;a href=&quot;https://pypi.org&quot;&gt;Python Package Index&lt;/a&gt;, &lt;a href=&quot;https://github.com/search?q=flask+blueprint&quot;&gt;GitHub Search&lt;/a&gt;, and web search engines. You can learn more about searching PyPI packages in &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;What Is Pip? A Guide for New Pythonistas&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are various Flask Blueprints and &lt;strong&gt;Flask Extensions&lt;/strong&gt; (which are implemented using Blueprints) that provide functionality that you may find useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Admin/CRUD generation&lt;/li&gt;
&lt;li&gt;CMS functionality&lt;/li&gt;
&lt;li&gt;And more!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Instead of coding your application from scratch, you may consider searching for an existing Flask Blueprint or Extension that you can reuse. Leveraging third-party Blueprints and Extensions can help you to reduce development time and keep your focus on your application&amp;rsquo;s core logic!&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this tutorial, you&amp;rsquo;ve seen how Flask Blueprints work, how to use them, and how they can help you to organize your application&amp;rsquo;s code. Flask Blueprints are a great tool for dealing with application complexity as it increases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You&amp;rsquo;ve learned:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What &lt;strong&gt;Flask Blueprints&lt;/strong&gt; are and how they work&lt;/li&gt;
&lt;li&gt;How you can &lt;strong&gt;implement and use&lt;/strong&gt; a Flask Blueprint&lt;/li&gt;
&lt;li&gt;How Flask Blueprints can help you to &lt;strong&gt;organize&lt;/strong&gt; your application&amp;rsquo;s code&lt;/li&gt;
&lt;li&gt;How you can use Flask Blueprints to ease the &lt;strong&gt;reusability&lt;/strong&gt; of your own and third-party components&lt;/li&gt;
&lt;li&gt;How using a Flask Blueprint in your project can reduce development time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can use what you&amp;rsquo;ve learned in this tutorial to start organizing your applications as a set of blueprints. When you architect your applications this way, you&amp;rsquo;ll improve code reuse, maintainability, and teamwork!&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python Modules and Packages: An Introduction</title>
      <id>https://realpython.com/courses/python-modules-packages/</id>
      <link href="https://realpython.com/courses/python-modules-packages/"/>
      <updated>2020-01-28T14:00:00+00:00</updated>
      <summary>In this course, you&#39;ll explore Python modules and Python packages, two mechanisms that facilitate modular programming. See how to write and import modules so you can optimize the structure of your own programs and make them more maintainable.</summary>
      <content type="html">
        &lt;p&gt;In this course, you&amp;rsquo;ll learn about Python &lt;strong&gt;modules&lt;/strong&gt; and Python &lt;strong&gt;packages&lt;/strong&gt;, two mechanisms that facilitate &lt;strong&gt;modular programming&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Modular programming&lt;/strong&gt; is the process of breaking a large, unwieldy programming task into separate, smaller, more manageable subtasks or &lt;strong&gt;modules&lt;/strong&gt;.  Individual modules can then be put together like building blocks to create a larger application.&lt;/p&gt;
&lt;p&gt;Learn how to write and import modules so you can optimize the structure of your own programs and make them easier to maintain and grow.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Basic Data Types in Python</title>
      <id>https://realpython.com/courses/python-data-types/</id>
      <link href="https://realpython.com/courses/python-data-types/"/>
      <updated>2020-01-21T14:00:00+00:00</updated>
      <summary>In this course, you&#39;ll learn the basic data types that are built into Python, like numbers, strings, and Booleans. You&#39;ll also get an overview of Python&#39;s built-in functions.</summary>
      <content type="html">
        &lt;p&gt;In this step-by-step course, you&amp;rsquo;ll dig into the basic &lt;strong&gt;data types&lt;/strong&gt; that are built into Python.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You&amp;rsquo;ll learn about several basic &lt;strong&gt;numeric&lt;/strong&gt;, &lt;strong&gt;string&lt;/strong&gt;, and &lt;strong&gt;Boolean&lt;/strong&gt; types that are built into Python. &lt;/li&gt;
&lt;li&gt;You&amp;rsquo;ll see what objects of these &lt;strong&gt;types&lt;/strong&gt; look like and how you can &lt;strong&gt;represent&lt;/strong&gt; them.&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;ll get an overview of Python&amp;rsquo;s built-in &lt;strong&gt;functions&lt;/strong&gt;, which are pre-written chunks of code that you can call to do useful things.&lt;/li&gt;
&lt;/ul&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Supercharge Your Classes With Python super()</title>
      <id>https://realpython.com/courses/python-super/</id>
      <link href="https://realpython.com/courses/python-super/"/>
      <updated>2020-01-14T14:00:00+00:00</updated>
      <summary>In this step-by-step course, you&#39;ll learn how to leverage single and multiple inheritance in your object-oriented application to supercharge your classes with Python super().</summary>
      <content type="html">
        &lt;p&gt;While Python isn&amp;rsquo;t purely an object-oriented language, it&amp;rsquo;s flexible enough and powerful enough to allow you to build your applications using the &lt;strong&gt;object-oriented paradigm&lt;/strong&gt;. One of the ways in which Python achieves this is by supporting &lt;strong&gt;inheritance&lt;/strong&gt;, which it does with &lt;strong&gt;&lt;code&gt;super()&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll be able to:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compose a class&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;super()&lt;/code&gt; to access parent methods&lt;/li&gt;
&lt;li&gt;Understand single and multiple inheritance&lt;/li&gt;
&lt;/ul&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python args and kwargs: Demystified</title>
      <id>https://realpython.com/courses/python-kwargs-and-args/</id>
      <link href="https://realpython.com/courses/python-kwargs-and-args/"/>
      <updated>2020-01-07T14:00:00+00:00</updated>
      <summary>In this step-by-step course, you&#39;ll learn how to use args and kwargs in Python to add more flexibility to your functions. You&#39;ll also take a closer look at the single and double-asterisk unpacking operators, which you can use to unpack any iterable object in Python.</summary>
      <content type="html">
        &lt;p&gt;Sometimes, when you look at a function definition in Python, you might see that it takes two strange arguments: &lt;strong&gt;&lt;code&gt;*args&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;**kwargs&lt;/code&gt;&lt;/strong&gt;. If you&amp;rsquo;ve ever wondered what these peculiar variables are, or why your IDE defines them in &lt;code&gt;main()&lt;/code&gt;, then this course is for you! You&amp;rsquo;ll learn how to use args and kwargs in Python to add more flexibility to your functions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of the course, you&amp;rsquo;ll know:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt; actually mean&lt;/li&gt;
&lt;li&gt;How to use &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt; in function definitions&lt;/li&gt;
&lt;li&gt;How to use a single asterisk (&lt;code&gt;*&lt;/code&gt;) to unpack iterables&lt;/li&gt;
&lt;li&gt;How to use two asterisks (&lt;code&gt;**&lt;/code&gt;) to unpack dictionaries&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This course assumes that you already know how to define Python functions and work with &lt;a href=&quot;https://realpython.com/lessons/mutable-data-structures-lists-dictionaries/&quot;&gt;lists and dictionaries&lt;/a&gt;.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Sorting Data With Python</title>
      <id>https://realpython.com/courses/python-sorting-data/</id>
      <link href="https://realpython.com/courses/python-sorting-data/"/>
      <updated>2019-12-31T14:00:00+00:00</updated>
      <summary>In this step-by-step course, you’ll learn how to sort in Python. You&#39;ll know how to sort various types of data in different data structures, customize the order, and work with two different ways of sorting in Python.</summary>
      <content type="html">
        &lt;p&gt;All programmers will have to write code to sort items or data at some point. &lt;strong&gt;Sorting&lt;/strong&gt; can be critical to the user experience in your application, whether it&amp;rsquo;s ordering a user&amp;rsquo;s most recent activity by timestamp, or putting a list of email recipients in alphabetical order by last name. Python sorting functionality offers robust features to do basic sorting or customize ordering at a granular level. &lt;/p&gt;
&lt;p&gt;In this course, you&amp;rsquo;ll learn how to sort various types of data in different data structures, customize the order, and work with two different methods of sorting in Python. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you&amp;rsquo;ll know how to:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implement basic Python sorting and ordering on data structures&lt;/li&gt;
&lt;li&gt;Differentiate between &lt;strong&gt;&lt;code&gt;sorted()&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;.sort()&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Customize a complex sort order in your code based on unique requirements&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For this course, you&amp;rsquo;ll need a basic understanding of &lt;a href=&quot;https://realpython.com/python-lists-tuples/&quot;&gt;lists and tuples&lt;/a&gt; as well as &lt;a href=&quot;https://realpython.com/quizzes/python-sets/&quot;&gt;sets&lt;/a&gt;. Those data structures will be used in this course, and some basic operations will be performed on them. Also, this course uses Python 3, so example output might vary slightly from what you&amp;rsquo;d see if you were using Python 2.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  

</feed>
