{"title":"Real Python","link":[{"@attributes":{"href":"https:\/\/realpython.com\/atom.xml","rel":"self"}},{"@attributes":{"href":"https:\/\/realpython.com\/"}}],"updated":"2026-06-05T12:00:00+00:00","id":"https:\/\/realpython.com\/","author":{"name":"Real Python"},"entry":[{"title":"The Real Python Podcast \u2013 Episode #298: Reducing the Size of Python Docker Containers","id":"https:\/\/realpython.com\/podcasts\/rpp\/298\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/podcasts\/rpp\/298\/"}},"updated":"2026-06-05T12:00:00+00:00","summary":"How can you easily reduce the size of a Python Docker container? What are the exceptions you should catch in your code? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.","content":"\n        <p>How can you easily reduce the size of a Python Docker container? What are the exceptions you should catch in your code? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Quiz: How to Read User Input From the Keyboard in Python","id":"https:\/\/realpython.com\/quizzes\/python-keyboard-input\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/quizzes\/python-keyboard-input\/"}},"updated":"2026-06-04T12:00:00+00:00","summary":"Try your hand at reading Python keyboard input with input(), handling errors, hiding passwords, and validating with PyInputPlus.","content":"\n        <p>In this quiz, you&rsquo;ll test your understanding of <a href=\"https:\/\/realpython.com\/python-keyboard-input\/\">How to Read User Input From the Keyboard in Python<\/a>.<\/p>\n<p>By working through this quiz, you&rsquo;ll revisit the <a href=\"\/ref\/builtin-functions\/input\/\" class=\"ref-link\"><code>input()<\/code><\/a> function, type conversion, error handling with <code>try<\/code> and <code>except<\/code>, the <a href=\"\/ref\/stdlib\/getpass\/\" class=\"ref-link\"><code>getpass<\/code><\/a> module for hidden input, and the PyInputPlus library for automatic validation.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"How to Use GitHub Copilot Code Review in Pull Requests","id":"https:\/\/realpython.com\/github-copilot-code-review\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/github-copilot-code-review\/"}},"updated":"2026-06-03T14:00:00+00:00","summary":"Learn how to use GitHub Copilot code review on pull requests for AI-assisted feedback, one-click fixes, and project-specific custom instructions.","content":"\n        <div><p>GitHub offers several AI tools under the Copilot umbrella that cover your entire development workflow. Copilot can provide an AI-powered code review shortly after you open a pull request on GitHub. Rather than waiting for a teammate, you can add Copilot as a reviewer to receive context-aware feedback. With access to your entire codebase, it delivers actionable suggestions that you can apply in just a few clicks:<\/p>\n<div>\n\n\n\n\n\n<div class=\"embed-responsive rounded mb-3 bg-light\" style=\"aspect-ratio: 1920\/1080;\">\n  <video-animation data-src=\"https:\/\/stream.realpython.com\/39340f1a-fdb0-4df0-911d-1d3844a18e59\/playlist.m3u8\">\n    <video class=\"embed-responsive-item rounded video-animation--bordered\" muted loop playsinline preload=\"none\" poster=\"https:\/\/stream.realpython.com\/39340f1a-fdb0-4df0-911d-1d3844a18e59\/thumbnail.jpg\" disablepictureinpicture disableremoteplayback><\/video>\n  <\/video-animation>\n<\/div>\n\n\n<\/div>\n\n<p>Pull requests are the standard collaborative workflow provided by GitHub and similar services like GitLab to facilitate code review for projects managed with <a href=\"\/ref\/tools\/git\/\" class=\"ref-link\">Git<\/a>. A pull request, or a PR for short, is a formal request to merge code from one branch\u2014or fork\u2014into another, and it\u2019s where code review typically happens.<\/p>\n<p>In practice, code review isn\u2019t always timely or consistent. Some reviewers approve pull requests immediately without much scrutiny, while others leave long lists of minor nitpicks. It can also be difficult to find someone with the right level of experience or enough context about a specific part of the codebase. These issues are common in open-source projects as well, where reviews depend on the limited time of volunteer maintainers.<\/p>\n<p>In this tutorial, you\u2019ll learn how to leverage GitHub Copilot for <strong>AI-assisted code review<\/strong> in pull requests and how to integrate it into your workflow to get faster, more structured feedback. Whether you\u2019re working on a commercial project or contributing to an open-source one, Copilot can help you catch issues early and improve your code before it\u2019s merged.<\/p>\n<p>Think of Copilot\u2019s review as a fast first pass. It can reliably flag correctness mistakes and regressions to documented behavior, often before a human reviewer has even opened the PR.<\/p>\n<h2 id=\"prerequisites\">Prerequisites<a class=\"headerlink\" href=\"#prerequisites\" title=\"Permanent link\"><\/a><\/h2>\n<p>Before you get started with AI-assisted code reviews, make sure you have the following in place:<\/p>\n<ul>\n<li><strong>Git and GitHub Knowledge:<\/strong> You should have a basic familiarity with <a href=\"https:\/\/realpython.com\/python-git-github-intro\/\">Git and GitHub<\/a>, including how to <a href=\"https:\/\/realpython.com\/python-git-github-intro\/#branching-basics\">create branches<\/a>, <a href=\"https:\/\/docs.github.com\/en\/pull-requests\/committing-changes-to-your-project\/creating-and-editing-commits\/about-commits\">commit changes<\/a>, and <a href=\"https:\/\/docs.github.com\/en\/pull-requests\/collaborating-with-pull-requests\/proposing-changes-to-your-work-with-pull-requests\/creating-a-pull-request\">open pull requests<\/a>.<\/li>\n<li><strong>Git Client and GitHub CLI:<\/strong> You should have the <a href=\"https:\/\/git-scm.com\/docs\/git\"><code>git<\/code><\/a> client configured in your command line. Additionally, you\u2019ll need the <a href=\"https:\/\/cli.github.com\/\">GitHub CLI<\/a> tool, as it simplifies common GitHub-related tasks. Make sure you\u2019re running <a href=\"https:\/\/github.com\/cli\/cli\/releases\/tag\/v2.88.0\">v2.88.0<\/a> or later, which introduced support for <a href=\"https:\/\/github.blog\/changelog\/2026-03-11-request-copilot-code-review-from-github-cli\/\">requesting Copilot code reviews<\/a> from the command line.<\/li>\n<li><strong>GitHub Account:<\/strong> You need a GitHub account with a paid <a href=\"https:\/\/github.com\/features\/copilot\/plans\">Copilot plan<\/a> (Pro, Pro+, Business, or Enterprise). To check your subscription status, visit <a href=\"https:\/\/github.com\/settings\/copilot\">GitHub Copilot settings<\/a>.<\/li>\n<\/ul>\n<p>Depending on how you use GitHub, you may already have access to GitHub Copilot through your organization. Sometimes, you may qualify for Copilot under special conditions.<\/p>\n<p>For example, if you\u2019re a student or a teacher, or if you regularly contribute to a popular open-source project, then you might be eligible for <a href=\"https:\/\/docs.github.com\/en\/copilot\/how-tos\/manage-your-account\/get-free-access-to-copilot-pro\">free access to GitHub Copilot Pro<\/a>. Check out <a href=\"https:\/\/github.com\/education\">GitHub Education<\/a> to learn more. Keep in mind that GitHub reassesses whether you qualify for free access on a monthly basis.<\/p>\n<p>But even on the free plan, you can still try out Copilot\u2019s code review feature for 30 days at no cost. Just <a href=\"https:\/\/github.com\/github-copilot\/pro\/signup\">subscribe to GitHub Copilot Pro<\/a> and cancel before the first billing cycle begins. The trial period is a one-time offer per account, so you won\u2019t be able to start another one after the first one ends.<\/p>\n<div class=\"alert alert-primary\" role=\"alert\">\n<p><strong>Note:<\/strong> At the time of writing, GitHub has temporarily paused new paid subscriptions for Copilot due to exceptionally high demand and the associated infrastructure costs. You can read the <a href=\"https:\/\/github.blog\/news-insights\/company-news\/changes-to-github-copilot-individual-plans\/\">official announcement<\/a> on GitHub\u2019s blog to learn more.<\/p>\n<\/div>\n<p>To follow along with this tutorial, you\u2019ll also need a <strong>GitHub repository<\/strong> where you can freely create branches and pull requests. Although you can <a href=\"https:\/\/github.com\/new\">create a new repository<\/a> from scratch or <a href=\"https:\/\/github.com\/new\/import\">import one<\/a> from another Git-based hosting service, the quickest option is to download the provided supporting materials. They include a small, hands-on project you\u2019ll be working on:<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Get Your Code:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/github-copilot-code-review-code\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-github-copilot-code-review-code\" markdown>Click here to download the free sample code<\/a> you\u2019ll use to practice AI-assisted code review on a sample FastAPI pull request with GitHub Copilot.<\/p>\n<\/div>\n<div class=\"container border rounded text-wrap-pretty my-3\">\n\n  <p class=\"my-3\"><mark class=\"marker-highlight\"><strong><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span> Take the Quiz:<\/strong><\/mark> Test your knowledge with our interactive \u201cHow to Use GitHub Copilot Code Review in Pull Requests\u201d quiz. You\u2019ll receive a score upon completion to help you track your learning progress:<\/p>\n\n  <hr>\n\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center\">\n\n      <a href=\"\/quizzes\/github-copilot-code-review\/\" tabindex=\"-1\">\n        <div class=\"embed-responsive embed-responsive-16by9\">\n\n            <img class=\"card-img-top m-0 p-0 embed-responsive-item rounded\" style=\"object-fit: contain; background: #b9abe6;\" alt='A robot labeled Copilot says \"Reviewing...\" while marking bugs on a long printout fed from a machine labeled Planted Bugs with a Python logo.' src=\"https:\/\/files.realpython.com\/media\/How-to-Use-GitHub-Copilot-for-AI-assisted-Code-Review_Watermarked.2c1aa9a36a45.jpg\" width=\"1920\" height=\"1080\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-GitHub-Copilot-for-AI-assisted-Code-Review_Watermarked.2c1aa9a36a45.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-GitHub-Copilot-for-AI-assisted-Code-Review_Watermarked.2c1aa9a36a45.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-GitHub-Copilot-for-AI-assisted-Code-Review_Watermarked.2c1aa9a36a45.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-GitHub-Copilot-for-AI-assisted-Code-Review_Watermarked.2c1aa9a36a45.jpg 1920w\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\">\n\n\n          <div class=\"card-img-overlay d-flex align-items-center\">\n            <div class=\"mx-auto\">\n              <span class=\"text-light\" style=\"opacity: 0.90;\"><span class=\"icon baseline scale2x\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span><\/span>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/a>\n\n    <\/div>\n    <div class=\"col\">\n      <div class=\"mt-3 d-md-none\"><\/div> \n      <p class=\"small text-muted mb-0\"><strong>Interactive Quiz<\/strong><\/p>\n      <a href=\"\/quizzes\/github-copilot-code-review\/\" class=\"stretched-link\"><span class=\"my-0 h4\">How to Use GitHub Copilot Code Review in Pull Requests<\/span><\/a> \n      <p class=\"text-muted mb-0 small\">Test your knowledge of GitHub Copilot code review in pull requests, including custom instructions and automatic reviews.<\/p>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<p>The sample project is a real-time quiz application inspired by <a href=\"https:\/\/kahoot.it\/\">Kahoot!<\/a> and <a href=\"https:\/\/www.mentimeter.com\/\">Mentimeter<\/a>, featuring a <a href=\"https:\/\/realpython.com\/get-started-with-fastapi\/\">FastAPI<\/a> backend and a mobile-first <a href=\"https:\/\/realpython.com\/python-vs-javascript\/\">JavaScript<\/a>, <a href=\"https:\/\/realpython.com\/html-css-python\/\">HTML, and CSS<\/a> frontend. It allows you to make your own quizzes from scratch\u2014and store them in the human-readable <a href=\"https:\/\/realpython.com\/python-yaml\/\">YAML format<\/a>\u2014or generate a random quiz on the fly using <a href=\"https:\/\/realpython.com\/chatgpt-api-python\/\">ChatGPT\u2019s API<\/a>:<\/p>\n<div>\n\n\n\n\n\n<div class=\"embed-responsive rounded mb-3 bg-light\" style=\"aspect-ratio: 1920\/1080;\">\n  <video-animation data-src=\"https:\/\/stream.realpython.com\/05af2bf6-fbbe-4b92-bb78-23aee5a6e017\/playlist.m3u8\">\n    <video class=\"embed-responsive-item rounded video-animation--bordered\" muted loop playsinline preload=\"none\" poster=\"https:\/\/stream.realpython.com\/05af2bf6-fbbe-4b92-bb78-23aee5a6e017\/thumbnail.jpg\" disablepictureinpicture disableremoteplayback><\/video>\n  <\/video-animation>\n<\/div>\n\n\n<\/div>\n\n<p>Each player is assigned a randomly generated name with an emoji, such as \ud83d\udc2f Grumpy Tiger, \ud83e\udda8 Gentle Skunk, or \ud83d\udc2e Lazy Cow, to keep things light and fun. You can start the server on a local network and have your friends or family connect from their mobile devices using a <a href=\"https:\/\/realpython.com\/python-generate-qr-code\/\">QR code<\/a> or a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Personal_identification_number\">PIN<\/a>.<\/p>\n<p>Are you ready to dive in?<\/p>\n<h2 id=\"step-1-request-a-code-review-from-github-copilot\">Step 1: Request a Code Review From GitHub Copilot<a class=\"headerlink\" href=\"#step-1-request-a-code-review-from-github-copilot\" title=\"Permanent link\"><\/a><\/h2>\n<p>If you haven\u2019t already, go ahead and grab the supporting materials. The sample Git repository includes a <a href=\"https:\/\/martinfowler.com\/bliki\/FeatureBranch.html\">feature branch<\/a> with intentional code issues that GitHub Copilot can catch when you request a review. For reference, you\u2019ll also find another branch with the completed code to explore at your own pace:<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Get Your Code:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/github-copilot-code-review-code\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-github-copilot-code-review-code\" markdown>Click here to download the free sample code<\/a> you\u2019ll use to practice AI-assisted code review on a sample FastAPI pull request with GitHub Copilot.<\/p>\n<\/div>\n<p>After downloading the materials, upload the local <code>pop-quiz<\/code> repository\u2014including all branches\u2014to your GitHub account. This will create a remote copy of the repository for your own experimentation. There are several ways to accomplish this. Although you can handle most tasks through the <a href=\"https:\/\/github.com\/\">GitHub web interface<\/a>, the GitHub CLI is often faster and more convenient.<\/p>\n<p>One straightforward approach is to use the GitHub CLI (<code>gh<\/code>) alongside standard <code>git<\/code> commands. This allows you to create the repository and push all branches in just two steps once you\u2019re in the downloaded <code>pop-quiz\/<\/code> directory:<\/p>\n<\/div><h2><a href=\"https:\/\/realpython.com\/github-copilot-code-review\/?utm_source=realpython&utm_medium=rss\">Read the full article at https:\/\/realpython.com\/github-copilot-code-review\/ \u00bb<\/a><\/h2>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Quiz: How to Use GitHub Copilot Code Review in Pull Requests","id":"https:\/\/realpython.com\/quizzes\/github-copilot-code-review\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/quizzes\/github-copilot-code-review\/"}},"updated":"2026-06-03T12:00:00+00:00","summary":"Test your knowledge of GitHub Copilot code review in pull requests, including custom instructions and automatic reviews.","content":"\n        <p>In this quiz, you&rsquo;ll test your understanding of <a href=\"https:\/\/realpython.com\/github-copilot-code-review\/\">How to Use GitHub Copilot Code Review in Pull Requests<\/a>.<\/p>\n<p>By working through this quiz, you&rsquo;ll revisit how to request a review from Copilot on your pull requests, apply or push back on its suggestions, configure automatic reviews, and use custom instructions to make Copilot&rsquo;s feedback follow your team&rsquo;s conventions.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Structuring Your Python Script","id":"https:\/\/realpython.com\/courses\/structuring-your-python-script\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/courses\/structuring-your-python-script\/"}},"updated":"2026-06-02T14:00:00+00:00","summary":"Master Python script structure with best practices for shebangs, ordered imports, formatting with Ruff, constants, and a clean entry point.","content":"\n        <p>You may have begun your Python journey interactively, exploring ideas within Jupyter Notebooks or through the Python REPL. While that&rsquo;s great for quick experimentation and immediate feedback, you&rsquo;ll likely find yourself saving code into <code>.py<\/code> files. However, as your codebase grows, knowing where things should go in your script becomes increasingly important.<\/p>\n<p>Transitioning from interactive environments to structured scripts helps promote readability, enabling better collaboration and more robust development practices. This video course shows you the foundations of organizing a Python script: where the runnable bits go, how to arrange your imports, and how to refactor with constants and a fixed entry point.<\/p>\n<p><strong>By the end of this video course, you&rsquo;ll know how to:<\/strong><\/p>\n<ul>\n<li>Make a script <strong>directly executable<\/strong> on Unix-like systems with a <strong>shebang line<\/strong><\/li>\n<li>Organize your <strong>import statements<\/strong> using standard grouping conventions<\/li>\n<li>Automatically sort imports and format your code with the <strong><code>ruff<\/code><\/strong> linter<\/li>\n<li>Replace hard-coded values with meaningful <strong>constants<\/strong><\/li>\n<li>Define a clear script entry point using <code>if __name__ == \"__main__\"<\/code><\/li>\n<\/ul>\n<p>Without further ado, it&rsquo;s time to start working through a concrete script and progressively shape it into well-organized, shareable code.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Quiz: Python's Format Mini-Language for Tidy Strings","id":"https:\/\/realpython.com\/quizzes\/python-format-mini-language\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/quizzes\/python-format-mini-language\/"}},"updated":"2026-06-02T12:00:00+00:00","summary":"Test your understanding of Python's format mini-language and how to use format specifiers to align text, control precision, and tidy your strings.","content":"\n        <p>In this quiz, you&rsquo;ll test your understanding of <a href=\"https:\/\/realpython.com\/python-format-mini-language\/\">Python&rsquo;s Format Mini-Language for Tidy Strings<\/a>.<\/p>\n<p>By working through this quiz, you&rsquo;ll revisit how format specifiers work inside f-strings and <code>str.format()<\/code>, including alignment and width fields, decimal precision, type representations, thousand separators, sign handling, dynamic specifiers, and percentage formatting.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Quiz: Structuring Your Python Script","id":"https:\/\/realpython.com\/quizzes\/structuring-your-python-script\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/quizzes\/structuring-your-python-script\/"}},"updated":"2026-06-02T12:00:00+00:00","summary":"Check your understanding of Python script structure, including shebangs, import order, ruff formatting, constants, and a clean entry point.","content":"\n        <p>In this quiz, you&rsquo;ll test your understanding of the video course <a href=\"https:\/\/realpython.com\/courses\/structuring-your-python-script\/\">Structuring Your Python Script<\/a>.<\/p>\n<p>By working through this quiz, you&rsquo;ll revisit how to make a Python script executable with a shebang, organize your imports per PEP 8, automatically sort imports with <code>ruff<\/code>, and define a clear entry point using <code>if __name__ == \"__main__\"<\/code>.<\/p>\n<p>These habits help you transition from quick experiments in the REPL to writing Python scripts that are easy to read, share, and grow.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Python sleep(): How to Add Time Delays to Your Code","id":"https:\/\/realpython.com\/python-sleep\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/python-sleep\/"}},"updated":"2026-06-01T14:00:00+00:00","summary":"Learn how to use Python's sleep() function to add time delays and pause your code with time.sleep(), decorators, threads, and asyncio.","content":"\n        <div><p>Sometimes you need to make Python sleep, wait, or pause before running the next line of code. Whether you\u2019re spacing out <a href=\"https:\/\/realpython.com\/python-api\/\">API<\/a> requests, pacing a thread, or adding a delay to terminal output, Python\u2019s <code>time.sleep()<\/code> function is the standard tool:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"python\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"kn\">from<\/span><span class=\"w\"> <\/span><span class=\"nn\">time<\/span><span class=\"w\"> <\/span><span class=\"kn\">import<\/span> <span class=\"n\">sleep<\/span>\n<span class=\"n\">sleep<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>  <span class=\"c1\"># Pause execution for 3 seconds<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>Beyond <code>time.sleep()<\/code>, Python provides different ways to add time delays depending on the context, including threads, async code, and GUI applications.<\/p>\n<p><strong>By the end of this tutorial, you\u2019ll understand that:<\/strong><\/p>\n<ul>\n<li><strong><code>time.sleep()<\/code><\/strong> suspends execution for a given number of seconds, including <strong>fractional<\/strong> values like milliseconds.<\/li>\n<li><strong>Retry decorators<\/strong> use <code>time.sleep()<\/code> to add a delay between failed attempts.<\/li>\n<li><strong><code>Event.wait()<\/code><\/strong> is the preferred way to add delays in <strong>threads<\/strong> because it can be interrupted cleanly.<\/li>\n<li><strong><code>asyncio.sleep()<\/code><\/strong> pauses a single <strong>coroutine<\/strong> without blocking the rest of your async code.<\/li>\n<li><strong>GUI frameworks<\/strong> like Tkinter provide scheduling methods such as <code>.after()<\/code> to <strong>avoid freezing<\/strong> the event loop.<\/li>\n<\/ul>\n<p>The following sections cover each of these approaches with working code examples.<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Get Your Code:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/python-sleep-code\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-python-sleep-code\" markdown>Click here to download the free sample code<\/a> you\u2019ll use to add time delays to scripts, threads, async code, and GUI apps.<\/p>\n<\/div>\n<div class=\"container border rounded text-wrap-pretty my-3\">\n\n  <p class=\"my-3\"><mark class=\"marker-highlight\"><strong><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span> Take the Quiz:<\/strong><\/mark> Test your knowledge with our interactive \u201cPython time.sleep()\u201d quiz. You\u2019ll receive a score upon completion to help you track your learning progress:<\/p>\n\n  <hr>\n\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center\">\n\n      <a href=\"\/quizzes\/python-sleep\/\" tabindex=\"-1\">\n        <div class=\"embed-responsive embed-responsive-16by9\">\n\n            <img class=\"card-img-top m-0 p-0 embed-responsive-item rounded\" style=\"object-fit: contain; background: #ffc873;\" alt=\"Python sleep(): How to Add Time Delays to Your Code\" src=\"https:\/\/files.realpython.com\/media\/Python-wait-sleep-time-delays-in-Python_Watermarked.f486144e9c69.jpg\" width=\"1920\" height=\"1080\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/Python-wait-sleep-time-delays-in-Python_Watermarked.f486144e9c69.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/Python-wait-sleep-time-delays-in-Python_Watermarked.f486144e9c69.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/Python-wait-sleep-time-delays-in-Python_Watermarked.f486144e9c69.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/Python-wait-sleep-time-delays-in-Python_Watermarked.f486144e9c69.jpg 1920w\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\">\n\n\n          <div class=\"card-img-overlay d-flex align-items-center\">\n            <div class=\"mx-auto\">\n              <span class=\"text-light\" style=\"opacity: 0.90;\"><span class=\"icon baseline scale2x\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span><\/span>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/a>\n\n    <\/div>\n    <div class=\"col\">\n      <div class=\"mt-3 d-md-none\"><\/div> \n      <p class=\"small text-muted mb-0\"><strong>Interactive Quiz<\/strong><\/p>\n      <a href=\"\/quizzes\/python-sleep\/\" class=\"stretched-link\"><span class=\"my-0 h4\">Python time.sleep()<\/span><\/a> \n      <p class=\"text-muted mb-0 small\">In this quiz, you'll revisit how to add time delays to your Python programs.<\/p>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<h2 id=\"pause-execution-with-python-sleep\">Pause Execution With Python <code>sleep()<\/code><a class=\"headerlink\" href=\"#pause-execution-with-python-sleep\" title=\"Permanent link\"><\/a><\/h2>\n<p>Python has built-in support for making your program wait. The <a href=\"https:\/\/realpython.com\/python-time-module\/\"><code>time<\/code> module<\/a> has a <a href=\"https:\/\/docs.python.org\/3\/library\/time.html#time.sleep\"><code>sleep()<\/code><\/a> function that you can use to add a delay by suspending execution of the calling thread for the number of seconds you specify:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"pycon\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"kn\">import<\/span><span class=\"w\"> <\/span><span class=\"nn\">time<\/span>\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"n\">time<\/span><span class=\"o\">.<\/span><span class=\"n\">sleep<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>  <span class=\"c1\"># Sleep for 3 seconds<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>Here\u2019s a quick example of <code>time.sleep()<\/code> in action:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"python\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    <span class=\"mr-2\"><span class=\"sr-only\">Filename: <\/span><code style=\"color: inherit; background: inherit;\">coffee.py<\/code><\/span>\n    <div class=\"noselect\">\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"kn\">import<\/span><span class=\"w\"> <\/span><span class=\"nn\">time<\/span>\n\n<span class=\"nb\">print<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"Brewing coffee...\"<\/span><span class=\"p\">)<\/span>\n<span class=\"nb\">print<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"This would take like 3 secs...\"<\/span><span class=\"p\">)<\/span>\n<span class=\"hll\"><span class=\"n\">time<\/span><span class=\"o\">.<\/span><span class=\"n\">sleep<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\n<\/span><span class=\"nb\">print<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"Done! Your coffee is ready!\"<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>If you <a href=\"https:\/\/realpython.com\/run-python-scripts\/\">run this script<\/a>, you\u2019ll see a three-second pause between the messages while <code>time.sleep()<\/code> suspends execution.<\/p>\n<p>You can also pass fractional seconds to <code>time.sleep()<\/code> for finer-grained durations. Here are some common values:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"python\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"kn\">import<\/span><span class=\"w\"> <\/span><span class=\"nn\">time<\/span>\n\n<span class=\"n\">time<\/span><span class=\"o\">.<\/span><span class=\"n\">sleep<\/span><span class=\"p\">(<\/span><span class=\"mf\">0.5<\/span><span class=\"p\">)<\/span>  <span class=\"c1\"># Wait 500 milliseconds<\/span>\n<span class=\"n\">time<\/span><span class=\"o\">.<\/span><span class=\"n\">sleep<\/span><span class=\"p\">(<\/span><span class=\"mf\">0.001<\/span><span class=\"p\">)<\/span>  <span class=\"c1\"># Wait 1 millisecond<\/span>\n<span class=\"n\">time<\/span><span class=\"o\">.<\/span><span class=\"n\">sleep<\/span><span class=\"p\">(<\/span><span class=\"mf\">1.5<\/span><span class=\"p\">)<\/span>  <span class=\"c1\"># Wait 1.5 seconds<\/span>\n<span class=\"n\">time<\/span><span class=\"o\">.<\/span><span class=\"n\">sleep<\/span><span class=\"p\">(<\/span><span class=\"mi\">60<\/span><span class=\"p\">)<\/span>  <span class=\"c1\"># Wait 1 minute<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>The <code>time.sleep()<\/code> function isn\u2019t perfectly precise. The specified value acts as a <em>minimum<\/em> delay. The actual pause will almost always be slightly longer in practice due to operating system scheduler overhead and current system load.<\/p>\n<p>You can test how long the sleep lasts by using Python\u2019s <a href=\"\/ref\/stdlib\/timeit\/\" class=\"ref-link\"><code>timeit<\/code><\/a> module:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"console\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--yellow\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Shell<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">$ <\/span>python<span class=\"w\"> <\/span>-m<span class=\"w\"> <\/span>timeit<span class=\"w\"> <\/span>-n<span class=\"w\"> <\/span><span class=\"m\">3<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"import time; time.sleep(3)\"<\/span>\n<span class=\"go\">3 loops, best of 5: 3 sec per loop<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>Here, you run the <code>timeit<\/code> module with the <code>-n<\/code> parameter, which tells <code>timeit<\/code> how many times to run the statement per repeat. With the <a href=\"https:\/\/docs.python.org\/3\/library\/timeit.html#cmdoption-timeit-r\">default of five repeats<\/a>, the statement runs 15 times in total (3 \u00d7 5). <code>timeit<\/code> then reports the best time across all repeats, which is three seconds per loop, as expected.<\/p>\n<p>For a more realistic example, say you need to monitor whether a website is up. You want to check its status code periodically, but querying the server too often could overload it or get you rate-limited. You can use <code>time.sleep()<\/code> to space out the checks:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"python\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    <span class=\"mr-2\"><span class=\"sr-only\">Filename: <\/span><code style=\"color: inherit; background: inherit;\">uptime_bot.py<\/code><\/span>\n    <div class=\"noselect\">\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"kn\">import<\/span><span class=\"w\"> <\/span><span class=\"nn\">time<\/span>\n<span class=\"kn\">import<\/span><span class=\"w\"> <\/span><span class=\"nn\">urllib.request<\/span>\n<span class=\"kn\">import<\/span><span class=\"w\"> <\/span><span class=\"nn\">urllib.error<\/span>\n\n<span class=\"hll\"><span class=\"n\">CHECK_INTERVAL<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">60<\/span>  <span class=\"c1\"># Seconds between checks<\/span>\n<\/span>\n<span class=\"k\">def<\/span><span class=\"w\"> <\/span><span class=\"nf\">uptime_bot<\/span><span class=\"p\">(<\/span><span class=\"n\">url<\/span><span class=\"p\">):<\/span>\n    <span class=\"k\">while<\/span> <span class=\"kc\">True<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">urllib<\/span><span class=\"o\">.<\/span><span class=\"n\">request<\/span><span class=\"o\">.<\/span><span class=\"n\">urlopen<\/span><span class=\"p\">(<\/span><span class=\"n\">url<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">except<\/span> <span class=\"n\">urllib<\/span><span class=\"o\">.<\/span><span class=\"n\">error<\/span><span class=\"o\">.<\/span><span class=\"n\">HTTPError<\/span> <span class=\"k\">as<\/span> <span class=\"n\">e<\/span><span class=\"p\">:<\/span>\n            <span class=\"c1\"># Email admin or log<\/span>\n            <span class=\"nb\">print<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"s2\">\"HTTPError: <\/span><span class=\"si\">{<\/span><span class=\"n\">e<\/span><span class=\"o\">.<\/span><span class=\"n\">code<\/span><span class=\"si\">}<\/span><span class=\"s2\"> for <\/span><span class=\"si\">{<\/span><span class=\"n\">url<\/span><span class=\"si\">}<\/span><span class=\"s2\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">except<\/span> <span class=\"n\">urllib<\/span><span class=\"o\">.<\/span><span class=\"n\">error<\/span><span class=\"o\">.<\/span><span class=\"n\">URLError<\/span> <span class=\"k\">as<\/span> <span class=\"n\">e<\/span><span class=\"p\">:<\/span>\n            <span class=\"c1\"># Email admin or log<\/span>\n            <span class=\"nb\">print<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"s2\">\"URLError: <\/span><span class=\"si\">{<\/span><span class=\"n\">e<\/span><span class=\"o\">.<\/span><span class=\"n\">reason<\/span><span class=\"si\">}<\/span><span class=\"s2\"> for <\/span><span class=\"si\">{<\/span><span class=\"n\">url<\/span><span class=\"si\">}<\/span><span class=\"s2\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n            <span class=\"c1\"># Website is up<\/span>\n            <span class=\"nb\">print<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"s2\">\"<\/span><span class=\"si\">{<\/span><span class=\"n\">url<\/span><span class=\"si\">}<\/span><span class=\"s2\"> is up\"<\/span><span class=\"p\">)<\/span>\n<span class=\"hll\">        <span class=\"n\">time<\/span><span class=\"o\">.<\/span><span class=\"n\">sleep<\/span><span class=\"p\">(<\/span><span class=\"n\">CHECK_INTERVAL<\/span><span class=\"p\">)<\/span>\n<\/span>\n<span class=\"k\">if<\/span> <span class=\"vm\">__name__<\/span> <span class=\"o\">==<\/span> <span class=\"s2\">\"__main__\"<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">url<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"https:\/\/www.google.com\/py\"<\/span>\n    <span class=\"n\">uptime_bot<\/span><span class=\"p\">(<\/span><span class=\"n\">url<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<\/div><h2><a href=\"https:\/\/realpython.com\/python-sleep\/?utm_source=realpython&utm_medium=rss\">Read the full article at https:\/\/realpython.com\/python-sleep\/ \u00bb<\/a><\/h2>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Quiz: Regular Expressions: Regexes in Python (Part 1)","id":"https:\/\/realpython.com\/quizzes\/regex-python\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/quizzes\/regex-python\/"}},"updated":"2026-06-01T12:00:00+00:00","summary":"Test your understanding of Python regular expressions: the re module, character classes, anchors, groups, alternation, and flags.","content":"\n        <p>In this quiz, you&rsquo;ll test your understanding of\n<a href=\"https:\/\/realpython.com\/regex-python\/\">Regular Expressions: Regexes in Python (Part 1)<\/a>.<\/p>\n<p>By working through this quiz, you&rsquo;ll revisit how to use the <code>re<\/code> module to search\nfor patterns, build character classes and anchors, group and capture substrings,\nand apply flags like <code>re.IGNORECASE<\/code> to control matching behavior.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"The Real Python Podcast \u2013 Episode #297: Improving Python Through PEPs and Protocols","id":"https:\/\/realpython.com\/podcasts\/rpp\/297\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/podcasts\/rpp\/297\/"}},"updated":"2026-05-29T12:00:00+00:00","summary":"Have you ever been confused by the naming of modules you're importing from a package? Is there a standard way to organize and name your Python virtual environments? This week on the show, Brett Cannon returns to discuss the Python Enhancement Proposals (PEPs) he's been working on recently.","content":"\n        <p>Have you ever been confused by the naming of modules you're importing from a package? Is there a standard way to organize and name your Python virtual environments? This week on the show, Brett Cannon returns to discuss the Python Enhancement Proposals (PEPs) he's been working on recently.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Quiz: Python's assert: Debug and Test Your Code Like a Pro","id":"https:\/\/realpython.com\/quizzes\/python-assert-statement\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/quizzes\/python-assert-statement\/"}},"updated":"2026-05-29T12:00:00+00:00","summary":"Test your understanding of Python's assert statement. Learn when to use assertions for debugging, testing, and documenting your code.","content":"\n        <p>In this quiz, you&rsquo;ll test your understanding of\n<a href=\"https:\/\/realpython.com\/python-assert-statement\/\">Python&rsquo;s assert: Debug and Test Your Code Like a Pro<\/a>.<\/p>\n<p>By working through this quiz, you&rsquo;ll revisit how assertions help you debug, test,\nand document your code, when to disable them in production, and which common\npitfalls to avoid.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Quiz: BNF Notation: Dive Deeper Into Python's Grammar","id":"https:\/\/realpython.com\/quizzes\/python-bnf-notation\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/quizzes\/python-bnf-notation\/"}},"updated":"2026-05-28T12:00:00+00:00","summary":"Test your understanding of BNF notation and how to read Python's grammar rules in the official documentation.","content":"\n        <p>In this quiz, you&rsquo;ll test your understanding of\n<a href=\"https:\/\/realpython.com\/python-bnf-notation\/\">BNF Notation: Dive Deeper Into Python&rsquo;s Grammar<\/a>.<\/p>\n<p>By working through this quiz, you&rsquo;ll revisit how to read Python&rsquo;s grammar\nrules, recognize terminals and nonterminals, and interpret the BNF\nfragments that appear throughout the official documentation.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Sending Emails With Python","id":"https:\/\/realpython.com\/python-send-email\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/python-send-email\/"}},"updated":"2026-05-27T14:00:00+00:00","summary":"Learn how to send emails with Python using SMTP, attach files, format HTML messages, and personalize bulk emails for your contact list.","content":"\n        <div><p>You probably found this tutorial because you want to send emails with Python to automate confirmation messages, password resets, or scheduled notifications. Python\u2019s standard library covers the whole pipeline, from making a server connection to building the message and sending it to one or many recipients. This tutorial walks through every step in working code.<\/p>\n<p><strong>By the end of this tutorial, you\u2019ll understand that:<\/strong><\/p>\n<ul>\n<li>A safe testing setup uses a <strong>throwaway Gmail account<\/strong> with an <strong>app password<\/strong>, a local <code>aiosmtpd<\/code> debug server, or a privacy-focused provider like Posteo or Proton Mail.<\/li>\n<li>A secure SMTP session uses <code>.SMTP_SSL()<\/code> with <code>ssl.create_default_context()<\/code>, which <strong>validates the server certificate<\/strong> and <strong>encrypts<\/strong> your credentials and message content.<\/li>\n<li>The <code>EmailMessage<\/code> class from the <code>email<\/code> package assembles <strong>plain text<\/strong>, <strong>HTML alternatives<\/strong>, <strong>file attachments<\/strong>, and <strong>personalized fields<\/strong> through <code>.set_content()<\/code>, <code>.add_alternative()<\/code>, and <code>.add_attachment()<\/code>.<\/li>\n<li>Setting <code>msg[\"reply-to\"]<\/code> or any other RFC 5322 header on an <code>EmailMessage<\/code> routes <strong>replies<\/strong> to a different mailbox than the sender address.<\/li>\n<li>For high-volume sending, <strong>transactional email services<\/strong> like SendGrid, Mailgun, and Brevo provide deliverability, statistics, and <strong>API libraries<\/strong> that go beyond what <code>smtplib<\/code> alone offers.<\/li>\n<\/ul>\n<p>Before you jump into the code, you\u2019ll set up a throwaway email account or a local debug server so you can experiment freely without spamming real inboxes.<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Get Your Code:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/python-send-email-code\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-python-send-email-code\" markdown>Click here to download the free sample code<\/a> you\u2019ll use to learn how to send plain-text and HTML emails, attach files, and automate email delivery with Python.<\/p>\n<\/div>\n<div class=\"container border rounded text-wrap-pretty my-3\">\n\n  <p class=\"my-3\"><mark class=\"marker-highlight\"><strong><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span> Take the Quiz:<\/strong><\/mark> Test your knowledge with our interactive \u201cSending Emails With Python\u201d quiz. You\u2019ll receive a score upon completion to help you track your learning progress:<\/p>\n\n  <hr>\n\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center\">\n\n      <a href=\"\/quizzes\/python-send-email-update\/\" tabindex=\"-1\">\n        <div class=\"embed-responsive embed-responsive-16by9\">\n\n            <img class=\"card-img-top m-0 p-0 embed-responsive-item rounded\" style=\"object-fit: contain; background: #ffc873;\" alt=\"Sending Emails With Python\" src=\"https:\/\/files.realpython.com\/media\/Sending-Emails-With-Python_Watermarked.6fee62c5f3b9.jpg\" width=\"1920\" height=\"1080\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/Sending-Emails-With-Python_Watermarked.6fee62c5f3b9.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/Sending-Emails-With-Python_Watermarked.6fee62c5f3b9.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/Sending-Emails-With-Python_Watermarked.6fee62c5f3b9.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/Sending-Emails-With-Python_Watermarked.6fee62c5f3b9.jpg 1920w\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\">\n\n\n          <div class=\"card-img-overlay d-flex align-items-center\">\n            <div class=\"mx-auto\">\n              <span class=\"text-light\" style=\"opacity: 0.90;\"><span class=\"icon baseline scale2x\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span><\/span>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/a>\n\n    <\/div>\n    <div class=\"col\">\n      <div class=\"mt-3 d-md-none\"><\/div> \n      <p class=\"small text-muted mb-0\"><strong>Interactive Quiz<\/strong><\/p>\n      <a href=\"\/quizzes\/python-send-email-update\/\" class=\"stretched-link\"><span class=\"my-0 h4\">Sending Emails With Python<\/span><\/a> \n      <p class=\"text-muted mb-0 small\">Use Python's standard library to send email through secure SMTP connections, attach files, include HTML content, and route replies.<\/p>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<h2 id=\"setting-up-an-email-service\">Setting Up an Email Service<a class=\"headerlink\" href=\"#setting-up-an-email-service\" title=\"Permanent link\"><\/a><\/h2>\n<p>Email is sent from a client to an email server, and from one email server to another, using the Simple Mail Transfer Protocol, or SMTP, defined under <a href=\"https:\/\/tools.ietf.org\/html\/rfc821\">RFC 821<\/a>. Python comes with the built-in <a href=\"https:\/\/docs.python.org\/3\/library\/smtplib.html\"><code>smtplib<\/code><\/a> <a href=\"\/ref\/glossary\/module\/\" class=\"ref-link\">module<\/a>, which implements this protocol, allowing you to programmatically send email through any accessible email server.<\/p>\n<p>While you can certainly use your own email account for this tutorial, it\u2019s recommended that you set up a throwaway email account instead. There are several free and paid email services you can use. In this tutorial, you\u2019ll explore the following options:<\/p>\n<ul>\n<li><strong>Setting up a Gmail account for development:<\/strong> You\u2019ll learn how to create a dedicated testing account and use app passwords to satisfy modern security requirements.<\/li>\n<li><strong>Setting up a local SMTP server:<\/strong> You\u2019ll use the <code>aiosmtpd<\/code> library to run a server on your own machine, allowing you to inspect email content without sending any live messages.<\/li>\n<li><strong>Setting up other email accounts for development:<\/strong> You\u2019ll see how to connect to alternative services like Posteo or Proton Mail to ensure your code works across different providers.<\/li>\n<\/ul>\n<p>Understanding the distinction between secure (encrypted) and insecure (unencrypted) connections is vital. Most modern providers require encryption via SSL or TLS to protect your data, while the local debugging server uses no encryption. By the end of this section, you\u2019ll know how to choose the right connection type for your specific service choice.<\/p>\n<h3 id=\"setting-up-a-gmail-account-for-development\">Setting Up a Gmail Account for Development<a class=\"headerlink\" href=\"#setting-up-a-gmail-account-for-development\" title=\"Permanent link\"><\/a><\/h3>\n<p>To set up a Gmail account for testing your code, follow these steps:<\/p>\n<ol>\n<li><a href=\"https:\/\/accounts.google.com\/signup\">Create a new Google account<\/a>. You need to provide a name, a birthday, and a unique username for the account.<\/li>\n<li>Set up <a href=\"https:\/\/myaccount.google.com\/signinoptions\/twosv\">two-factor authentication<\/a> for the new account.<\/li>\n<li>Add a <a href=\"https:\/\/myaccount.google.com\/apppasswords\">new app password<\/a> to allow password sign-ins to the account.<\/li>\n<\/ol>\n<p>An app password is a temporary password generated by Google. Instead of using your main account password to authenticate with your username, you use the app password. You can delete and recreate app passwords whenever you like.<\/p>\n<p>App passwords allow access to Gmail when modern security measures like OAuth2 aren\u2019t available. When creating one, make sure you copy it to a secure location, as you won\u2019t be able to review it after leaving the page.<\/p>\n<p>If you don\u2019t want to use an app password, check out <a href=\"https:\/\/developers.google.com\/workspace\/gmail\/api\/quickstart\/python\">Google\u2019s documentation<\/a> on how to obtain access credentials for your Python script using the OAuth2 authorization framework.<\/p>\n<p>A nice feature of Gmail is that you can use the <code>+<\/code> sign to add modifiers to your email address right before the <code>@<\/code> sign. For example, emails sent to <code>my+person1@gmail.com<\/code> and <code>my+person2@gmail.com<\/code> will both arrive at <code>my@gmail.com<\/code>. When testing email functionality, you can use this to simulate multiple addresses that all point to the same inbox.<\/p>\n<h3 id=\"setting-up-a-local-smtp-server\">Setting Up a Local SMTP Server<a class=\"headerlink\" href=\"#setting-up-a-local-smtp-server\" title=\"Permanent link\"><\/a><\/h3>\n<p>You can test email functionality by running a local Simple Mail Transfer Protocol (SMTP) debugging server with the <a href=\"https:\/\/pypi.org\/project\/aiosmtpd\/\"><code>aiosmtpd<\/code><\/a> module. Rather than sending emails to a specific address, the local debug server discards the message after printing its content to the console. Running a local debugging server makes it unnecessary to deal with encryption of messages or use credentials to log in to an email server.<\/p>\n<div class=\"alert alert-primary\" role=\"alert\">\n<p><strong>Note:<\/strong> <code>aiosmtpd<\/code> is a third-party library that replaces the former built-in <code>smtpd<\/code> module, which was initially deprecated in Python 3.4.7. Deprecation notices were repeated in 3.5.4 and 3.6.1, and the module was eventually <a href=\"https:\/\/docs.python.org\/3\/whatsnew\/3.12.html#whatsnew312-removed\">removed in Python 3.12<\/a>, as outlined in <a href=\"https:\/\/peps.python.org\/pep-0594\/\">PEP 594<\/a>.<\/p>\n<\/div>\n<p>Install the <code>aiosmtpd<\/code> module with the following command:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"console\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--yellow\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Shell<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">$ <\/span>python<span class=\"w\"> <\/span>-m<span class=\"w\"> <\/span>pip<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>aiosmtpd\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>Then, start a local SMTP debugging server with this command:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"console\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--yellow\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Shell<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">$ <\/span>python<span class=\"w\"> <\/span>-m<span class=\"w\"> <\/span>aiosmtpd<span class=\"w\"> <\/span>-n\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<\/div><h2><a href=\"https:\/\/realpython.com\/python-send-email\/?utm_source=realpython&utm_medium=rss\">Read the full article at https:\/\/realpython.com\/python-send-email\/ \u00bb<\/a><\/h2>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Quiz: Sending Emails With Python","id":"https:\/\/realpython.com\/quizzes\/python-send-email-update\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/quizzes\/python-send-email-update\/"}},"updated":"2026-05-27T12:00:00+00:00","summary":"Use Python's standard library to send email through secure SMTP connections, attach files, include HTML content, and route replies.","content":"\n        <p>In this quiz, you&rsquo;ll test your understanding of <a href=\"https:\/\/realpython.com\/python-send-email\/\">Sending Emails With Python<\/a>.<\/p>\n<p>By working through this quiz, you&rsquo;ll revisit how to build messages with the <code>EmailMessage<\/code> class, secure your SMTP connection, attach files, send HTML alternatives, route replies to a different mailbox, and address multiple recipients at once.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Connecting LLMs to Your Data With Python MCP Servers","id":"https:\/\/realpython.com\/courses\/connecting-llms-data-python-mcp-servers\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/courses\/connecting-llms-data-python-mcp-servers\/"}},"updated":"2026-05-26T14:00:00+00:00","summary":"Build an MCP server in Python that exposes tools, resources, and prompts so AI agents like Cursor can interact with your data.","content":"\n        <p>The Model Context Protocol (MCP) is a new open protocol that allows AI models to interact with external systems in a standardized, extensible way. In this video course, you&rsquo;ll install MCP, explore its client-server architecture, and work with its core concepts: prompts, resources, and tools. You&rsquo;ll then build and test a Python MCP server that queries e-commerce data and integrate it with an AI agent in Cursor to see real tool calls in action.<\/p>\n<p><strong>By the end of this video course, you&rsquo;ll understand:<\/strong><\/p>\n<ul>\n<li>What <strong>MCP<\/strong> is and why it was created<\/li>\n<li>What MCP <strong>prompts<\/strong>, <strong>resources<\/strong>, and <strong>tools<\/strong> are<\/li>\n<li>How to build an <strong>MCP server<\/strong> with customized tools<\/li>\n<li>How to integrate your MCP server with <strong>AI agents<\/strong> like <strong>Cursor<\/strong><\/li>\n<\/ul>\n<p>You&rsquo;ll get hands-on experience with Python MCP by creating and testing MCP servers and connecting your MCP to AI tools. To keep the focus on learning MCP rather than building a complex project, you&rsquo;ll build a simple MCP server that interacts with a simulated e-commerce database. You&rsquo;ll also use Cursor&rsquo;s MCP client, which saves you from having to implement your own.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Quiz: Write More Pythonic Code","id":"https:\/\/realpython.com\/quizzes\/writing-pythonic-code\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/quizzes\/writing-pythonic-code\/"}},"updated":"2026-05-26T12:00:00+00:00","summary":"Test your understanding of Pythonic code: the Zen of Python, PEP 8, code quality, type checking, and documentation in 20 questions.","content":"\n        <p>In this quiz, you&rsquo;ll revisit the core concepts covered in the\n<a href=\"https:\/\/realpython.com\/learning-paths\/writing-pythonic-code\/\">Write More Pythonic Code<\/a> learning path:<\/p>\n<div>\n\n\n<learning-path-card data-path-id=\"writing-pythonic-code\" class=\"d-block container border rounded mb-4 shadow-sm\" data-progress-card>\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center px-3\">\n\n        <a href=\"\/learning-paths\/writing-pythonic-code\/\" aria-hidden=\"true\" tabindex=\"-1\" data-not-previewable><img loading=\"lazy\" src=\"https:\/\/files.realpython.com\/media\/pcl-Python-Best-Practices_Watermarked.c8b751435ec5.jpg\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/pcl-Python-Best-Practices_Watermarked.c8b751435ec5.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/pcl-Python-Best-Practices_Watermarked.c8b751435ec5.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/pcl-Python-Best-Practices_Watermarked.c8b751435ec5.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/pcl-Python-Best-Practices_Watermarked.c8b751435ec5.jpg 1920w\" style=\"background: #ffc873;\" class=\"rounded img-fluid w-100 my-0\" alt=\"A set of three light bulbs with Python symbols on them, followed by a rocket ascending into space\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\"><\/a>\n\n    <\/div>\n    <div class=\"col px-3 pl-sm-0 mt-3 mt-sm-0\">\n      <p class=\"small text-muted mb-0\"><strong>Learning Path<\/strong><\/p>\n      <a class=\"stretched-link\" href=\"\/learning-paths\/writing-pythonic-code\/\"><h2 class=\"my-0 h3\">Write More Pythonic Code<\/h2><\/a>\n      <p class=\"text-muted mb-0 small\">15 Resources \u22c5 <strong>Skills:<\/strong> Zen of Python, PEP 8, Application Layouts, Duck Typing, Type Checking, Type Hints, Code Documentation, MkDocs, Code Quality, Pylint<\/p>\n\n\n      <div class=\"progress mt-2\" data-progress-placeholder>\n        <div class=\"progress-bar bg-light text-black-50 small w-100\" data-progress-placeholder-bar><\/div>\n      <\/div>\n\n\n      <div class=\"progress mt-2 d-none\" data-progress-container>\n        <div class=\"progress-bar small\"\n             role=\"progressbar\"\n             data-progress-bar\n             aria-valuenow=\"0\"\n             aria-valuemin=\"0\"\n             aria-valuemax=\"100\"\n             style=\"min-width: 2.5em; cursor: default;\">\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/learning-path-card>\n<\/div>\n\n<p>The 20 questions span the Zen of Python, PEP 8 style guidelines, code quality tools, type checking, and documentation practices, giving you a way to check that you understood the most important ideas.<\/p>\n<p>Take your time and revisit any topics that feel rusty before moving on.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Quiz: Python Data Structures","id":"https:\/\/realpython.com\/quizzes\/basic-python-data-structures\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/quizzes\/basic-python-data-structures\/"}},"updated":"2026-05-26T12:00:00+00:00","summary":"Test your understanding of Python's built-in data structures: strings, lists, tuples, dictionaries, sets, sorting, and bytes in 20 questions.","content":"\n        <p>In this quiz, you&rsquo;ll revisit the core concepts covered in the\n<a href=\"https:\/\/realpython.com\/learning-paths\/basic-python-data-structures\/\">Python Data Structures<\/a> learning path:<\/p>\n<div>\n\n\n<learning-path-card data-path-id=\"basic-python-data-structures\" class=\"d-block container border rounded mb-4 shadow-sm\" data-progress-card>\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center px-3\">\n\n        <a href=\"\/learning-paths\/basic-python-data-structures\/\" aria-hidden=\"true\" tabindex=\"-1\" data-not-previewable><img loading=\"lazy\" src=\"https:\/\/files.realpython.com\/media\/pcl-Python-Tricks-Chapter-on-Data-Structures_Watermarked.01bffa7044af.jpg\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/pcl-Python-Tricks-Chapter-on-Data-Structures_Watermarked.01bffa7044af.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/pcl-Python-Tricks-Chapter-on-Data-Structures_Watermarked.01bffa7044af.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/pcl-Python-Tricks-Chapter-on-Data-Structures_Watermarked.01bffa7044af.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/pcl-Python-Tricks-Chapter-on-Data-Structures_Watermarked.01bffa7044af.jpg 1920w\" style=\"background: #abe0e6;\" class=\"rounded img-fluid w-100 my-0\" alt=\"A person pointing on a screen that transforms a digital data structure representation into a real-life one based on square objects\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\"><\/a>\n\n    <\/div>\n    <div class=\"col px-3 pl-sm-0 mt-3 mt-sm-0\">\n      <p class=\"small text-muted mb-0\"><strong>Learning Path<\/strong><\/p>\n      <a class=\"stretched-link\" href=\"\/learning-paths\/basic-python-data-structures\/\"><h2 class=\"my-0 h3\">Python Data Structures<\/h2><\/a>\n      <p class=\"text-muted mb-0 small\">24 Resources \u22c5 <strong>Skills:<\/strong> Python, Strings, Lists, Tuples, Dictionaries, Sets, List Comprehensions, range(), Bytes, Sorting<\/p>\n\n\n      <div class=\"progress mt-2\" data-progress-placeholder>\n        <div class=\"progress-bar bg-light text-black-50 small w-100\" data-progress-placeholder-bar><\/div>\n      <\/div>\n\n\n      <div class=\"progress mt-2 d-none\" data-progress-container>\n        <div class=\"progress-bar small\"\n             role=\"progressbar\"\n             data-progress-bar\n             aria-valuenow=\"0\"\n             aria-valuemin=\"0\"\n             aria-valuemax=\"100\"\n             style=\"min-width: 2.5em; cursor: default;\">\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/learning-path-card>\n<\/div>\n\n<p>The 20 questions span strings, lists, tuples, dictionaries, sets, sorting, and bytes, giving you a way to check that you understood the most important ideas.<\/p>\n<p>Take your time and revisit any topics that feel rusty before moving on to the next learning path.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"How to Make a Scatter Plot in Python With plt.scatter()","id":"https:\/\/realpython.com\/visualizing-python-plt-scatter\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/visualizing-python-plt-scatter\/"}},"updated":"2026-05-25T14:00:00+00:00","summary":"Learn how to make scatter plots in Python with plt.scatter() and customize markers by size, color, shape, and transparency.","content":"\n        <div><p>Visualizing data is a core part of analysis, and Python\u2019s most popular plotting library is <strong>Matplotlib<\/strong>. To <strong>make a scatter plot<\/strong>, you reach for <strong><code>plt.scatter()<\/code><\/strong> from Matplotlib\u2019s <strong><code>pyplot<\/code><\/strong> submodule, conventionally aliased as <strong><code>plt<\/code><\/strong>. You\u2019ll use it to build both simple two-variable charts and richly customized plots that encode several variables at once.<\/p>\n<p><strong>By the end of this tutorial, you\u2019ll understand that:<\/strong><\/p>\n<ul>\n<li>A scatter plot is created by calling <code>plt.scatter()<\/code> with two <strong>array-like sequences<\/strong> for the x and y values.<\/li>\n<li>Marker <strong>size<\/strong>, <strong>color<\/strong>, <strong>shape<\/strong>, and <strong>transparency<\/strong> are controlled by the <code>s<\/code>, <code>c<\/code>, <code>marker<\/code>, and <code>alpha<\/code> parameters.<\/li>\n<li><code>plt.scatter()<\/code> enables <strong>per-point customization<\/strong> like variable size or color, while <code>plt.plot()<\/code> with marker arguments runs <strong>faster<\/strong> for basic plots.<\/li>\n<li>A single scatter plot can represent <strong>more than two variables<\/strong> by mapping extra dimensions to <strong>marker properties<\/strong>.<\/li>\n<li>Matplotlib\u2019s <strong>plot styles<\/strong>, listed in <code>plt.style.available<\/code>, are applied with <code>plt.style.use()<\/code>.<\/li>\n<\/ul>\n<p>To get the most out of this tutorial, you should be familiar with the <a href=\"https:\/\/realpython.com\/products\/python-basics-book\/\">fundamentals of Python programming<\/a> and the basics of <a href=\"https:\/\/realpython.com\/numpy-tutorial\/\">NumPy<\/a> and its <code>ndarray<\/code> object. You don\u2019t need to be familiar with Matplotlib to follow this tutorial, but if you\u2019d like to learn more about the module, then check out <a href=\"https:\/\/realpython.com\/python-matplotlib-guide\/\">Python Plotting With Matplotlib (Guide)<\/a>.<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Get Your Code:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/visualizing-python-plt-scatter-code\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-visualizing-python-plt-scatter-code\" markdown>Click here to download the free sample code<\/a> you\u2019ll use to build customized scatter plots in Python with plt.scatter().<\/p>\n<\/div>\n<div class=\"container border rounded text-wrap-pretty my-3\">\n\n  <p class=\"my-3\"><mark class=\"marker-highlight\"><strong><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span> Take the Quiz:<\/strong><\/mark> Test your knowledge with our interactive \u201cHow to Make a Scatter Plot in Python With plt.scatter()\u201d quiz. You\u2019ll receive a score upon completion to help you track your learning progress:<\/p>\n\n  <hr>\n\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center\">\n\n      <a href=\"\/quizzes\/visualizing-python-plt-scatter\/\" tabindex=\"-1\">\n        <div class=\"embed-responsive embed-responsive-16by9\">\n\n            <img class=\"card-img-top m-0 p-0 embed-responsive-item rounded\" style=\"object-fit: contain; background: #ffc873;\" alt=\"Visualizing Data in Python Using plt.scatter()\" src=\"https:\/\/files.realpython.com\/media\/How-to-Use-plt.scatter_Watermarked.a2f94b29f841.jpg\" width=\"1920\" height=\"1080\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-plt.scatter_Watermarked.a2f94b29f841.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-plt.scatter_Watermarked.a2f94b29f841.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-plt.scatter_Watermarked.a2f94b29f841.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-plt.scatter_Watermarked.a2f94b29f841.jpg 1920w\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\">\n\n\n          <div class=\"card-img-overlay d-flex align-items-center\">\n            <div class=\"mx-auto\">\n              <span class=\"text-light\" style=\"opacity: 0.90;\"><span class=\"icon baseline scale2x\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span><\/span>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/a>\n\n    <\/div>\n    <div class=\"col\">\n      <div class=\"mt-3 d-md-none\"><\/div> \n      <p class=\"small text-muted mb-0\"><strong>Interactive Quiz<\/strong><\/p>\n      <a href=\"\/quizzes\/visualizing-python-plt-scatter\/\" class=\"stretched-link\"><span class=\"my-0 h4\">How to Make a Scatter Plot in Python With plt.scatter()<\/span><\/a> \n      <p class=\"text-muted mb-0 small\">Practice using plt.scatter() in Python to create scatter plots and encode multiple variables with marker size, color, shape, and transparency.<\/p>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<h2 id=\"how-to-make-a-scatter-plot-in-python\">How to Make a Scatter Plot in Python<a class=\"headerlink\" href=\"#how-to-make-a-scatter-plot-in-python\" title=\"Permanent link\"><\/a><\/h2>\n<p>A <a href=\"https:\/\/en.wikipedia.org\/wiki\/Scatter_plot\">scatter plot<\/a> is a visual representation of how two <a href=\"https:\/\/realpython.com\/python-variables\/\">variables<\/a> relate to each other. You can use scatter plots to explore the relationship between two variables, for example by looking for any correlation between them.<\/p>\n<p>In this section of the tutorial, you\u2019ll become familiar with creating basic scatter plots using Matplotlib. In later sections, you\u2019ll learn how to further customize your plots to represent more complex data using more than two dimensions.<\/p>\n<h3 id=\"getting-started-with-pltscatter\">Getting Started With <code>plt.scatter()<\/code><a class=\"headerlink\" href=\"#getting-started-with-pltscatter\" title=\"Permanent link\"><\/a><\/h3>\n<p>Before you can start working with <a href=\"https:\/\/matplotlib.org\/stable\/api\/_as_gen\/matplotlib.pyplot.scatter.html\"><code>plt.scatter()<\/code><\/a>, you\u2019ll need to install Matplotlib. You can do so using Python\u2019s standard package manager, <a href=\"https:\/\/realpython.com\/what-is-pip\/\"><code>pip<\/code><\/a>, by running the following command in the console:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"console\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--yellow\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Shell<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">$ <\/span>python<span class=\"w\"> <\/span>-m<span class=\"w\"> <\/span>pip<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>matplotlib\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>Now that you have Matplotlib installed, consider the following use case. A caf\u00e9 sells six different types of bottled orange drinks. The owner wants to understand the relationship between the price of the drinks and his daily sales, so he keeps track of how many of each drink he sells every day. You can visualize this relationship as follows:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"python\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"kn\">import<\/span><span class=\"w\"> <\/span><span class=\"nn\">matplotlib.pyplot<\/span><span class=\"w\"> <\/span><span class=\"k\">as<\/span><span class=\"w\"> <\/span><span class=\"nn\">plt<\/span>\n\n<span class=\"n\">price<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mf\">2.50<\/span><span class=\"p\">,<\/span> <span class=\"mf\">1.23<\/span><span class=\"p\">,<\/span> <span class=\"mf\">4.02<\/span><span class=\"p\">,<\/span> <span class=\"mf\">3.25<\/span><span class=\"p\">,<\/span> <span class=\"mf\">5.00<\/span><span class=\"p\">,<\/span> <span class=\"mf\">4.40<\/span><span class=\"p\">]<\/span>\n<span class=\"n\">sales_per_day<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">34<\/span><span class=\"p\">,<\/span> <span class=\"mi\">62<\/span><span class=\"p\">,<\/span> <span class=\"mi\">49<\/span><span class=\"p\">,<\/span> <span class=\"mi\">22<\/span><span class=\"p\">,<\/span> <span class=\"mi\">13<\/span><span class=\"p\">,<\/span> <span class=\"mi\">19<\/span><span class=\"p\">]<\/span>\n\n<span class=\"n\">plt<\/span><span class=\"o\">.<\/span><span class=\"n\">scatter<\/span><span class=\"p\">(<\/span><span class=\"n\">price<\/span><span class=\"p\">,<\/span> <span class=\"n\">sales_per_day<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">plt<\/span><span class=\"o\">.<\/span><span class=\"n\">show<\/span><span class=\"p\">()<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>In this Python script, you <a href=\"https:\/\/realpython.com\/python-import\/\">import<\/a> the <code>pyplot<\/code> submodule from Matplotlib using the alias <code>plt<\/code>. This alias is generally used by convention to shorten the module and submodule names. You then create <a href=\"https:\/\/realpython.com\/python-lists-tuples\/\">lists<\/a> with the price and average sales per day for each of the six orange drinks sold.<\/p>\n<p>Finally, you create the scatter plot by using <code>plt.scatter()<\/code> with the two variables you wish to compare as input arguments. As you\u2019re using a Python script, you also need to explicitly display the figure by using <code>plt.show()<\/code>.<\/p>\n<p>When you\u2019re using an interactive environment, such as a console or a <a href=\"https:\/\/realpython.com\/jupyter-notebook-introduction\/\">Jupyter Notebook<\/a>, you don\u2019t need to call <code>plt.show()<\/code>. All examples in this tutorial are scripts and include the call to <code>plt.show()<\/code>.<\/p>\n<p>Here\u2019s the output from this code:<\/p>\n<figure class=\"js-lightbox\"><a href=\"https:\/\/files.realpython.com\/media\/scatter_plot_drinks_1.db41b7631bc5.png\" target=\"_blank\"><img loading=\"lazy\" class=\"img-fluid mx-auto d-block w-75\" src=\"https:\/\/files.realpython.com\/media\/scatter_plot_drinks_1.db41b7631bc5.png\" width=\"1280\" height=\"960\" srcset=\"\/cdn-cgi\/image\/width=320,format=auto\/https:\/\/files.realpython.com\/media\/scatter_plot_drinks_1.db41b7631bc5.png 320w, \/cdn-cgi\/image\/width=426,format=auto\/https:\/\/files.realpython.com\/media\/scatter_plot_drinks_1.db41b7631bc5.png 426w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/scatter_plot_drinks_1.db41b7631bc5.png 640w, \/cdn-cgi\/image\/width=1280,format=auto\/https:\/\/files.realpython.com\/media\/scatter_plot_drinks_1.db41b7631bc5.png 1280w\" sizes=\"(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)\" alt=\"Scatter Plot Part 1\" data-asset=\"3544\"><\/a><\/figure>\n\n<p>This plot shows that, in general, the more expensive a drink is, the fewer items are sold. However, the drink that costs $4.02 is an outlier, suggesting that it\u2019s a particularly popular product. When using scatter plots in this way, close inspection can help you explore the relationship between variables. You can then carry out further analysis, whether it\u2019s using <a href=\"https:\/\/realpython.com\/linear-regression-in-python\/\">linear regression<\/a> or other techniques.<\/p>\n<h3 id=\"comparing-pltscatter-and-pltplot\">Comparing <code>plt.scatter()<\/code> and <code>plt.plot()<\/code><a class=\"headerlink\" href=\"#comparing-pltscatter-and-pltplot\" title=\"Permanent link\"><\/a><\/h3>\n<p>You can also produce the scatter plot shown above using another function within <code>matplotlib.pyplot<\/code>. Matplotlib\u2019s <a href=\"https:\/\/matplotlib.org\/stable\/api\/_as_gen\/matplotlib.pyplot.plot.html\"><code>plt.plot()<\/code><\/a> is a general-purpose plotting function that will allow you to create various line or marker plots.<\/p>\n<p>You can achieve the same scatter plot as the one you obtained in the section above with the following call to <code>plt.plot()<\/code>, using the same data:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"python\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"n\">plt<\/span><span class=\"o\">.<\/span><span class=\"n\">plot<\/span><span class=\"p\">(<\/span><span class=\"n\">price<\/span><span class=\"p\">,<\/span> <span class=\"n\">sales_per_day<\/span><span class=\"p\">,<\/span> <span class=\"s2\">\"o\"<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">plt<\/span><span class=\"o\">.<\/span><span class=\"n\">show<\/span><span class=\"p\">()<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>In this case, you had to include the marker <code>\"o\"<\/code> as a third argument because otherwise, <code>plt.plot()<\/code> would plot a line graph. The plot you created with this code is identical to the plot you created earlier with <code>plt.scatter()<\/code>.<\/p>\n<\/div><h2><a href=\"https:\/\/realpython.com\/visualizing-python-plt-scatter\/?utm_source=realpython&utm_medium=rss\">Read the full article at https:\/\/realpython.com\/visualizing-python-plt-scatter\/ \u00bb<\/a><\/h2>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"The Real Python Podcast \u2013 Episode #296: Managing Polars Schema Issues & Profiling GitHub Users","id":"https:\/\/realpython.com\/podcasts\/rpp\/296\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/podcasts\/rpp\/296\/"}},"updated":"2026-05-22T12:00:00+00:00","summary":"How can you avoid schema problems in your Polars data pipeline when adding new columns? How can you quickly examine a GitHub user's profile to decide how much to invest in their contributions? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.","content":"\n        <p>How can you avoid schema problems in your Polars data pipeline when adding new columns? How can you quickly examine a GitHub user's profile to decide how much to invest in their contributions? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"How to Use the Claude API in Python","id":"https:\/\/realpython.com\/claude-api-python\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/claude-api-python\/"}},"updated":"2026-05-20T14:00:00+00:00","summary":"Learn how to use the Claude API in Python to send prompts, control responses with system instructions, and get structured JSON output.","content":"\n        <div><p>The fastest way to use the Claude API in Python is to install <code>anthropic<\/code>, set your API key, and call <code>client.messages.create()<\/code>. You\u2019ll have a working response in under a minute:<\/p>\n<figure class=\"js-lightbox\"><a href=\"https:\/\/files.realpython.com\/media\/How_to_Use_the_Claude_API_in_Python_for_AI-Powered_Applications_-_screenshot.019ec0681f37.png\" target=\"_blank\"><img loading=\"lazy\" class=\"img-fluid mx-auto d-block \" src=\"https:\/\/files.realpython.com\/media\/How_to_Use_the_Claude_API_in_Python_for_AI-Powered_Applications_-_screenshot.019ec0681f37.png\" width=\"1822\" height=\"1320\" srcset=\"\/cdn-cgi\/image\/width=455,format=auto\/https:\/\/files.realpython.com\/media\/How_to_Use_the_Claude_API_in_Python_for_AI-Powered_Applications_-_screenshot.019ec0681f37.png 455w, \/cdn-cgi\/image\/width=607,format=auto\/https:\/\/files.realpython.com\/media\/How_to_Use_the_Claude_API_in_Python_for_AI-Powered_Applications_-_screenshot.019ec0681f37.png 607w, \/cdn-cgi\/image\/width=911,format=auto\/https:\/\/files.realpython.com\/media\/How_to_Use_the_Claude_API_in_Python_for_AI-Powered_Applications_-_screenshot.019ec0681f37.png 911w, \/cdn-cgi\/image\/width=1822,format=auto\/https:\/\/files.realpython.com\/media\/How_to_Use_the_Claude_API_in_Python_for_AI-Powered_Applications_-_screenshot.019ec0681f37.png 1822w\" sizes=\"(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)\" alt=\"How to Use the Claude API in Python for AI-Powered Applications\" data-asset=\"6887\"><\/a><figcaption class=\"figure-caption text-center\">Example of Using the Claude API in Python<\/figcaption><\/figure>\n\n<p><a href=\"\/ref\/ai-coding-tools\/claude\/\" class=\"ref-link\">Claude<\/a> is Anthropic\u2019s <a href=\"\/ref\/ai-coding-glossary\/llm\/\" class=\"ref-link\">large language model<\/a>, accessible via a clean <a href=\"https:\/\/realpython.com\/api-integration-in-python\/\">REST API<\/a> with an official Python SDK. Unlike heavier AI frameworks that require you to wire up multiple components before you see any output, the <code>anthropic<\/code> package gets you to a working response in a handful of lines.<\/p>\n<p>In the following steps, you\u2019ll install the <code>anthropic<\/code> SDK, call Claude from Python, shape Claude\u2019s behavior with a <a href=\"\/ref\/ai-coding-glossary\/system-prompt\/\" class=\"ref-link\">system prompt<\/a>, and then return structured <a href=\"https:\/\/realpython.com\/python-json\/\">JSON<\/a> output using a schema or <a href=\"https:\/\/realpython.com\/python-pydantic\/\">Pydantic<\/a>.<\/p>\n<div class=\"alert alert-primary\" role=\"alert\">\n<p><strong>Note:<\/strong> Claude\u2019s responses are non-deterministic, so the same prompt produces different output each time, which is expected for a large language model. Also, API calls cost money based on the number of <a href=\"\/ref\/ai-coding-glossary\/token\/\" class=\"ref-link\">tokens<\/a> processed. Keep an eye on your usage in the Claude Console as you follow along.<\/p>\n<\/div>\n<p>Each step builds on the last, and the final script is short enough to read in one sitting but complete enough to extend into a real application of your own.<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Get Your Code:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/claude-api-python-code\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-claude-api-python-code\" markdown>Click here to download the free sample code<\/a> that shows you how to use the Claude API in Python.<\/p>\n<\/div>\n<div class=\"container border rounded text-wrap-pretty my-3\">\n\n  <p class=\"my-3\"><mark class=\"marker-highlight\"><strong><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span> Take the Quiz:<\/strong><\/mark> Test your knowledge with our interactive \u201cHow to Use the Claude API in Python\u201d quiz. You\u2019ll receive a score upon completion to help you track your learning progress:<\/p>\n\n  <hr>\n\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center\">\n\n      <a href=\"\/quizzes\/claude-api-python\/\" tabindex=\"-1\">\n        <div class=\"embed-responsive embed-responsive-16by9\">\n\n            <img class=\"card-img-top m-0 p-0 embed-responsive-item rounded\" style=\"object-fit: contain; background: #abe5b2;\" alt=\"Two people at a service counter labeled Claude API, where a robot behind the window prints out a long paper response, with a Python logo on the counter.\" src=\"https:\/\/files.realpython.com\/media\/How-to-Use-the-Claude-API-in-Python-for-AI-Powered-Applications_Watermarked.2bd1f7ed4e48.jpg\" width=\"1920\" height=\"1080\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-the-Claude-API-in-Python-for-AI-Powered-Applications_Watermarked.2bd1f7ed4e48.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-the-Claude-API-in-Python-for-AI-Powered-Applications_Watermarked.2bd1f7ed4e48.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-the-Claude-API-in-Python-for-AI-Powered-Applications_Watermarked.2bd1f7ed4e48.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-the-Claude-API-in-Python-for-AI-Powered-Applications_Watermarked.2bd1f7ed4e48.jpg 1920w\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\">\n\n\n          <div class=\"card-img-overlay d-flex align-items-center\">\n            <div class=\"mx-auto\">\n              <span class=\"text-light\" style=\"opacity: 0.90;\"><span class=\"icon baseline scale2x\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span><\/span>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/a>\n\n    <\/div>\n    <div class=\"col\">\n      <div class=\"mt-3 d-md-none\"><\/div> \n      <p class=\"small text-muted mb-0\"><strong>Interactive Quiz<\/strong><\/p>\n      <a href=\"\/quizzes\/claude-api-python\/\" class=\"stretched-link\"><span class=\"my-0 h4\">How to Use the Claude API in Python<\/span><\/a> \n      <p class=\"text-muted mb-0 small\">Test your understanding of using the Claude API in Python. Send prompts, set system instructions, and return structured JSON with a schema.<\/p>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<h2 id=\"prerequisites\">Prerequisites<a class=\"headerlink\" href=\"#prerequisites\" title=\"Permanent link\"><\/a><\/h2>\n<p>Before diving in, make sure you have the following in place:<\/p>\n<ul>\n<li>\n<p><strong>Python knowledge:<\/strong> You should be comfortable with Python basics, like <a href=\"https:\/\/realpython.com\/defining-your-own-python-function\/\">defining functions<\/a>, <a href=\"https:\/\/realpython.com\/run-python-scripts\/\">running scripts<\/a> from the terminal, and working with <a href=\"\/ref\/glossary\/virtual-environment\/\" class=\"ref-link\">virtual environments<\/a>. If virtual environments are new to you, <a href=\"https:\/\/realpython.com\/python-virtual-environments-a-primer\/\">Python Virtual Environments: A Primer<\/a> has you covered before you continue.<\/p>\n<\/li>\n<li>\n<p><strong>Python 3.9 or higher:<\/strong> The <code>anthropic<\/code> SDK requires Python 3.9 as a minimum. If you\u2019re not sure which version you have, run <code>python --version<\/code> in your terminal. If you need to install or upgrade, follow the steps in the <a href=\"https:\/\/realpython.com\/installing-python\/\">guide on installing Python<\/a>.<\/p>\n<\/li>\n<li>\n<p><strong>An Anthropic account:<\/strong> You\u2019ll need an Anthropic account to generate an API key in the Claude Console. Step 1 will show you how to find and secure your key once you\u2019re in.<\/p>\n<\/li>\n<\/ul>\n<p>Don\u2019t worry if you\u2019ve never worked with an <a href=\"\/ref\/glossary\/api\/\" class=\"ref-link\">API<\/a> before. This tutorial will walk you through authentication and help you make your first request from scratch.<\/p>\n<h2 id=\"step-1-set-up-the-claude-api-in-python\">Step 1: Set Up the Claude API in Python<a class=\"headerlink\" href=\"#step-1-set-up-the-claude-api-in-python\" title=\"Permanent link\"><\/a><\/h2>\n<p>Before you can call Claude from Python, you need an API key and the <code>anthropic<\/code> package installed. By the end of this step, you\u2019ll have both, and Claude will be responding to your first prompt.<\/p>\n<h3 id=\"get-your-api-key-and-install-anthropic\">Get Your API Key and Install <code>anthropic<\/code><a class=\"headerlink\" href=\"#get-your-api-key-and-install-anthropic\" title=\"Permanent link\"><\/a><\/h3>\n<p>Log in to the <a href=\"https:\/\/console.anthropic.com\/\">Claude Console<\/a> or create a new account. If you\u2019re starting fresh, you can begin using the API after adding $5 of credits.<\/p>\n<p>Then navigate to the API Keys section. Click <em>Create Key<\/em>, give it a descriptive name like <code>real-python-tutorial<\/code>, and copy it immediately. You won\u2019t see it again after you close the dialog.<\/p>\n<div class=\"alert alert-primary\" role=\"alert\">\n<p><strong>Note:<\/strong> Never paste your API key directly into your code. Instead, store it as an <a href=\"\/ref\/stdlib\/os\/\" class=\"ref-link\">environment variable<\/a>. The <code>anthropic<\/code> SDK automatically reads it from <code>ANTHROPIC_API_KEY<\/code> at runtime, so you never need to reference it explicitly in your scripts.<\/p>\n<\/div>\n<p>Storing your key as an environment variable means it never touches your source code or version control history. The exact command depends on your operating system:<\/p>\n<ul class=\"nav nav-tabs justify-content-end js-platform-widget-tabs\" role=\"tablist\">\n\n  <li class=\"nav-item mb-0 js-platform-widget-tab-windows\" role=\"presentation\">\n    <a class=\"nav-link link-unstyled text-body active small\" id=\"windows-tab-1\" data-toggle=\"tab\" href=\"#windows-1\" role=\"tab\" aria-controls=\"windows-1\" aria-selected=\"true\"><span class=\"icon baseline text-muted mr-1\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#brands--windows\"><\/use><\/svg><\/span>Windows<\/a>\n  <\/li>\n\n\n\n\n  <li class=\"nav-item mb-0 js-platform-widget-tab-linuxmacos\" role=\"presentation\">\n    <a class=\"nav-link link-unstyled text-body small\" id=\"macos-tab-1\" data-toggle=\"tab\" href=\"#linux-macos-1\" role=\"tab\" aria-controls=\"linux-macos-1\" aria-selected=\"false\"><span class=\"icon baseline text-muted\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#v4--linux\"><\/use><\/svg><\/span><span class=\"icon baseline text-muted mr-1\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#v4--apple\"><\/use><\/svg><\/span>Linux + macOS<\/a>\n  <\/li>\n\n<\/ul>\n<div class=\"tab-content mt-2 mb-0 js-platform-widget-content\">\n<div aria-labelledby=\"windows-tab-1\" class=\"tab-pane fade show active\" id=\"windows-1\" role=\"tabpanel\">\n<code-block class=\"mb-3\" data-syntax-language=\"powershell\">\n  <div class=\"codeblock__header codeblock--yellow\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>PowerShell Script<\/span>\n    \n    <div class=\"noselect\">\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"n\">PS<\/span><span class=\"p\">&gt;<\/span> <span class=\"nv\">$env:ANTHROPIC_API_KEY<\/span><span class=\"p\">=<\/span><span class=\"s2\">\"your-api-key-here\"<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<\/div>\n<div aria-labelledby=\"linux-macos-tab-1\" class=\"tab-pane fade \" id=\"linux-macos-1\" role=\"tabpanel\">\n<code-block class=\"mb-3\" data-syntax-language=\"console\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--yellow\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Shell<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">$ <\/span><span class=\"nb\">export<\/span><span class=\"w\"> <\/span><span class=\"nv\">ANTHROPIC_API_KEY<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"your-api-key-here\"<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<\/div>\n<\/div>\n<p>With your API key stored safely, you\u2019re ready to install the SDK. Create a fresh virtual environment and activate it before installing anything. This isolation prevents the <code>anthropic<\/code> package from conflicting with your system-level tools.<\/p>\n<ul class=\"nav nav-tabs justify-content-end js-platform-widget-tabs\" role=\"tablist\">\n\n  <li class=\"nav-item mb-0 js-platform-widget-tab-windows\" role=\"presentation\">\n    <a class=\"nav-link link-unstyled text-body active small\" id=\"windows-tab-2\" data-toggle=\"tab\" href=\"#windows-2\" role=\"tab\" aria-controls=\"windows-2\" aria-selected=\"true\"><span class=\"icon baseline text-muted mr-1\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#brands--windows\"><\/use><\/svg><\/span>Windows<\/a>\n  <\/li>\n\n\n\n\n  <li class=\"nav-item mb-0 js-platform-widget-tab-linuxmacos\" role=\"presentation\">\n    <a class=\"nav-link link-unstyled text-body small\" id=\"macos-tab-2\" data-toggle=\"tab\" href=\"#linux-macos-2\" role=\"tab\" aria-controls=\"linux-macos-2\" aria-selected=\"false\"><span class=\"icon baseline text-muted\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#v4--linux\"><\/use><\/svg><\/span><span class=\"icon baseline text-muted mr-1\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#v4--apple\"><\/use><\/svg><\/span>Linux + macOS<\/a>\n  <\/li>\n\n<\/ul>\n<div class=\"tab-content mt-2 mb-0 js-platform-widget-content\">\n<div aria-labelledby=\"windows-tab-2\" class=\"tab-pane fade show active\" id=\"windows-2\" role=\"tabpanel\">\n<code-block class=\"mb-3\" data-syntax-language=\"powershell\">\n  <div class=\"codeblock__header codeblock--yellow\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>PowerShell Script<\/span>\n    \n    <div class=\"noselect\">\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"n\">PS<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">python<\/span> <span class=\"n\">-m<\/span> <span class=\"n\">venv<\/span> <span class=\"n\">venv<\/span>\n<span class=\"n\">PS<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">venv<\/span><span class=\"p\">\\<\/span><span class=\"n\">Scripts<\/span><span class=\"p\">\\<\/span><span class=\"n\">activate<\/span>\n<span class=\"p\">(<\/span><span class=\"n\">venv<\/span><span class=\"p\">)<\/span> <span class=\"n\">PS<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">python<\/span> <span class=\"n\">-m<\/span> <span class=\"n\">pip<\/span> <span class=\"n\">install<\/span> <span class=\"n\">anthropic<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<\/div>\n<div aria-labelledby=\"linux-macos-tab-2\" class=\"tab-pane fade \" id=\"linux-macos-2\" role=\"tabpanel\">\n<code-block class=\"mb-3\" data-syntax-language=\"console\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--yellow\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Shell<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">$ <\/span>python<span class=\"w\"> <\/span>-m<span class=\"w\"> <\/span>venv<span class=\"w\"> <\/span>venv\/\n<span class=\"gp\">$ <\/span><span class=\"nb\">source<\/span><span class=\"w\"> <\/span>venv\/bin\/activate\n<span class=\"gp gp-VirtualEnv\">(venv)<\/span> <span class=\"gp\">$ <\/span>python<span class=\"w\"> <\/span>-m<span class=\"w\"> <\/span>pip<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>anthropic\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<\/div>\n<\/div>\n<h3 id=\"send-your-first-prompt\">Send Your First Prompt<a class=\"headerlink\" href=\"#send-your-first-prompt\" title=\"Permanent link\"><\/a><\/h3>\n<\/div><h2><a href=\"https:\/\/realpython.com\/claude-api-python\/?utm_source=realpython&utm_medium=rss\">Read the full article at https:\/\/realpython.com\/claude-api-python\/ \u00bb<\/a><\/h2>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Tapping Into the Zen of Python","id":"https:\/\/realpython.com\/courses\/tapping-into-the-zen-of-python\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/courses\/tapping-into-the-zen-of-python\/"}},"updated":"2026-05-19T14:00:00+00:00","summary":"Explore the Zen of Python and its 19 guiding principles for writing readable, practical code. Learn its history, jokes, and meaning.","content":"\n        <p>The <strong>Zen of Python<\/strong> is a collection of 19 aphorisms that capture the guiding principles behind Python&rsquo;s design. You can display them anytime by running <code>import this<\/code> in a Python REPL. Tim Peters wrote them in 1999 as a joke, but they became an iconic part of Python culture that was even formalized as <a href=\"\/ref\/glossary\/pep\/\" class=\"ref-link\">PEP<\/a> 20.<\/p>\n<p><strong>By the end of this video course, you&rsquo;ll understand:<\/strong><\/p>\n<ul>\n<li>The Zen of Python is a <strong>humorous poem<\/strong> of 19 aphorisms describing Python&rsquo;s design philosophy<\/li>\n<li>Running <code>import this<\/code> in a Python <a href=\"\/ref\/glossary\/interpreter\/\" class=\"ref-link\">interpreter<\/a> displays the <strong>complete text<\/strong> of the Zen of Python<\/li>\n<li><strong>Tim Peters<\/strong> wrote the Zen of Python in 1999 as a tongue-in-cheek comment on a mailing list<\/li>\n<li>The aphorisms are <strong>guidelines, not strict rules<\/strong>, and some intentionally contradict each other<\/li>\n<li>The principles promote <strong>readability, simplicity, and explicitness<\/strong> while acknowledging that practicality matters<\/li>\n<\/ul>\n<p>Experienced Pythonistas often refer to the Zen of Python as a source of wisdom and guidance, especially when they want to settle an argument about certain design decisions in a piece of code. In this video course, you&rsquo;ll explore the origins of the Zen of Python, learn how to interpret its mysterious aphorisms, and discover the Easter eggs hidden within it.<\/p>\n<p>You don&rsquo;t need to be a Python master to understand the Zen of Python! But you do need to answer an important question: <strong>What exactly is the Zen of Python?<\/strong><\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Python Built-in Functions: A Complete Guide","id":"https:\/\/realpython.com\/python-built-in-functions\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/python-built-in-functions\/"}},"updated":"2026-05-18T14:00:00+00:00","summary":"Use Python's built-in functions for math, data types, iterables, and I\/O to write shorter, more Pythonic code.","content":"\n        <div><p>Python\u2019s <strong>built-in functions<\/strong> are predefined functions you can use anywhere in your code without any imports. They handle common tasks across math, data type creation, iterable processing, and input and output. Knowing which ones to reach for makes your code shorter and more <strong>Pythonic<\/strong>.<\/p>\n<p><strong>In this tutorial, you\u2019ll:<\/strong><\/p>\n<ul>\n<li>Recognize Python\u2019s <strong>built-in functions<\/strong> and the <strong>built-in scope<\/strong> they live in<\/li>\n<li>Use the right built-in for <strong>math<\/strong>, <strong>data types<\/strong>, <strong>iterables<\/strong>, and <strong>I\/O<\/strong> tasks<\/li>\n<li>Tell apart true functions and <strong>classes<\/strong> that look like functions<\/li>\n<li>Apply built-ins to solve <strong>practical problems<\/strong> without reinventing the wheel<\/li>\n<\/ul>\n<p>To get the most out of this tutorial, you\u2019ll need to be familiar with Python programming, including topics like working with built-in <a href=\"https:\/\/realpython.com\/python-data-types\/\">data types<\/a>, <a href=\"https:\/\/realpython.com\/defining-your-own-python-function\/\">functions<\/a>, <a href=\"https:\/\/realpython.com\/python-classes\/\">classes<\/a>, <a href=\"https:\/\/realpython.com\/primer-on-python-decorators\/\">decorators<\/a>, <a href=\"https:\/\/realpython.com\/python-scope-legb-rule\/\">scopes<\/a>, and the <a href=\"https:\/\/realpython.com\/python-import\/\">import<\/a> system.<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Get Your Code:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/python-built-in-functions-code\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-python-built-in-functions-code\" markdown>Click here to download the free sample code<\/a> that shows you how to use Python\u2019s built-in functions.<\/p>\n<\/div>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Get the PDF Guide:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/python-built-in-functions-cheatsheet\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-python-built-in-functions-cheatsheet\" markdown>Click here to download<\/a> a free PDF guide that gives you a complete overview of Python\u2019s built-in functions and how to use them.<\/p>\n<\/div>\n<div class=\"container border rounded text-wrap-pretty my-3\">\n\n  <p class=\"my-3\"><mark class=\"marker-highlight\"><strong><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span> Take the Quiz:<\/strong><\/mark> Test your knowledge with our interactive \u201cPython Built-in Functions: A Complete Guide\u201d quiz. You\u2019ll receive a score upon completion to help you track your learning progress:<\/p>\n\n  <hr>\n\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center\">\n\n      <a href=\"\/quizzes\/python-built-in-functions\/\" tabindex=\"-1\">\n        <div class=\"embed-responsive embed-responsive-16by9\">\n\n            <img class=\"card-img-top m-0 p-0 embed-responsive-item rounded\" style=\"object-fit: contain; background: #ff7e74;\" alt=\"Python's Built-in Functions: A Complete Exploration\" src=\"https:\/\/files.realpython.com\/media\/Pythons-Built-in-Functions-A-Quick-Exploration_Watermarked.44a8e102943b.jpg\" width=\"1920\" height=\"1080\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/Pythons-Built-in-Functions-A-Quick-Exploration_Watermarked.44a8e102943b.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/Pythons-Built-in-Functions-A-Quick-Exploration_Watermarked.44a8e102943b.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/Pythons-Built-in-Functions-A-Quick-Exploration_Watermarked.44a8e102943b.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/Pythons-Built-in-Functions-A-Quick-Exploration_Watermarked.44a8e102943b.jpg 1920w\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\">\n\n\n          <div class=\"card-img-overlay d-flex align-items-center\">\n            <div class=\"mx-auto\">\n              <span class=\"text-light\" style=\"opacity: 0.90;\"><span class=\"icon baseline scale2x\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span><\/span>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/a>\n\n    <\/div>\n    <div class=\"col\">\n      <div class=\"mt-3 d-md-none\"><\/div> \n      <p class=\"small text-muted mb-0\"><strong>Interactive Quiz<\/strong><\/p>\n      <a href=\"\/quizzes\/python-built-in-functions\/\" class=\"stretched-link\"><span class=\"my-0 h4\">Python Built-in Functions: A Complete Guide<\/span><\/a> \n      <p class=\"text-muted mb-0 small\">Test your understanding of Python's built-in functions for math, data types, iterables, and I\/O\u2014and when to reach for each one.<\/p>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<h2 id=\"built-in-functions-in-python\">Built-in Functions in Python<a class=\"headerlink\" href=\"#built-in-functions-in-python\" title=\"Permanent link\"><\/a><\/h2>\n<p>Python has several <a href=\"https:\/\/realpython.com\/defining-your-own-python-function\/\">functions<\/a> available for you to use directly from anywhere in your code. These functions are known as <a href=\"https:\/\/docs.python.org\/3\/library\/functions.html\">built-in functions<\/a> and they cover many common programming problems, from mathematical computations to Python-specific features.<\/p>\n<div class=\"alert alert-primary\" role=\"alert\">\n<p><strong>Note:<\/strong> All these functions live in the <a href=\"https:\/\/docs.python.org\/3\/library\/builtins.html\"><code>builtins<\/code><\/a> module, which Python loads at startup and exposes through the built-in scope, so you can use them anywhere without importing the module. Importing the module explicitly is useful if you know that you\u2019ll shadow a built-in name with one of your own variables or functions. Doing so keeps the original within reach as <code>builtins.name<\/code>.<\/p>\n<p>Among these built-ins, you\u2019ll also find classes with function-style names like <a href=\"\/ref\/builtin-types\/str\/\" class=\"ref-link\"><code>str<\/code><\/a>, <a href=\"\/ref\/builtin-types\/tuple\/\" class=\"ref-link\"><code>tuple<\/code><\/a>, <a href=\"\/ref\/builtin-types\/list\/\" class=\"ref-link\"><code>list<\/code><\/a>, and <a href=\"\/ref\/builtin-types\/dict\/\" class=\"ref-link\"><code>dict<\/code><\/a>, which define built-in data types. These classes are listed in the Python documentation as <em>built-in functions<\/em>, so they\u2019re covered in this tutorial too.<\/p>\n<\/div>\n<p>In this tutorial, you\u2019ll learn the basics of Python\u2019s built-in functions. By the end, you\u2019ll know what their use cases are and how they work. You\u2019ll start with the built-in functions for math computations.<\/p>\n<h2 id=\"using-math-related-built-in-functions\">Using Math-Related Built-in Functions<a class=\"headerlink\" href=\"#using-math-related-built-in-functions\" title=\"Permanent link\"><\/a><\/h2>\n<p>In Python, you\u2019ll find a few built-in functions that take care of common math operations, like computing the absolute value of a <a href=\"https:\/\/realpython.com\/python-numbers\/\">number<\/a>, calculating powers, and more. Here\u2019s a summary of the math-related built-in functions in Python:<\/p>\n<div class=\"table-responsive\">\n<table class=\"table table-hover\">\n<thead>\n<tr>\n<th>Function<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><a href=\"https:\/\/realpython.com\/python-absolute-value\/\"><code>abs()<\/code><\/a><\/td>\n<td>Calculates the absolute value of a number<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/docs.python.org\/3\/library\/functions.html#divmod\"><code>divmod()<\/code><\/a><\/td>\n<td>Computes the quotient and remainder of integer division<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/realpython.com\/python-min-and-max\/\"><code>max()<\/code><\/a><\/td>\n<td>Finds the largest of the given arguments or items in an iterable<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/realpython.com\/python-min-and-max\/\"><code>min()<\/code><\/a><\/td>\n<td>Finds the smallest of the given arguments or items in an iterable<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/docs.python.org\/3\/library\/functions.html#pow\"><code>pow()<\/code><\/a><\/td>\n<td>Raises a number to a power<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/realpython.com\/python-rounding\/#pythons-built-in-round-function\"><code>round()<\/code><\/a><\/td>\n<td>Rounds a floating-point value<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/realpython.com\/python-sum-function\/\"><code>sum()<\/code><\/a><\/td>\n<td>Sums the values in an iterable<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>In the following sections, you\u2019ll learn how these functions work and how to use them in your Python code.<\/p>\n<h3 id=\"getting-the-absolute-value-of-a-number-abs\">Getting the Absolute Value of a Number: <code>abs()<\/code><a class=\"headerlink\" href=\"#getting-the-absolute-value-of-a-number-abs\" title=\"Permanent link\"><\/a><\/h3>\n<p>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Absolute_value\">absolute value<\/a> or <strong>modulus<\/strong> of a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Real_number\">real number<\/a> is its non-negative value. In other words, the absolute value is the number without its <a href=\"https:\/\/en.wikipedia.org\/wiki\/Sign_(mathematics)\">sign<\/a>. For example, the absolute value of <em>-5<\/em> is <em>5<\/em>, and the absolute value of <em>5<\/em> is also <em>5<\/em>.<\/p>\n<div class=\"alert alert-primary\" role=\"alert\">\n<p><strong>Note:<\/strong> To learn more about <code>abs()<\/code>, check out the <a href=\"https:\/\/realpython.com\/python-absolute-value\/\">How to Find an Absolute Value in Python<\/a> tutorial.<\/p>\n<\/div>\n<p>Python\u2019s built-in <code>abs()<\/code> function allows you to quickly compute the absolute value of a <a href=\"https:\/\/realpython.com\/python-numbers\/\">number<\/a>. Here\u2019s its signature:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"python_syntax\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python Syntax<\/span>\n    \n    <div class=\"noselect\">\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"nb\">abs<\/span><span class=\"p\">(<\/span><span class=\"n\">number<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>The <code>number<\/code> argument can be any numeric value, including integers, floating-point numbers, complex numbers, fractions, and decimals. Take a look at a few examples:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"pycon\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"kn\">from<\/span><span class=\"w\"> <\/span><span class=\"nn\">decimal<\/span><span class=\"w\"> <\/span><span class=\"kn\">import<\/span> <span class=\"n\">Decimal<\/span>\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"kn\">from<\/span><span class=\"w\"> <\/span><span class=\"nn\">fractions<\/span><span class=\"w\"> <\/span><span class=\"kn\">import<\/span> <span class=\"n\">Fraction<\/span>\n\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">abs<\/span><span class=\"p\">(<\/span><span class=\"o\">-<\/span><span class=\"mi\">42<\/span><span class=\"p\">)<\/span>\n<span class=\"go\">42<\/span>\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">abs<\/span><span class=\"p\">(<\/span><span class=\"mi\">42<\/span><span class=\"p\">)<\/span>\n<span class=\"go\">42<\/span>\n\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">abs<\/span><span class=\"p\">(<\/span><span class=\"o\">-<\/span><span class=\"mf\">42.42<\/span><span class=\"p\">)<\/span>\n<span class=\"go\">42.42<\/span>\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">abs<\/span><span class=\"p\">(<\/span><span class=\"mf\">42.42<\/span><span class=\"p\">)<\/span>\n<span class=\"go\">42.42<\/span>\n\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">abs<\/span><span class=\"p\">(<\/span><span class=\"nb\">complex<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"-2+3j\"<\/span><span class=\"p\">))<\/span>\n<span class=\"go\">3.605551275463989<\/span>\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">abs<\/span><span class=\"p\">(<\/span><span class=\"nb\">complex<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"2+3j\"<\/span><span class=\"p\">))<\/span>\n<span class=\"go\">3.605551275463989<\/span>\n\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">abs<\/span><span class=\"p\">(<\/span><span class=\"n\">Fraction<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"-1\/2\"<\/span><span class=\"p\">))<\/span>\n<span class=\"go\">Fraction(1, 2)<\/span>\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">abs<\/span><span class=\"p\">(<\/span><span class=\"n\">Fraction<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"1\/2\"<\/span><span class=\"p\">))<\/span>\n<span class=\"go\">Fraction(1, 2)<\/span>\n\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">abs<\/span><span class=\"p\">(<\/span><span class=\"n\">Decimal<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"-0.5\"<\/span><span class=\"p\">))<\/span>\n<span class=\"go\">Decimal('0.5')<\/span>\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">abs<\/span><span class=\"p\">(<\/span><span class=\"n\">Decimal<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"0.5\"<\/span><span class=\"p\">))<\/span>\n<span class=\"go\">Decimal('0.5')<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>In these examples, you compute the absolute value of different numeric types using the <code>abs()<\/code> function. First, you use integer numbers, then floating-point and complex numbers, and finally, fractional and decimal numbers. In all cases, when you call the function with a negative value, the final result removes the sign.<\/p>\n<p>For a practical example, say that you need to compute the total profits and losses of your company from a month\u2019s transactions:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"pycon\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"n\">transactions<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"o\">-<\/span><span class=\"mi\">200<\/span><span class=\"p\">,<\/span> <span class=\"mi\">300<\/span><span class=\"p\">,<\/span> <span class=\"o\">-<\/span><span class=\"mi\">100<\/span><span class=\"p\">,<\/span> <span class=\"mi\">500<\/span><span class=\"p\">]<\/span>\n\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"n\">incomes<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">sum<\/span><span class=\"p\">(<\/span><span class=\"n\">income<\/span> <span class=\"k\">for<\/span> <span class=\"n\">income<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">transactions<\/span> <span class=\"k\">if<\/span> <span class=\"n\">income<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"n\">expenses<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">abs<\/span><span class=\"p\">(<\/span>\n<span class=\"hll\"><span class=\"gp\">... <\/span>    <span class=\"nb\">sum<\/span><span class=\"p\">(<\/span><span class=\"n\">expense<\/span> <span class=\"k\">for<\/span> <span class=\"n\">expense<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">transactions<\/span> <span class=\"k\">if<\/span> <span class=\"n\">expense<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\n<\/span><span class=\"gp\">... <\/span><span class=\"p\">)<\/span>\n\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">print<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"s2\">\"Total incomes: $<\/span><span class=\"si\">{<\/span><span class=\"n\">incomes<\/span><span class=\"si\">}<\/span><span class=\"s2\">\"<\/span><span class=\"p\">)<\/span>\n<span class=\"go\">Total incomes: $800<\/span>\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">print<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"s2\">\"Total expenses: $<\/span><span class=\"si\">{<\/span><span class=\"n\">expenses<\/span><span class=\"si\">}<\/span><span class=\"s2\">\"<\/span><span class=\"p\">)<\/span>\n<span class=\"go\">Total expenses: $300<\/span>\n<span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"nb\">print<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"s2\">\"Total profit: $<\/span><span class=\"si\">{<\/span><span class=\"n\">incomes<\/span><span class=\"w\"> <\/span><span class=\"o\">-<\/span><span class=\"w\"> <\/span><span class=\"n\">expenses<\/span><span class=\"si\">}<\/span><span class=\"s2\">\"<\/span><span class=\"p\">)<\/span>\n<span class=\"go\">Total profit: $500<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<\/div><h2><a href=\"https:\/\/realpython.com\/python-built-in-functions\/?utm_source=realpython&utm_medium=rss\">Read the full article at https:\/\/realpython.com\/python-built-in-functions\/ \u00bb<\/a><\/h2>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"The Real Python Podcast \u2013 Episode #295: Agentic Architecture: Why Files Aren't Always Enough","id":"https:\/\/realpython.com\/podcasts\/rpp\/295\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/podcasts\/rpp\/295\/"}},"updated":"2026-05-15T12:00:00+00:00","summary":"What are the limitations of using a file-based agent workflow? Why do massive context windows tend to collapse? This week on the show, Mikiko Bazeley from MongoDB joins us to discuss agentic architecture and context engineering.","content":"\n        <p>What are the limitations of using a file-based agent workflow? Why do massive context windows tend to collapse? This week on the show, Mikiko Bazeley from MongoDB joins us to discuss agentic architecture and context engineering.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"How to Use OpenCode for AI-Assisted Python Coding","id":"https:\/\/realpython.com\/opencode-guide\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/opencode-guide\/"}},"updated":"2026-05-13T14:00:00+00:00","summary":"Learn how to use OpenCode, an open-source AI coding assistant, with a free Gemini API key to analyze and refactor Python code in your terminal.","content":"\n        <div><p>OpenCode is an open-source AI coding agent that runs in your terminal and lets you analyze and refactor a Python project through conversational commands. In this guide, you\u2019ll install it on your system, set it up with a free Google Gemini API key, and learn the basics of how to use it in your daily programming work.<\/p>\n<p>Here\u2019s what OpenCode\u2019s main interface looks like:<\/p>\n<figure class=\"js-lightbox\"><a href=\"https:\/\/files.realpython.com\/media\/opencode-initial-screen.7b04d0286d62.png\" target=\"_blank\"><img loading=\"lazy\" class=\"img-fluid mx-auto d-block \" src=\"https:\/\/files.realpython.com\/media\/opencode-initial-screen.7b04d0286d62.png\" width=\"2048\" height=\"1152\" srcset=\"\/cdn-cgi\/image\/width=512,format=auto\/https:\/\/files.realpython.com\/media\/opencode-initial-screen.7b04d0286d62.png 512w, \/cdn-cgi\/image\/width=682,format=auto\/https:\/\/files.realpython.com\/media\/opencode-initial-screen.7b04d0286d62.png 682w, \/cdn-cgi\/image\/width=1024,format=auto\/https:\/\/files.realpython.com\/media\/opencode-initial-screen.7b04d0286d62.png 1024w, \/cdn-cgi\/image\/width=2048,format=auto\/https:\/\/files.realpython.com\/media\/opencode-initial-screen.7b04d0286d62.png 2048w\" sizes=\"(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)\" alt=\"OpenCode's Initial Screen\" data-asset=\"6837\"><\/a><figcaption class=\"figure-caption text-center\">OpenCode's Initial Screen<\/figcaption><\/figure>\n\n<p><a href=\"\/ref\/ai-coding-tools\/opencode\/\" class=\"ref-link\">OpenCode<\/a> works as a conversational assistant you explicitly direct. Ask it to analyze functions, refactor code, or explain issues. Press <span class=\"keys\"><kbd class=\"key-enter\">Enter<\/kbd><\/span> to send your query, and you\u2019ll get a response with full awareness of your project context. It supports more than seventy-five AI providers, including Anthropic, OpenAI, and <a href=\"\/ref\/ai-coding-tools\/gemini\/\" class=\"ref-link\">Google Gemini<\/a>.<\/p>\n<p>If you\u2019re a Python developer who prefers working in the terminal, OpenCode offers deliberate, context-aware assistance and a customizable <code>AGENTS.md<\/code> configuration file.<\/p>\n<div class=\"container border rounded text-wrap-pretty my-3\">\n\n  <p class=\"my-3\"><mark class=\"marker-highlight\"><strong><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span> Take the Quiz:<\/strong><\/mark> Test your knowledge with our interactive \u201cHow to Use OpenCode for AI-Assisted Python Coding\u201d quiz. You\u2019ll receive a score upon completion to help you track your learning progress:<\/p>\n\n  <hr>\n\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center\">\n\n      <a href=\"\/quizzes\/opencode-guide\/\" tabindex=\"-1\">\n        <div class=\"embed-responsive embed-responsive-16by9\">\n\n            <img class=\"card-img-top m-0 p-0 embed-responsive-item rounded\" style=\"object-fit: contain; background: #abe5b2;\" alt=\"A person in a hard hat and safety goggles with a clipboard stands beside a wall of panels labeled OpenCode, Analyze, Refactor, AI Models, Python Projects, LSP, Git UI, and Modes (Plan\/Build).\" src=\"https:\/\/files.realpython.com\/media\/How-to-Use-OpenCode-for-AI-Assisted-Engineering_Watermarked.737726d966fd.jpg\" width=\"1920\" height=\"1080\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-OpenCode-for-AI-Assisted-Engineering_Watermarked.737726d966fd.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-OpenCode-for-AI-Assisted-Engineering_Watermarked.737726d966fd.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-OpenCode-for-AI-Assisted-Engineering_Watermarked.737726d966fd.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Use-OpenCode-for-AI-Assisted-Engineering_Watermarked.737726d966fd.jpg 1920w\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\">\n\n\n          <div class=\"card-img-overlay d-flex align-items-center\">\n            <div class=\"mx-auto\">\n              <span class=\"text-light\" style=\"opacity: 0.90;\"><span class=\"icon baseline scale2x\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span><\/span>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/a>\n\n    <\/div>\n    <div class=\"col\">\n      <div class=\"mt-3 d-md-none\"><\/div> \n      <p class=\"small text-muted mb-0\"><strong>Interactive Quiz<\/strong><\/p>\n      <a href=\"\/quizzes\/opencode-guide\/\" class=\"stretched-link\"><span class=\"my-0 h4\">How to Use OpenCode for AI-Assisted Python Coding<\/span><\/a> \n      <p class=\"text-muted mb-0 small\">Quiz yourself on OpenCode: install it, connect an AI provider, and use it to analyze and refactor Python from your terminal.<\/p>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<h2 id=\"prerequisites\">Prerequisites<a class=\"headerlink\" href=\"#prerequisites\" title=\"Permanent link\"><\/a><\/h2>\n<p>Before you start working with OpenCode, you\u2019ll need to fulfill the following prerequisites regarding your current system and working environment:<\/p>\n<ul>\n<li>Python 3.11 or higher for the sample project<\/li>\n<li>A modern terminal emulator<\/li>\n<\/ul>\n<p>You also need an <strong>AI provider account<\/strong>. In this guide, you\u2019ll use <a href=\"https:\/\/aistudio.google.com\">Google AI Studio<\/a> to get a free Gemini <a href=\"\/ref\/glossary\/api\/\" class=\"ref-link\">API<\/a> key. The free Gemini tier lets you follow along without any additional costs. However, you can also use Anthropic, OpenAI, or <a href=\"https:\/\/realpython.com\/github-copilot-python\/\">GitHub Copilot<\/a> if you already have subscriptions to those services.<\/p>\n<p>This guide uses a sample project consisting of a dice-rolling script. You\u2019ll find the full <a href=\"\/ref\/glossary\/source-code\/\" class=\"ref-link\">source code<\/a> in a collapsible block at the start of Step 2. The download below includes the starting script and the final refactored version so you can compare your work when you\u2019re done:<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Get Your Code:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/opencode-guide-code\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-opencode-guide-code\" markdown>Click here to download the free sample code<\/a> you\u2019ll use to learn about AI-assisted Python coding with OpenCode.<\/p>\n<\/div>\n<p>You\u2019ll also need some background knowledge of <a href=\"https:\/\/realpython.com\/python-first-steps\/\">Python programming<\/a> and basic experience with your operating system\u2019s <a href=\"https:\/\/realpython.com\/terminal-commands\/\">terminal or command line<\/a>.<\/p>\n<h2 id=\"step-1-install-and-set-up-opencode\">Step 1: Install and Set Up OpenCode<a class=\"headerlink\" href=\"#step-1-install-and-set-up-opencode\" title=\"Permanent link\"><\/a><\/h2>\n<p>It\u2019s time to install OpenCode and get it talking to a model. You\u2019ll install the tool on your system, authenticate with Gemini using a free API key, configure a default model, and verify that OpenCode responds correctly to your Python questions before you start coding with it.<\/p>\n<h3 id=\"install-and-launch-opencode\">Install and Launch OpenCode<a class=\"headerlink\" href=\"#install-and-launch-opencode\" title=\"Permanent link\"><\/a><\/h3>\n<p>The quickest way to install OpenCode is to use the official installation script, which you can do with the following command:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"console\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--yellow\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Shell<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">$ <\/span>curl<span class=\"w\"> <\/span>-fsSL<span class=\"w\"> <\/span>https:\/\/opencode.ai\/install<span class=\"w\"> <\/span><span class=\"p\">|<\/span><span class=\"w\"> <\/span>bash\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>This script detects your platform, downloads the appropriate binary, installs the tool, and adds it to your <a href=\"https:\/\/realpython.com\/add-python-to-path\/\"><code>PATH<\/code><\/a>.<\/p>\n<p>If you prefer a package manager, you can also install OpenCode with Homebrew on macOS or Linux:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"console\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--yellow\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Shell<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">$ <\/span>brew<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>anomalyco\/tap\/opencode\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>Note that the Homebrew team maintains the official formula and updates it less frequently than the installation script above.<\/p>\n<p>Alternatively, you can install it as a <a href=\"https:\/\/nodejs.org\/en\">Node.js<\/a> package using <a href=\"https:\/\/www.npmjs.com\/\"><code>npm<\/code><\/a> if you already have this tool on your system:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"console\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--yellow\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Shell<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">$ <\/span>npm<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>-g<span class=\"w\"> <\/span>opencode-ai\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>If you\u2019re on <a href=\"https:\/\/opencode.ai\/docs\/windows-wsl\">Windows<\/a>, the best experience comes from using WSL (Windows Subsystem for Linux). Set up WSL first by following <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/wsl\/install\">Microsoft\u2019s WSL installation guide<\/a>, then open a WSL terminal and run the <code>curl<\/code> command above. For optimal performance, you should store your project within the WSL filesystem rather than on a Windows drive.<\/p>\n<\/div><h2><a href=\"https:\/\/realpython.com\/opencode-guide\/?utm_source=realpython&utm_medium=rss\">Read the full article at https:\/\/realpython.com\/opencode-guide\/ \u00bb<\/a><\/h2>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Building Type-Safe LLM Agents With Pydantic AI","id":"https:\/\/realpython.com\/courses\/building-type-safe-llm-agents-with-pydantic-ai\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/courses\/building-type-safe-llm-agents-with-pydantic-ai\/"}},"updated":"2026-05-12T14:00:00+00:00","summary":"Build type-safe LLM agents in Python with Pydantic AI using structured outputs, function calling, and dependency injection.","content":"\n        <p>Pydantic AI is a Python framework for building LLM agents that return validated, structured outputs using Pydantic models. Instead of parsing raw strings from LLMs, you get type-safe objects with automatic validation.<\/p>\n<p>If you&rsquo;ve used FastAPI or Pydantic before, then you&rsquo;ll recognize the familiar pattern of defining schemas with type hints and letting the framework handle the type validation for you.<\/p>\n<p><strong>By the end of this video course, you&rsquo;ll understand that:<\/strong><\/p>\n<ul>\n<li><strong>Pydantic AI<\/strong> uses <code>BaseModel<\/code> classes to define structured outputs that guarantee <strong>type safety<\/strong> and automatic <strong>validation<\/strong>.<\/li>\n<li>The <code>@agent.tool<\/code> <strong>decorator<\/strong> registers Python functions that <strong>LLMs can invoke<\/strong> based on user queries and docstrings.<\/li>\n<li><strong>Dependency injection<\/strong> with <code>deps_type<\/code> provides <strong>type-safe<\/strong> runtime context like database connections without using <strong>global state<\/strong>.<\/li>\n<li><strong>Validation retries<\/strong> automatically rerun queries when the LLM returns invalid data, which increases <strong>reliability<\/strong> but also <strong>API costs<\/strong>.<\/li>\n<li><strong>Google Gemini<\/strong>, <strong>OpenAI<\/strong>, and <strong>Anthropic<\/strong> models support structured outputs best, while other providers have <strong>varying capabilities<\/strong>.<\/li>\n<\/ul>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"How to Flatten a List of Lists in Python","id":"https:\/\/realpython.com\/python-flatten-list\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/python-flatten-list\/"}},"updated":"2026-05-11T14:00:00+00:00","summary":"Learn how to flatten a list of lists in Python using for loops, list comprehensions, itertools, functools, NumPy, and recursion.","content":"\n        <div><p>Flattening a list in Python involves converting a nested list structure into a single, one-dimensional list. A common approach to flatten a list of lists is to use a <code>for<\/code> loop to iterate through each sublist. Then you can add each item to a new list with the <code>.extend()<\/code> method or the augmented concatenation operator (<code>+=<\/code>). This will \u201cunlist\u201d the list, resulting in a flattened list.<\/p>\n<p>Python\u2019s standard library offers other tools to achieve similar results. You can also use a list comprehension for a concise one-liner solution. Each method has its own performance characteristics, but <code>for<\/code> loops and list comprehensions are generally more efficient.<\/p>\n<p><strong>By the end of this tutorial, you\u2019ll understand that:<\/strong><\/p>\n<ul>\n<li><strong>Flattening a list<\/strong> involves converting nested lists into a single list.<\/li>\n<li>You can use a <strong><code>for<\/code> loop and <code>.extend()<\/code><\/strong> or a <strong>list comprehension<\/strong> to flatten lists in Python.<\/li>\n<li><strong>Standard-library functions<\/strong> like <code>itertools.chain()<\/code> and <code>functools.reduce()<\/code> can also flatten lists.<\/li>\n<li>A custom <strong><code>flatten()<\/code><\/strong> function, either recursive or iterative, handles arbitrarily nested lists.<\/li>\n<li>The <strong><code>.flatten()<\/code> method in NumPy<\/strong> efficiently flattens arrays for data science tasks.<\/li>\n<\/ul>\n<p>To better illustrate what it means to flatten a list, say that you have the following matrix of numeric values:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"pycon\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"n\">matrix<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span>\n<span class=\"gp\">... <\/span>    <span class=\"p\">[<\/span><span class=\"mi\">9<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span> <span class=\"mi\">8<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">],<\/span>\n<span class=\"gp\">... <\/span>    <span class=\"p\">[<\/span><span class=\"mi\">4<\/span><span class=\"p\">,<\/span> <span class=\"mi\">5<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">8<\/span><span class=\"p\">],<\/span>\n<span class=\"gp\">... <\/span>    <span class=\"p\">[<\/span><span class=\"mi\">6<\/span><span class=\"p\">,<\/span> <span class=\"mi\">4<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">],<\/span>\n<span class=\"gp\">... <\/span>    <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">4<\/span><span class=\"p\">,<\/span> <span class=\"mi\">5<\/span><span class=\"p\">],<\/span>\n<span class=\"gp\">... <\/span><span class=\"p\">]<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>The <code>matrix<\/code> variable holds a Python <a href=\"https:\/\/realpython.com\/python-list\/\">list<\/a> that contains four nested lists. Each nested list represents a row in the matrix. The rows store four items or numbers each. Now say that you want to turn this matrix into the following list:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"python\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"p\">[<\/span><span class=\"mi\">9<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span> <span class=\"mi\">8<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span> <span class=\"mi\">4<\/span><span class=\"p\">,<\/span> <span class=\"mi\">5<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">8<\/span><span class=\"p\">,<\/span> <span class=\"mi\">6<\/span><span class=\"p\">,<\/span> <span class=\"mi\">4<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">4<\/span><span class=\"p\">,<\/span> <span class=\"mi\">5<\/span><span class=\"p\">]<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>How do you manage to flatten your matrix and get a one-dimensional list like the one above? In this tutorial, you\u2019ll learn how to do that in Python.<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Free Bonus:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/python-flatten-list-code\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-python-flatten-list-code\" markdown>Click here to download the free sample code<\/a> that showcases and compares several ways to flatten a list of lists in Python.<\/p>\n<\/div>\n<div class=\"container border rounded text-wrap-pretty my-3\">\n\n  <p class=\"my-3\"><mark class=\"marker-highlight\"><strong><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span> Take the Quiz:<\/strong><\/mark> Test your knowledge with our interactive \u201cHow to Flatten a List of Lists in Python\u201d quiz. You\u2019ll receive a score upon completion to help you track your learning progress:<\/p>\n\n  <hr>\n\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center\">\n\n      <a href=\"\/quizzes\/python-flatten-list\/\" tabindex=\"-1\">\n        <div class=\"embed-responsive embed-responsive-16by9\">\n\n            <img class=\"card-img-top m-0 p-0 embed-responsive-item rounded\" style=\"object-fit: contain; background: #aae4b1;\" alt=\"How to Flatten a List of Lists in Python\" src=\"https:\/\/files.realpython.com\/media\/How-to-Flatten-a-List-of-Lists_Watermarked.2f9407737589.jpg\" width=\"1920\" height=\"1080\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Flatten-a-List-of-Lists_Watermarked.2f9407737589.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Flatten-a-List-of-Lists_Watermarked.2f9407737589.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Flatten-a-List-of-Lists_Watermarked.2f9407737589.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/How-to-Flatten-a-List-of-Lists_Watermarked.2f9407737589.jpg 1920w\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\">\n\n\n          <div class=\"card-img-overlay d-flex align-items-center\">\n            <div class=\"mx-auto\">\n              <span class=\"text-light\" style=\"opacity: 0.90;\"><span class=\"icon baseline scale2x\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span><\/span>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/a>\n\n    <\/div>\n    <div class=\"col\">\n      <div class=\"mt-3 d-md-none\"><\/div> \n      <p class=\"small text-muted mb-0\"><strong>Interactive Quiz<\/strong><\/p>\n      <a href=\"\/quizzes\/python-flatten-list\/\" class=\"stretched-link\"><span class=\"my-0 h4\">How to Flatten a List of Lists in Python<\/span><\/a> \n      <p class=\"text-muted mb-0 small\">Test your understanding of how to flatten a list of lists in Python using for loops, list comprehensions, itertools, recursion, and NumPy.<\/p>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<h2 id=\"how-to-flatten-a-list-of-lists-with-a-for-loop\">How to Flatten a List of Lists With a <code>for<\/code> Loop<a class=\"headerlink\" href=\"#how-to-flatten-a-list-of-lists-with-a-for-loop\" title=\"Permanent link\"><\/a><\/h2>\n<p>How can you flatten a list of lists in Python? In general, to flatten a list of lists, you can run the following steps either explicitly or implicitly:<\/p>\n<ol>\n<li><strong>Create<\/strong> a new empty list to store the <strong>flattened data<\/strong>.<\/li>\n<li><strong>Iterate<\/strong> over each <strong>nested list<\/strong> or sublist in the original list.<\/li>\n<li><strong>Add<\/strong> every <strong>item<\/strong> from the current sublist to the list of flattened data.<\/li>\n<li><strong>Return<\/strong> the resulting list with the <strong>flattened data<\/strong>.<\/li>\n<\/ol>\n<p>You can follow several paths and use multiple tools to run these steps in Python. The most natural and readable way to do this is to use a <a href=\"https:\/\/realpython.com\/python-for-loop\/\"><code>for<\/code> loop<\/a>, which allows you to explicitly iterate over the sublists.<\/p>\n<p>Then you need a way to add items to the new flattened list. For that, you have a couple of valid options. First, you\u2019ll turn to the <code>.extend()<\/code> method from the <code>list<\/code> class itself, and then you\u2019ll give the <a href=\"https:\/\/realpython.com\/python-assignment-operator\/#augmented-assignments-for-concatenation-and-repetition\">augmented concatenation operator<\/a> (<code>+=<\/code>) a go.<\/p>\n<p>To continue with the <code>matrix<\/code> example, here\u2019s how you would translate these steps into Python code using a <code>for<\/code> loop and the <code>.extend()<\/code> method:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"pycon\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"k\">def<\/span><span class=\"w\"> <\/span><span class=\"nf\">flatten_extend<\/span><span class=\"p\">(<\/span><span class=\"n\">matrix<\/span><span class=\"p\">):<\/span>\n<span class=\"gp\">... <\/span>    <span class=\"n\">flat_list<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\n<span class=\"gp\">... <\/span>    <span class=\"k\">for<\/span> <span class=\"n\">row<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">matrix<\/span><span class=\"p\">:<\/span>\n<span class=\"gp\">... <\/span>        <span class=\"n\">flat_list<\/span><span class=\"o\">.<\/span><span class=\"n\">extend<\/span><span class=\"p\">(<\/span><span class=\"n\">row<\/span><span class=\"p\">)<\/span>\n<span class=\"gp\">... <\/span>    <span class=\"k\">return<\/span> <span class=\"n\">flat_list<\/span>\n<span class=\"gp\">...<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>Inside <code>flatten_extend()<\/code>, you first create a new empty list called <code>flat_list<\/code>. You\u2019ll use this list to store the flattened data when you extract it from <code>matrix<\/code>. Then you start a loop to iterate over the inner, or nested, lists from <code>matrix<\/code>. In this example, you use the name <code>row<\/code> to represent the current nested list.<\/p>\n<p>In every iteration, you use <code>.extend()<\/code> to add the content of the current sublist to <code>flat_list<\/code>. This method takes an <a href=\"https:\/\/realpython.com\/python-iterators-iterables\/\">iterable<\/a> as an <a href=\"\/ref\/glossary\/argument\/\" class=\"ref-link\">argument<\/a> and appends its items to the end of the target list.<\/p>\n<p>Now go ahead and run the following code to check that your <a href=\"\/ref\/glossary\/function\/\" class=\"ref-link\">function<\/a> does the job:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"pycon\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"n\">flatten_extend<\/span><span class=\"p\">(<\/span><span class=\"n\">matrix<\/span><span class=\"p\">)<\/span>\n<span class=\"go\">[9, 3, 8, 3, 4, 5, 2, 8, 6, 4, 3, 1, 1, 0, 4, 5]<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<p>That\u2019s neat! You\u2019ve flattened your first list of lists. As a result, you have a one-dimensional list containing all the numeric values from <code>matrix<\/code>.<\/p>\n<p>With <code>.extend()<\/code>, you\u2019ve come up with a Pythonic and readable way to flatten your lists. You can get the same result using the <a href=\"https:\/\/realpython.com\/python-assignment-operator\/#augmented-assignments-for-concatenation-and-repetition\">augmented concatenation operator<\/a> (<code>+=<\/code>) on your <code>flat_list<\/code> object. However, this alternative approach may not be as readable:<\/p>\n<code-block class=\"mb-3\" data-syntax-language=\"pycon\" data-is-repl=\"true\">\n  <div class=\"codeblock__header codeblock--blue\">\n    <span class=\"mr-2 noselect\"><span class=\"sr-only\">Language: <\/span>Python<\/span>\n    \n    <div class=\"noselect\">\n      \n        <span class=\"codeblock__output-toggle\" title=\"Toggle prompts and output\" aria-label=\"Toggle prompts and output\" role=\"button\" tabindex=\"0\"><span class=\"icon baseline js-codeblock-output-on codeblock__header--icon-lower\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#regular--rectangle-terminal\"><\/use><\/svg><\/span><\/span>\n      \n    <\/div>\n  <\/div>\n  <div class=\"codeblock__contents\">\n    <div class=\"highlight highlight--with-header\"><pre><span><\/span><code><span class=\"gp\">&gt;&gt;&gt; <\/span><span class=\"k\">def<\/span><span class=\"w\"> <\/span><span class=\"nf\">flatten_concatenation<\/span><span class=\"p\">(<\/span><span class=\"n\">matrix<\/span><span class=\"p\">):<\/span>\n<span class=\"gp\">... <\/span>    <span class=\"n\">flat_list<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\n<span class=\"gp\">... <\/span>    <span class=\"k\">for<\/span> <span class=\"n\">row<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">matrix<\/span><span class=\"p\">:<\/span>\n<span class=\"hll\"><span class=\"gp\">... <\/span>        <span class=\"n\">flat_list<\/span> <span class=\"o\">+=<\/span> <span class=\"n\">row<\/span>\n<\/span><span class=\"gp\">... <\/span>    <span class=\"k\">return<\/span> <span class=\"n\">flat_list<\/span>\n<span class=\"gp\">...<\/span>\n<\/code><\/pre><\/div>\n    \n    <button class=\"codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only\" title=\"Copy to clipboard\" aria-label=\"Copy to clipboard\"><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@copy\"><\/use><\/svg><\/span><\/button>\n    \n  <\/div>\n<\/code-block>\n<\/div><h2><a href=\"https:\/\/realpython.com\/python-flatten-list\/?utm_source=realpython&utm_medium=rss\">Read the full article at https:\/\/realpython.com\/python-flatten-list\/ \u00bb<\/a><\/h2>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"The Real Python Podcast \u2013 Episode #294: Declarative Charts in Python & Discerning Iterators vs Iterables","id":"https:\/\/realpython.com\/podcasts\/rpp\/294\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/podcasts\/rpp\/294\/"}},"updated":"2026-05-08T12:00:00+00:00","summary":"What if you could build charts in Python by describing what your data means, instead of scripting every visual detail? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.","content":"\n        <p>What if you could build charts in Python by describing what your data means, instead of scripting every visual detail? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"ChatterBot: Build a Chatbot With Python","id":"https:\/\/realpython.com\/build-a-chatbot-python-chatterbot\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/build-a-chatbot-python-chatterbot\/"}},"updated":"2026-05-06T14:00:00+00:00","summary":"Build a Python chatbot with the ChatterBot library. Clean real conversation data, train on custom datasets, and add local AI with Ollama.","content":"\n        <div><p>The Python ChatterBot library lets you build a self-learning command-line chatbot with just a few lines of code. You\u2019ll set up a basic bot, clean real WhatsApp conversation data with regular expressions, and train your chatbot on that custom corpus. You\u2019ll also plug in a local LLM through Ollama to augment its replies with contextual knowledge.<\/p>\n<p><strong>By the end of this tutorial, you\u2019ll understand that:<\/strong><\/p>\n<ul>\n<li>ChatterBot is a <strong>Python library<\/strong> that combines text processing, machine learning, and a local database to generate chatbot replies.<\/li>\n<li>A <strong>minimal ChatterBot script<\/strong> instantiates <code>ChatBot<\/code>, collects user input in a loop, and returns matching responses through <code>.get_response()<\/code>.<\/li>\n<li>Training with <code>ListTrainer<\/code> and default settings stores conversation pairs in a <strong>SQLite<\/strong> database that ChatterBot queries with <strong>Levenshtein distance<\/strong> to pick each reply.<\/li>\n<li>ChatterBot can call a <strong>local LLM<\/strong> through <code>OllamaLogicAdapter<\/code>, voting against other logic adapters with a confidence score.<\/li>\n<li>ChatterBot was <strong>revived in 2025<\/strong> with spaCy-based <a href=\"\/ref\/ai-coding-glossary\/nlp\/\" class=\"ref-link\">NLP<\/a>, CSV and JSON trainers, and experimental <a href=\"\/ref\/ai-coding-glossary\/llm\/\" class=\"ref-link\">LLM<\/a> support.<\/li>\n<\/ul>\n<p>Along the way, you\u2019ll move from a potted plant that can only echo <em>hello<\/em> to a chatbot that chats knowledgeably about houseplants. You can follow along with your own WhatsApp export or grab the provided sample data below.<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Get Your Code:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/build-a-chatbot-python-chatterbot-code\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-build-a-chatbot-python-chatterbot-code\" markdown>Click here to download the free sample code<\/a> that you\u2019ll use to build a chatbot with Python\u2019s Chatterbot.<\/p>\n<\/div>\n<div class=\"container border rounded text-wrap-pretty my-3\">\n\n  <p class=\"my-3\"><mark class=\"marker-highlight\"><strong><span class=\"icon baseline\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span> Take the Quiz:<\/strong><\/mark> Test your knowledge with our interactive \u201cChatterBot: Build a Chatbot With Python\u201d quiz. You\u2019ll receive a score upon completion to help you track your learning progress:<\/p>\n\n  <hr>\n\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center\">\n\n      <a href=\"\/quizzes\/build-a-chatbot-python-chatterbot\/\" tabindex=\"-1\">\n        <div class=\"embed-responsive embed-responsive-16by9\">\n\n            <img class=\"card-img-top m-0 p-0 embed-responsive-item rounded\" style=\"object-fit: contain; background: #ffc774;\" alt=\"ChatterBot: Build a Chatbot With Python\" src=\"https:\/\/files.realpython.com\/media\/Chatterbot-Build-a-Chatbot-With-Python_Watermarked.07a26197ef70.jpg\" width=\"1920\" height=\"1080\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/Chatterbot-Build-a-Chatbot-With-Python_Watermarked.07a26197ef70.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/Chatterbot-Build-a-Chatbot-With-Python_Watermarked.07a26197ef70.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/Chatterbot-Build-a-Chatbot-With-Python_Watermarked.07a26197ef70.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/Chatterbot-Build-a-Chatbot-With-Python_Watermarked.07a26197ef70.jpg 1920w\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\">\n\n\n          <div class=\"card-img-overlay d-flex align-items-center\">\n            <div class=\"mx-auto\">\n              <span class=\"text-light\" style=\"opacity: 0.90;\"><span class=\"icon baseline scale2x\" aria-hidden=\"true\"><svg aria-hidden=\"true\"><use href=\"\/static\/icons.48f5632b9a94.svg#@quiz\"><\/use><\/svg><\/span><\/span>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/a>\n\n    <\/div>\n    <div class=\"col\">\n      <div class=\"mt-3 d-md-none\"><\/div> \n      <p class=\"small text-muted mb-0\"><strong>Interactive Quiz<\/strong><\/p>\n      <a href=\"\/quizzes\/build-a-chatbot-python-chatterbot\/\" class=\"stretched-link\"><span class=\"my-0 h4\">ChatterBot: Build a Chatbot With Python<\/span><\/a> \n      <p class=\"text-muted mb-0 small\">Test your understanding of the ChatterBot Python library, from training a basic bot with ListTrainer to wiring in a local LLM through Ollama.<\/p>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<h2 id=\"preview-the-chatbot\">Preview the Chatbot<a class=\"headerlink\" href=\"#preview-the-chatbot\" title=\"Permanent link\"><\/a><\/h2>\n<p>At the end of this tutorial, you\u2019ll have a command-line chatbot that can respond to your inputs with semi-meaningful replies:<\/p>\n<div>\n\n\n\n\n\n<div class=\"embed-responsive rounded mb-3 bg-light\" style=\"aspect-ratio: 3840\/2160;\">\n  <video-player>\n    <video-skin>\n\n        <hls-video src=\"https:\/\/stream.realpython.com\/01e4ee90-0fef-4099-bdbc-50785a2a3bc4\/playlist.m3u8\" poster=\"https:\/\/stream.realpython.com\/01e4ee90-0fef-4099-bdbc-50785a2a3bc4\/thumbnail.jpg\" preload=\"metadata\" playsinline>\n          <track default kind=\"metadata\" label=\"thumbnails\" src=\"\/video-thumbnails\/f182c5b4-8efc-4bce-86e1-85106691734a.vtt\">\n        <\/track><\/hls-video>\n\n    <\/video-skin>\n  <\/video-player>\n<\/div>\n\n\n\n<\/div>\n\n<p>You\u2019ll achieve that by preparing WhatsApp chat data and using it to train the chatbot. Beyond learning from your automated training, the chatbot will improve over time as it gets more exposure to questions and replies from user interactions.<\/p>\n<h2 id=\"project-overview\">Project Overview<a class=\"headerlink\" href=\"#project-overview\" title=\"Permanent link\"><\/a><\/h2>\n<p><a href=\"https:\/\/docs.chatterbot.us\/\">The ChatterBot library<\/a> combines text processing, <a href=\"\/ref\/ai-coding-glossary\/machine-learning\/\" class=\"ref-link\">machine learning<\/a> algorithms, and data storage and retrieval to allow you to build flexible chatbots.<\/p>\n<p>You can build an industry-specific chatbot by training it with relevant data. Additionally, the chatbot will remember user responses and continue building its internal <a href=\"https:\/\/en.wikipedia.org\/wiki\/Graph_(abstract_data_type)\">graph structure<\/a> to improve the responses that it can give.<\/p>\n<div class=\"alert alert-primary\" role=\"alert\">\n<p><strong>Note:<\/strong> After a long hiatus, ChatterBot was revived in early 2025 with support for modern Python, new training formats for <a href=\"https:\/\/realpython.com\/python-csv\/\">CSV<\/a> and <a href=\"https:\/\/realpython.com\/python-json\/\">JSON<\/a> data, and even experimental LLM integration. Under the hood, ChatterBot now uses <a href=\"https:\/\/spacy.io\/\">spaCy<\/a> for language processing, which gives it a more robust <a href=\"https:\/\/realpython.com\/natural-language-processing-spacy-python\/\">NLP pipeline<\/a> than before.<\/p>\n<\/div>\n<p>If you want to develop an LLM-first chatbot, Real Python\u2019s LLM Application Development With Python learning path takes you through the concepts and libraries step by step:<\/p>\n<div>\n\n\n<learning-path-card data-path-id=\"llm-application-development-python\" class=\"d-block container border rounded mb-4 shadow-sm\" data-progress-card>\n  <div class=\"row my-3\">\n    <div class=\"col-xs-12 col-sm-4 col-md-3 align-self-center px-3\">\n\n        <a href=\"\/learning-paths\/llm-application-development-python\/\" aria-hidden=\"true\" tabindex=\"-1\" data-not-previewable><img loading=\"lazy\" src=\"https:\/\/files.realpython.com\/media\/LLM-Application-Development-With-Python_Watermarked.b05c360e7536.jpg\" srcset=\"\/cdn-cgi\/image\/width=480,format=auto\/https:\/\/files.realpython.com\/media\/LLM-Application-Development-With-Python_Watermarked.b05c360e7536.jpg 480w, \/cdn-cgi\/image\/width=640,format=auto\/https:\/\/files.realpython.com\/media\/LLM-Application-Development-With-Python_Watermarked.b05c360e7536.jpg 640w, \/cdn-cgi\/image\/width=960,format=auto\/https:\/\/files.realpython.com\/media\/LLM-Application-Development-With-Python_Watermarked.b05c360e7536.jpg 960w, \/cdn-cgi\/image\/width=1920,format=auto\/https:\/\/files.realpython.com\/media\/LLM-Application-Development-With-Python_Watermarked.b05c360e7536.jpg 1920w\" style=\"background: #fe7e73;\" class=\"rounded img-fluid w-100 my-0\" alt=\"Two people operating a large machine with conveyor belts and panels labeled RAG, Agents, and MCP, alongside a robotic arm, a Python logo, and API key icons.\" sizes=\"(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)\"><\/a>\n\n    <\/div>\n    <div class=\"col px-3 pl-sm-0 mt-3 mt-sm-0\">\n      <p class=\"small text-muted mb-0\"><strong>Learning Path<\/strong><\/p>\n      <a class=\"stretched-link\" href=\"\/learning-paths\/llm-application-development-python\/\"><h2 class=\"my-0 h3\">LLM Application Development With Python<\/h2><\/a>\n      <p class=\"text-muted mb-0 small\">13 Resources \u22c5 <strong>Skills:<\/strong> OpenAI, Ollama, OpenRouter, Prompt Engineering, LangChain, LlamaIndex, ChromaDB, MarkItDown, RAG, Embeddings, Pydantic AI, LangGraph, MCP<\/p>\n\n\n      <div class=\"progress mt-2\" data-progress-placeholder>\n        <div class=\"progress-bar bg-light text-black-50 small w-100\" data-progress-placeholder-bar><\/div>\n      <\/div>\n\n\n      <div class=\"progress mt-2 d-none\" data-progress-container>\n        <div class=\"progress-bar small\" role=\"progressbar\" data-progress-bar aria-valuenow=\"0\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"min-width: 2.5em; cursor: default;\">\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/learning-path-card>\n<\/div>\n\n<p>In this tutorial, you\u2019ll start with an untrained chatbot that\u2019ll showcase how quickly you can create an interactive chatbot using Python\u2019s ChatterBot. You\u2019ll also notice how small the vocabulary of an untrained chatbot is.<\/p>\n<p>Next, you\u2019ll learn how you can train such a chatbot and check on the slightly improved results. The more plentiful and high-quality your training data is, the better your chatbot\u2019s responses will be.<\/p>\n<p>Therefore, you\u2019ll either fetch the conversation history of one of your WhatsApp chats or use the provided <code>chat.txt<\/code> file that you can download here:<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Get Your Code:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/build-a-chatbot-python-chatterbot-code\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-build-a-chatbot-python-chatterbot-code\" markdown>Click here to download the free sample code<\/a> that you\u2019ll use to build a chatbot with Python\u2019s Chatterbot.<\/p>\n<\/div>\n<p>It\u2019s rare that input data comes exactly in the form you need, so you\u2019ll clean the chat export data to get it into a useful input format. This process will show you some tools you can use for data cleaning, which may help you prepare other input data to feed to your chatbot.<\/p>\n<p>After data cleaning, you\u2019ll retrain your chatbot and give it another spin to experience the improved performance. Finally, you\u2019ll hook a local LLM into your chatbot to augment the variety and contextual relevance of its responses.<\/p>\n<p>When you work through this process from start to finish, you\u2019ll get a good idea of how you can build and train a Python chatbot with the ChatterBot library so that it can provide an interactive experience with relevant replies.<\/p>\n<h2 id=\"prerequisites\">Prerequisites<a class=\"headerlink\" href=\"#prerequisites\" title=\"Permanent link\"><\/a><\/h2>\n<p>Before you get started, make sure that you have <strong>Python 3.10 or later<\/strong> installed, which is the minimum Python version that ChatterBot supports. If you need help setting up Python, check out <a href=\"https:\/\/realpython.com\/installing-python\/\">Python 3 Installation &amp; Setup Guide<\/a>.<\/p>\n<\/div><h2><a href=\"https:\/\/realpython.com\/build-a-chatbot-python-chatterbot\/?utm_source=realpython&utm_medium=rss\">Read the full article at https:\/\/realpython.com\/build-a-chatbot-python-chatterbot\/ \u00bb<\/a><\/h2>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Use Codex CLI to Enhance Your Python Projects","id":"https:\/\/realpython.com\/courses\/use-codex-cli-enhance-your-python-projects\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/courses\/use-codex-cli-enhance-your-python-projects\/"}},"updated":"2026-05-05T14:00:00+00:00","summary":"Learn how to use Codex CLI to add features to Python projects directly from your terminal, without needing a browser or IDE plugins.","content":"\n        <p>After watching this video course, you&rsquo;ll be able to use Codex CLI to add features to a Python project directly from your terminal. <strong>Codex CLI<\/strong> is an AI-powered coding assistant that runs inside your terminal. It understands your project structure, reads your files, and proposes multi-file changes using natural language instructions.<\/p>\n<p>Instead of copying code from a browser or relying on an IDE plugin, you&rsquo;ll use Codex CLI to implement a real feature in a multi-file Python project directly from your terminal.<\/p>\n<p>In the following lessons, you&rsquo;ll install and configure Codex CLI, use it to implement a deletion feature in a contact book app, and then refine that feature through iterative prompting.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"A New Python Packaging Council and Other News for May 2026","id":"https:\/\/realpython.com\/python-news-may-2026\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/python-news-may-2026\/"}},"updated":"2026-05-04T14:00:00+00:00","summary":"A new Python Packaging Council, PEP 803 stabilizes the free-threaded ABI, the incremental GC gets reverted, and Astral changes hands.","content":"\n        <div><p>April gave Python developers a new governing body. <a href=\"https:\/\/peps.python.org\/pep-0772\/\">PEP 772<\/a> was accepted on April 16, creating a dedicated <strong>Python Packaging Council<\/strong> that will make binding decisions about packaging standards and tools. After years of informal coordination through the Python Packaging Authority (PyPA), the packaging community now has its own elected five-member council with authority comparable to the <a href=\"\/ref\/glossary\/python-steering-council\/\" class=\"ref-link\">Steering Council<\/a>.<\/p>\n<p>On the release side, <strong>Python 3.15.0 alpha 8<\/strong> dropped with a refreshed <a href=\"\/ref\/glossary\/jit-compiler\/\" class=\"ref-link\">JIT<\/a> delivering <strong>6\u20137 percent speedups on x86-64 Linux<\/strong> and <strong>12\u201313 percent on AArch64 macOS<\/strong>. The core team also decided to <strong>revert 3.14\u2019s incremental garbage collector<\/strong> after production reports of runaway memory use, with the fix landing in the upcoming 3.14.5 patch release. The next pre-release is the first beta, scheduled for <strong>May 5<\/strong>, which marks the feature freeze for Python 3.15.<\/p>\n<p>Elsewhere, Google released the open-weights <strong>Gemma 4<\/strong> family, <strong>Starlette 1.0<\/strong> shipped for FastAPI\u2019s foundation, and the broader Python ecosystem absorbed the news that <strong>OpenAI acquired Astral<\/strong>, the company behind <code>uv<\/code>, Ruff, and ty. Get ready to dig into the biggest Python news from the past month!<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown>Join Now:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/newsletter\/\" class=\"alert-link\" data-toggle=\"modal\" data-target=\"#modal-newsletter\" markdown>Click here to join the Real Python Newsletter<\/a> and you\u2019ll never miss another Python tutorial, course, or news update.<\/p>\n<\/div>\n<h2 id=\"python-releases-and-pep-highlights\">Python Releases and PEP Highlights<a class=\"headerlink\" href=\"#python-releases-and-pep-highlights\" title=\"Permanent link\"><\/a><\/h2>\n<p>April pushed Python 3.15 to its final alpha before the beta freeze, walked back the incremental garbage collector introduced in 3.14, and gave the Steering Council a busy month of PEP decisions. The packaging community even got its own elected governing body for the first time. Plenty to unpack on the language and process side of the ecosystem.<\/p>\n<h3 id=\"python-3150-alpha-8-final-alpha-before-beta-freeze\">Python 3.15.0 Alpha 8: Final Alpha Before Beta Freeze<a class=\"headerlink\" href=\"#python-3150-alpha-8-final-alpha-before-beta-freeze\" title=\"Permanent link\"><\/a><\/h3>\n<p><a href=\"https:\/\/blog.python.org\/2026\/04\/python-3150a8-3144-31313\/\">Python 3.15.0a8<\/a> landed on April 7, released alongside maintenance updates <strong>3.14.4<\/strong> and <strong>3.13.13<\/strong>. Release manager Hugo van Kemenade confirmed that a8 is the <strong>final alpha<\/strong> before the beta phase begins. If you maintain a library, this is the last alpha where you can file an issue against an unreleased feature and reasonably expect it to land before the freeze.<\/p>\n<p>Alpha 8 consolidates a long list of <a href=\"\/ref\/glossary\/pep\/\" class=\"ref-link\">PEPs<\/a> you\u2019ve been hearing about in earlier alphas:<\/p>\n<ul>\n<li><a href=\"https:\/\/peps.python.org\/pep-0810\/\">PEP 810<\/a>: Explicit lazy imports, which we covered <a href=\"https:\/\/realpython.com\/python-news-april-2026\/#python-3150-alpha-7-lazy-imports-land\">last month<\/a><\/li>\n<li><a href=\"https:\/\/peps.python.org\/pep-0814\/\">PEP 814<\/a>: <code>frozendict<\/code> as a built-in type<\/li>\n<li><a href=\"https:\/\/peps.python.org\/pep-0799\/\">PEP 799<\/a>: Statistical sampling profiler<\/li>\n<li><a href=\"https:\/\/peps.python.org\/pep-0798\/\">PEP 798<\/a>: Unpacking in comprehensions<\/li>\n<li><a href=\"https:\/\/peps.python.org\/pep-0686\/\">PEP 686<\/a>: UTF-8 as the default encoding<\/li>\n<li><a href=\"https:\/\/peps.python.org\/pep-0728\/\">PEP 728<\/a>: TypedDict enhancements<\/li>\n<\/ul>\n<p>The headline number is the <a href=\"\/ref\/glossary\/jit-compiler\/\" class=\"ref-link\">JIT<\/a> performance jump. On x86-64 Linux, the alpha reports a <strong>6\u20137 percent geometric mean improvement<\/strong> over the standard <a href=\"\/ref\/glossary\/interpreter\/\" class=\"ref-link\">interpreter<\/a>. On AArch64 macOS, the gain is <strong>12\u201313 percent<\/strong> over the tail-calling interpreter introduced in 3.14. Those aren\u2019t microbenchmark curiosities. They\u2019re cumulative gains across a broad suite of workloads.<\/p>\n<div class=\"alert alert-primary\" role=\"alert\">\n<p><strong>Note:<\/strong> If you haven\u2019t tried the alpha yet, installing it in an isolated environment is a good idea. Running <code>uv python install 3.15.0a8<\/code> pulls the binary, and <a href=\"https:\/\/realpython.com\/intro-to-pyenv\/\">pyenv<\/a> handles alpha builds too. The next pre-release, <strong>3.15.0 beta 1<\/strong>, is scheduled for <strong>May 5<\/strong>, which marks the feature freeze. After that, no new PEPs land in 3.15.<\/p>\n<\/div>\n<h3 id=\"incremental-gc-reverted-in-3145-and-315\">Incremental GC Reverted in 3.14.5 and 3.15<a class=\"headerlink\" href=\"#incremental-gc-reverted-in-3145-and-315\" title=\"Permanent link\"><\/a><\/h3>\n<p>On April 16, release manager Hugo van Kemenade <a href=\"https:\/\/discuss.python.org\/t\/reverting-the-incremental-gc-in-python-3-14-and-3-15\/107014\">proposed reverting<\/a> the incremental <a href=\"\/ref\/glossary\/garbage-collection\/\" class=\"ref-link\">garbage collector<\/a> that debuted in Python 3.14, and the core team agreed. The revert will ship in <strong>Python 3.14.5<\/strong> and also make it into 3.15 before feature freeze.<\/p>\n<p>The reasoning is practical. Neil Schemenauer\u2019s testing on production workloads showed that the incremental collector cut maximum pause times from <strong>26 ms down to 1.3 ms<\/strong>, which looks great on paper. But peak memory usage climbed to as much as <strong>5x<\/strong> the generational baseline in the worst case, and total runtime went up, not down, because of the extra bookkeeping.<\/p>\n<p>For most Python programs, like web apps, data pipelines, and batch jobs, reducing long pauses isn\u2019t the win that matters. Memory pressure is.<\/p>\n<p>The unusual part is doing this in a patch release. The working assumption during 3.14\u2019s release cycle was that the incremental GC had earned its place. Rolling it back in 3.14.5 is a reminder that \u201cpassed the benchmark suite\u201d and \u201cworks in production\u201d aren\u2019t the same thing. If you noticed your 3.14 deployments using noticeably more memory than 3.13, this is almost certainly why, and 3.14.5 should give you the old behavior back.<\/p>\n<div class=\"alert alert-primary\" role=\"alert\">\n<p><strong>Note:<\/strong> The incremental approach isn\u2019t dead. The core team noted that it could return in Python 3.16 through a proper <a href=\"https:\/\/peps.python.org\/\">PEP<\/a> review process, which the original implementation had skipped. If you were on the fence about the switch, waiting for the formal design round is probably the right call.<\/p>\n<\/div>\n<h3 id=\"pep-772-accepted-python-gets-a-packaging-council\">PEP 772 Accepted: Python Gets a Packaging Council<a class=\"headerlink\" href=\"#pep-772-accepted-python-gets-a-packaging-council\" title=\"Permanent link\"><\/a><\/h3>\n<p>On April 16, the <a href=\"\/ref\/glossary\/psf\/\" class=\"ref-link\">Python Software Foundation (PSF)<\/a> and the Steering Council accepted <a href=\"https:\/\/peps.python.org\/pep-0772\/\">PEP 772<\/a>, which creates a <strong>five-member Packaging Council<\/strong> with broad authority over packaging standards, tools, and implementations. It\u2019s one of the biggest governance changes the ecosystem has seen since the Steering Council itself was established back in 2019.<\/p>\n<p>Council members will be <strong>elected by PSF voting members<\/strong> who opt into the election. The council runs on staggered two-year terms, with two seats and three seats rotating in different cycles to preserve institutional continuity. Decision-making emphasizes <strong>consensus over voting<\/strong>, following the same pattern that has worked for the Steering Council.<\/p>\n<p>The practical impact is that a formal, elected body now owns decisions about tools like <a href=\"\/ref\/glossary\/pip\/\" class=\"ref-link\"><code>pip<\/code><\/a>, <code>setuptools<\/code>, and <a href=\"https:\/\/realpython.com\/pypi-publish-python-package\/\">PyPI<\/a>, replacing the ambiguous delegation model defined in PEP 609.<\/p>\n<p>If you\u2019ve ever wondered why packaging decisions in Python sometimes feel stuck in committee, PEP 772 is the structural answer to that complaint. It also sets the stage for the council to weigh in on <a href=\"\/ref\/ai-coding-glossary\/llm\/\" class=\"ref-link\">LLM<\/a>-era packaging concerns, which are popping up faster than the PyPA\u2019s informal coordination could address them.<\/p>\n<h3 id=\"pep-803-accepted-stable-abi-goes-free-threaded\">PEP 803 Accepted: Stable ABI Goes Free-Threaded<a class=\"headerlink\" href=\"#pep-803-accepted-stable-abi-goes-free-threaded\" title=\"Permanent link\"><\/a><\/h3>\n<p><a href=\"https:\/\/peps.python.org\/pep-0803\/\">PEP 803<\/a> was accepted on March 30 and targets Python 3.15. It defines <strong><code>abi3t<\/code><\/strong>, a new variant of the stable ABI that works with free-threaded builds. When the Steering Council accepted <a href=\"https:\/\/peps.python.org\/pep-0779\/\">PEP 779<\/a> last year, it promised <a href=\"https:\/\/realpython.com\/python-news-july-2025\/#python-314-beta-3-lands-free-threaded-support\">free-threading<\/a> would get a proper stable ABI story for 3.15. PEP 803 is that follow-through.<\/p>\n<\/div><h2><a href=\"https:\/\/realpython.com\/python-news-may-2026\/?utm_source=realpython&utm_medium=rss\">Read the full article at https:\/\/realpython.com\/python-news-may-2026\/ \u00bb<\/a><\/h2>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"The Real Python Podcast \u2013 Episode #293: Agentic Data Science Pair Programming With marimo pair","id":"https:\/\/realpython.com\/podcasts\/rpp\/293\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/podcasts\/rpp\/293\/"}},"updated":"2026-05-01T12:00:00+00:00","summary":"How do you add agent skills to your data science workflow? How can a coding agent assist with data wrangling and research? This week on the show, Trevor Manz from marimo joins us to discuss marimo pair.","content":"\n        <p>How do you add agent skills to your data science workflow? How can a coding agent assist with data wrangling and research? This week on the show, Trevor Manz from marimo joins us to discuss marimo pair.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Testing Your Code With Python's unittest","id":"https:\/\/realpython.com\/courses\/testing-your-code-with-pythons-unittest\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/courses\/testing-your-code-with-pythons-unittest\/"}},"updated":"2026-04-28T14:00:00+00:00","summary":"Learn how to use Python's unittest framework to write unit tests for your code, including test cases, fixtures, and test suites.","content":"\n        <p>The Python <a href=\"https:\/\/docs.python.org\/3\/library\/index.html\">standard library<\/a> ships with a testing framework named <strong><code>unittest<\/code><\/strong>, which you can use to write automated tests for your code. The <code>unittest<\/code> package has an object-oriented approach where test cases derive from a base class, which has several useful methods.<\/p>\n<p>The framework supports many features that will help you write consistent unit tests for your code. These features include test cases, fixtures, test suites, and test discovery capabilities.<\/p>\n<p><strong>In this video course, you&rsquo;ll learn how to:<\/strong><\/p>\n<ul>\n<li>Write <code>unittest<\/code> tests with the <strong><code>TestCase<\/code><\/strong> class<\/li>\n<li>Explore the <strong>assert<\/strong> methods that <code>TestCase<\/code> provides<\/li>\n<li>Use <code>unittest<\/code> from the <strong>command line<\/strong><\/li>\n<li>Group test cases using the <strong><code>TestSuite<\/code><\/strong> class<\/li>\n<li>Create <strong>fixtures<\/strong> to handle <strong>setup<\/strong> and <strong>teardown<\/strong> logic<\/li>\n<\/ul>\n<p>To get the most out of this video course, you should be familiar with some important Python concepts, such as <a href=\"https:\/\/realpython.com\/python3-object-oriented-programming\/\">object-oriented programming<\/a>, <a href=\"https:\/\/realpython.com\/inheritance-composition-python\/\">inheritance<\/a>, and <a href=\"https:\/\/realpython.com\/python-assert-statement\/\">assertions<\/a>. Having a good understanding of code <a href=\"https:\/\/realpython.com\/python-testing\/\">testing<\/a> is a plus.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"The Real Python Podcast \u2013 Episode #292: Becoming a Better Python Developer Through Learning Rust","id":"https:\/\/realpython.com\/podcasts\/rpp\/292\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/podcasts\/rpp\/292\/"}},"updated":"2026-04-24T12:00:00+00:00","summary":"How can learning Rust help make you a better Python Developer? How do techniques required by a compiled language translate to improving your Python code? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.","content":"\n        <p>How can learning Rust help make you a better Python Developer? How do techniques required by a compiled language translate to improving your Python code? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Leverage OpenAI's API in Your Python Projects","id":"https:\/\/realpython.com\/courses\/leverage-openais-api-in-your-python-projects\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/courses\/leverage-openais-api-in-your-python-projects\/"}},"updated":"2026-04-21T14:00:00+00:00","summary":"Learn how to use the ChatGPT API with Python's openai library to send prompts, control AI behavior with roles, and get structured outputs.","content":"\n        <p>Python&rsquo;s <code>openai<\/code> library provides the tools you need to integrate the ChatGPT API into your Python applications. With it, you can send text prompts to the API and receive AI-generated responses. You can also guide the AI&rsquo;s behavior with <code>developer<\/code> role messages and handle both simple text generation and more complex code creation tasks.<\/p>\n<p>After watching this video course, you&rsquo;ll understand how examples like this work under the hood. You&rsquo;ll learn the fundamentals of using the ChatGPT API from Python and have code examples you can adapt for your own projects.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"The Real Python Podcast \u2013 Episode #291: Reassessing the LLM Landscape & Summoning Ghosts","id":"https:\/\/realpython.com\/podcasts\/rpp\/291\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/podcasts\/rpp\/291\/"}},"updated":"2026-04-17T12:00:00+00:00","summary":"What are the current techniques being employed to improve the performance of LLM-based systems? How is the industry shifting from post-training towards context engineering and multi-agent orchestration? This week on the show, Jodie Burchell, data scientist and Python Advocacy Team Lead at JetBrains, returns to discuss the current AI coding landscape.","content":"\n        <p>What are the current techniques being employed to improve the performance of LLM-based systems? How is the industry shifting from post-training towards context engineering and multi-agent orchestration? This week on the show, Jodie Burchell, data scientist and Python Advocacy Team Lead at JetBrains, returns to discuss the current AI coding landscape.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Learning Path: Python Game Development","id":"https:\/\/realpython.com\/learning-paths\/python-game-development\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/learning-paths\/python-game-development\/"}},"updated":"2026-04-16T12:00:00+00:00","summary":"Build Python games from command-line projects to 2D graphical games with turtle, Tkinter, Pygame, and Arcade.","content":"\n        <p>Build Python games from command-line projects to 2D graphical games with turtle, Tkinter, Pygame, and Arcade.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Vector Databases and Embeddings With ChromaDB","id":"https:\/\/realpython.com\/courses\/vector-databases-embeddings-chromadb\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/courses\/vector-databases-embeddings-chromadb\/"}},"updated":"2026-04-14T14:00:00+00:00","summary":"Learn how to use ChromaDB, an open-source vector database, to store embeddings and give context to large language models in Python.","content":"\n        <p>The era of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Large_language_model\">large language models<\/a> (LLMs) is here, bringing with it rapidly evolving libraries like <a href=\"https:\/\/docs.trychroma.com\/\">ChromaDB<\/a> that help augment LLM applications. You&rsquo;ve most likely heard of chatbots like OpenAI&rsquo;s <a href=\"https:\/\/realpython.com\/chatgpt-coding-mentor-python\/\">ChatGPT<\/a>, and perhaps you&rsquo;ve even experienced their remarkable ability to reason about <a href=\"https:\/\/en.wikipedia.org\/wiki\/Natural_language_processing\">natural language processing (NLP)<\/a> problems.<\/p>\n<p>Modern LLMs, while imperfect, can accurately solve a wide range of problems and provide correct answers to many questions. However, due to the limits of their training and the number of text tokens they can process, LLMs aren&rsquo;t a silver bullet for all tasks.<\/p>\n<p>You wouldn&rsquo;t expect an LLM to deliver relevant responses about topics that don&rsquo;t appear in its training data. For example, if you asked ChatGPT to summarize information in confidential company documents, you&rsquo;d be out of luck. You could show some of these documents to ChatGPT, but there&rsquo;s a limit to how many documents you can upload before you exceed ChatGPT&rsquo;s maximum token count. How would you select which documents to show ChatGPT?<\/p>\n<p>To address these limitations and scale your LLM applications, a great option is to use a vector database like ChromaDB. A <strong>vector database<\/strong> allows you to store encoded unstructured objects, like text, as lists of numbers that can be compared to one another. For instance, you can find a collection of documents relevant to a question you&rsquo;d like an LLM to answer.<\/p>\n<p><strong>In this video course, you&rsquo;ll learn about:<\/strong><\/p>\n<ul>\n<li>Representing <strong>unstructured objects<\/strong> with <strong>vectors<\/strong><\/li>\n<li>Using <strong>word<\/strong> and <strong>text embeddings<\/strong> in Python<\/li>\n<li>Harnessing the power of <strong>vector databases<\/strong><\/li>\n<li><strong>Encoding<\/strong> and <strong>querying<\/strong> over documents with ChromaDB<\/li>\n<li>Providing <strong>context<\/strong> to <strong>LLMs<\/strong> like ChatGPT with ChromaDB<\/li>\n<\/ul>\n<p>After watching, you&rsquo;ll have the foundational knowledge to use ChromaDB in your NLP or LLM applications. Before watching, you should be comfortable with the <a href=\"https:\/\/realpython.com\/learning-paths\/python-basics\/\">basics of Python<\/a> and high school math.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"The Real Python Podcast \u2013 Episode #290: Advice on Managing Projects & Making Python Classes Friendly","id":"https:\/\/realpython.com\/podcasts\/rpp\/290\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/podcasts\/rpp\/290\/"}},"updated":"2026-04-10T12:00:00+00:00","summary":"What goes into managing a major project? What techniques can you employ for a project that's in crisis? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.","content":"\n        <p>What goes into managing a major project? What techniques can you employ for a project that's in crisis? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Using Loguru to Simplify Python Logging","id":"https:\/\/realpython.com\/courses\/using-loguru-to-simplify-python-logging\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/courses\/using-loguru-to-simplify-python-logging\/"}},"updated":"2026-04-07T14:00:00+00:00","summary":"Learn how to use Loguru for simpler Python logging, from zero-config setup and custom formats to file rotation, retention, and adding context.","content":"\n        <p>Logging is a vital programming practice that helps you track, understand, and debug your application&rsquo;s behavior. Loguru is a Python library that provides simpler, more intuitive logging compared to Python&rsquo;s built-in <code>logging<\/code> module.<\/p>\n<p>Good logging gives you insights into your program&rsquo;s execution, helps you diagnose issues, and provides valuable information about your application&rsquo;s health in production. Without proper logging, you risk missing critical errors, spending countless hours <a href=\"https:\/\/realpython.com\/python-debugging-pdb\/\">debugging<\/a> blind spots, and potentially undermining your project&rsquo;s overall stability.<\/p>\n<p><strong>By the end of this video course, you&rsquo;ll understand that:<\/strong><\/p>\n<ul>\n<li><strong>Logging<\/strong> in Python can be <strong>simple and intuitive<\/strong> with the right tools.<\/li>\n<li>Using Loguru lets you <strong>start logging immediately<\/strong> without complex configuration.<\/li>\n<li>You can <strong>customize log formats<\/strong> and send logs to multiple destinations like files, the standard error stream, or external services.<\/li>\n<li>Loguru provides <strong>powerful debugging capabilities<\/strong> that make troubleshooting easier.<\/li>\n<li>Loguru supports <strong>structured logging<\/strong> with JSON formatting for modern applications.<\/li>\n<\/ul>\n<p>After watching this course, you&rsquo;ll be able to quickly implement better logging in your Python applications. You&rsquo;ll spend less time wrestling with logging configuration and more time using logs effectively to debug issues. This will help you build production-ready applications that are easier to troubleshoot when problems occur.<\/p>\n<p>To get the most from this course, you should be familiar with Python concepts like <a href=\"https:\/\/realpython.com\/defining-your-own-python-function\/\">functions<\/a>, <a href=\"https:\/\/realpython.com\/primer-on-python-decorators\/\">decorators<\/a>, and <a href=\"https:\/\/realpython.com\/python-with-statement\/\">context managers<\/a>. You might also find it helpful to have some experience with Python&rsquo;s built-in <a href=\"https:\/\/realpython.com\/python-logging\/\"><code>logging<\/code><\/a> module, though this isn&rsquo;t required.<\/p>\n<p>Don&rsquo;t worry if you&rsquo;re new to logging in Python. This course will guide you through everything you need to know to get started with Loguru and implement effective logging in your applications.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Adding Python to PATH","id":"https:\/\/realpython.com\/courses\/adding-python-to-path\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/courses\/adding-python-to-path\/"}},"updated":"2026-03-31T14:00:00+00:00","summary":"Learn how to add Python to your PATH environment variable on Windows, macOS, and Linux so you can run Python from the command line.","content":"\n        <p>You may need to add Python to <code>PATH<\/code> if you&rsquo;ve <a href=\"https:\/\/realpython.com\/installing-python\/\">installed Python<\/a>, but typing <code>python<\/code> on the command line doesn&rsquo;t seem to work. You might see a message saying that <code>python<\/code> isn&rsquo;t recognized, or you might end up running the wrong version of Python.<\/p>\n<p>A common fix for these problems is adding Python to the <code>PATH<\/code> <a href=\"https:\/\/en.wikipedia.org\/wiki\/Environment_variable\">environment variable<\/a>. In this video course, you&rsquo;ll learn how to add Python to <code>PATH<\/code>. You&rsquo;ll also learn what <code>PATH<\/code> is and why it&rsquo;s essential for tools like the command line to be able to find your Python installation.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"The Real Python Podcast \u2013 Episode #289: Limitations in Human and Automated Code Review","id":"https:\/\/realpython.com\/podcasts\/rpp\/289\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/podcasts\/rpp\/289\/"}},"updated":"2026-03-27T12:00:00+00:00","summary":"With the mountains of Python code that it's possible to generate now, how's your code review going? What are the limitations of human review, and where does machine review excel? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.","content":"\n        <p>With the mountains of Python code that it's possible to generate now, how's your code review going? What are the limitations of human review, and where does machine review excel? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Learning Path: LLM Application Development With Python","id":"https:\/\/realpython.com\/learning-paths\/llm-application-development-python\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/learning-paths\/llm-application-development-python\/"}},"updated":"2026-03-19T12:00:00+00:00","summary":"Build LLM-powered applications in Python. Call model APIs, craft prompts, add retrieval-augmented generation, create AI agents, and connect via MCP.","content":"\n        <p>Build LLM-powered applications in Python. Call model APIs, craft prompts, add retrieval-augmented generation, create AI agents, and connect via MCP.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Learning Path: Python Coding With AI","id":"https:\/\/realpython.com\/learning-paths\/coding-with-ai\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/learning-paths\/coding-with-ai\/"}},"updated":"2025-12-07T12:00:00+00:00","summary":"Use AI coding assistants to write, review, and debug Python code faster. Pick from Claude Code, Cursor, or Gemini CLI and start coding.","content":"\n        <p>Use AI coding assistants to write, review, and debug Python code faster. Pick from Claude Code, Cursor, or Gemini CLI and start coding.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Learning Path: Python Control Flow and Loops","id":"https:\/\/realpython.com\/learning-paths\/python-control-flow-and-loops\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/learning-paths\/python-control-flow-and-loops\/"}},"updated":"2024-11-14T12:00:00+00:00","summary":"Learn Python control flow and loops. Use conditional statements, Boolean operators, for and while loops, and keywords like break and continue.","content":"\n        <p>Learn Python control flow and loops. Use conditional statements, Boolean operators, for and while loops, and keywords like break and continue.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Learning Path: Perfect Your Python Development Setup","id":"https:\/\/realpython.com\/learning-paths\/perfect-your-python-development-setup\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/learning-paths\/perfect-your-python-development-setup\/"}},"updated":"2024-11-14T12:00:00+00:00","summary":"Set up a Python development environment with VS Code, PyCharm, virtual environments, Git, pyenv, Docker, and AI coding tools like Claude Code and Cursor.","content":"\n        <p>Set up a Python development environment with VS Code, PyCharm, virtual environments, Git, pyenv, Docker, and AI coding tools like Claude Code and Cursor.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Learning Path: Functions and Scopes","id":"https:\/\/realpython.com\/learning-paths\/functions-and-scopes\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/learning-paths\/functions-and-scopes\/"}},"updated":"2024-11-14T12:00:00+00:00","summary":"Learn to define Python functions, use parameters and return values, create inner functions, and understand namespaces and scope.","content":"\n        <p>Learn to define Python functions, use parameters and return values, create inner functions, and understand namespaces and scope.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Learning Path: Modules and Packages","id":"https:\/\/realpython.com\/learning-paths\/modules-and-packages\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/learning-paths\/modules-and-packages\/"}},"updated":"2024-11-14T12:00:00+00:00","summary":"Learn Python's import system, organize code into modules and packages, manage dependencies with pip, and publish to PyPI.","content":"\n        <p>Learn Python's import system, organize code into modules and packages, manage dependencies with pip, and publish to PyPI.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Learning Path: Create Graphical User Interfaces (GUI)","id":"https:\/\/realpython.com\/learning-paths\/python-gui-programming\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/learning-paths\/python-gui-programming\/"}},"updated":"2024-11-14T12:00:00+00:00","summary":"Build Python GUI applications with Tkinter, PyQt, wxPython, and Kivy. Learn layouts, event handling, threading, and database integration.","content":"\n        <p>Build Python GUI applications with Tkinter, PyQt, wxPython, and Kivy. Learn layouts, event handling, threading, and database integration.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Learning Path: Important Standard Library Modules","id":"https:\/\/realpython.com\/learning-paths\/standard-library-modules-you-should-know\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/learning-paths\/standard-library-modules-you-should-know\/"}},"updated":"2024-11-14T12:00:00+00:00","summary":"Explore Python standard library modules including math, datetime, JSON, CSV, regex, subprocess, and argparse through hands-on tutorials and courses.","content":"\n        <p>Explore Python standard library modules including math, datetime, JSON, CSV, regex, subprocess, and argparse through hands-on tutorials and courses.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "},{"title":"Learning Path: Network Programming and Security","id":"https:\/\/realpython.com\/learning-paths\/network-programming-and-security\/","link":{"@attributes":{"href":"https:\/\/realpython.com\/learning-paths\/network-programming-and-security\/"}},"updated":"2024-11-14T12:00:00+00:00","summary":"Learn network programming and security in Python. Work with CRUD operations, REST APIs, HTTPS, and socket programming to build networked apps.","content":"\n        <p>Learn network programming and security in Python. Work with CRUD operations, REST APIs, HTTPS, and socket programming to build networked apps.<\/p>\n        <hr \/>\n        <p><em>[ Improve Your Python With \ud83d\udc0d Python Tricks \ud83d\udc8c \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n      "}]}