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

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

  
    <entry>
      <title>What&#x27;s New in Python 3.15</title>
      <id>https://realpython.com/courses/whats-new-in-python-315/</id>
      <link href="https://realpython.com/courses/whats-new-in-python-315/"/>
      <updated>2026-09-29T14:00:00+00:00</updated>
      <summary>Explore the new features in Python 3.15, including lazy imports, frozendict, sentinel values, a sampling profiler, and a faster JIT.</summary>
      <content type="html">
        &lt;p&gt;Python 3.15 is coming. The &lt;a href=&quot;https://www.python.org/downloads/release/python-3150rc2/&quot;&gt;final release&lt;/a&gt; is planned for October 1, 2026, as laid out in the &lt;a href=&quot;https://peps.python.org/pep-0790/&quot;&gt;release schedule&lt;/a&gt;. The release candidates are already out, and the feature set is frozen, so now is a good time to see what the new version has in store for you.&lt;/p&gt;
&lt;p&gt;This release trims the time you spend waiting. Imports can wait until you need them, the JIT compiler got faster, and a new profiler shows you where the remaining slow parts hide. There&amp;rsquo;s also plenty in it for everyday code, including two new built-in types.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this video course, you&amp;rsquo;ll explore features like:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lazy imports&lt;/strong&gt; with the new &lt;code&gt;lazy&lt;/code&gt; keyword&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;frozendict&lt;/code&gt;&lt;/strong&gt;, an immutable mapping in the built-ins&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;sentinel&lt;/code&gt;&lt;/strong&gt;, a clean way to say &amp;ldquo;no value given&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A sampling profiler&lt;/strong&gt; that you can point at a running process&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UTF-8&lt;/strong&gt; as the default encoding everywhere&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An upgraded JIT compiler&lt;/strong&gt; with measurable speedups&lt;/li&gt;
&lt;/ul&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: How to Use Python: Taking Your First Steps</title>
      <id>https://realpython.com/quizzes/first-steps-python/</id>
      <link href="https://realpython.com/quizzes/first-steps-python/"/>
      <updated>2026-09-29T12:00:00+00:00</updated>
      <summary>Test your Python foundations. Review syntax, variables, data types, indentation, functions, errors, and the tools you write Python with.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of &lt;a href=&quot;https://realpython.com/courses/python-first-steps/&quot;&gt;How to Use Python: Taking Your First Steps&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit Python&amp;rsquo;s readable syntax, keywords and variables, built-in data types, indentation and code blocks, functions, the difference between syntax errors and exceptions, coding tools, and PEP 8.&lt;/p&gt;
&lt;p&gt;These are the building blocks that everything else in Python rests on, so take your time with each question.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: LLM Application Development With Python</title>
      <id>https://realpython.com/quizzes/llm-application-development-python/</id>
      <link href="https://realpython.com/quizzes/llm-application-development-python/"/>
      <updated>2026-09-29T12:00:00+00:00</updated>
      <summary>Test your grasp of building LLM apps in Python, from calling model APIs and prompting to RAG, AI agents, and MCP.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll revisit the core concepts covered in the
&lt;a href=&quot;https://realpython.com/learning-paths/llm-application-development-python/&quot;&gt;LLM Application Development With Python&lt;/a&gt; learning path.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll check your understanding of connecting to LLM APIs, crafting effective prompts, working with LangChain, adding retrieval-augmented generation (RAG) with embeddings and vector databases, building AI agents with Pydantic AI and LangGraph, and connecting LLMs to external tools with the Model Context Protocol (MCP).&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: What&#x27;s New in Python 3.15</title>
      <id>https://realpython.com/quizzes/whats-new-in-python-315/</id>
      <link href="https://realpython.com/quizzes/whats-new-in-python-315/"/>
      <updated>2026-09-29T12:00:00+00:00</updated>
      <summary>Test your knowledge of Python 3.15, from lazy imports and frozendict to sentinels, friendlier errors, and UTF-8 by default.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/courses/whats-new-in-python-315/&quot;&gt;What&amp;rsquo;s New in Python 3.15&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit lazy imports, unpacking in comprehensions,
&lt;code&gt;frozendict&lt;/code&gt;, the new &lt;code&gt;sentinel()&lt;/code&gt; built-in, friendlier error messages, the new sampling
profiler, and UTF-8 as the default encoding.&lt;/p&gt;
&lt;p&gt;These are the features you&amp;rsquo;re most likely to reach for once you upgrade, so getting to
know them now gives you a head start.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python 3.15 Preview: Sentinel Values</title>
      <id>https://realpython.com/python315-sentinel-values/</id>
      <link href="https://realpython.com/python315-sentinel-values/"/>
      <updated>2026-09-28T14:00:00+00:00</updated>
      <summary>Learn how to create a Python sentinel value with the new built-in in Python 3.15 and get readable signatures, type hints, and safe copying and pickling.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;Sometimes your code needs to pass along a signal, like “no argument was passed” or “the stream has ended,” in the same place where it normally receives data. Any ordinary value you pick for that job, even &lt;code&gt;None&lt;/code&gt;, might also show up as real data. That’s why, in Python, you’ve probably written or seen something like &lt;code&gt;_MISSING = object()&lt;/code&gt; to create a sentinel value that your code treats as a signal rather than as data.&lt;/p&gt;
&lt;p&gt;That idiom works, but its default representation clutters function signatures, provides no useful information to static type checkers, and fails identity checks after copying. Other approaches have limitations, too. To address all of these drawbacks at once, Python 3.15 adds a built-in &lt;code&gt;sentinel&lt;/code&gt; type.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you’ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Python 3.15&lt;/strong&gt; adds &lt;code&gt;sentinel&lt;/code&gt; to the &lt;strong&gt;built-ins&lt;/strong&gt; through PEP 661, so you don’t need to import the type.&lt;/li&gt;
&lt;li&gt;A sentinel prints its own &lt;strong&gt;name&lt;/strong&gt;, so it reads clearly in function signatures, &lt;code&gt;help()&lt;/code&gt;, and &lt;code&gt;inspect.signature()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Sentinels keep their &lt;strong&gt;identity&lt;/strong&gt; through &lt;code&gt;copy()&lt;/code&gt;, &lt;code&gt;deepcopy()&lt;/code&gt;, and a &lt;code&gt;pickle&lt;/code&gt; round trip.&lt;/li&gt;
&lt;li&gt;A sentinel works as a &lt;strong&gt;type hint&lt;/strong&gt;, following the precedent set by &lt;code&gt;None&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;None&lt;/code&gt; remains the &lt;strong&gt;recommended default&lt;/strong&gt; unless &lt;code&gt;None&lt;/code&gt; is legitimate data in your code, in which case you should use a sentinel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To start, you’ll look at what a sentinel is and the existing options for creating one. Then you’ll meet Python 3.15’s &lt;code&gt;sentinel&lt;/code&gt; built-in and work through the issues it solves.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The code examples in this tutorial were tested with Python 3.14 and 3.15.0rc2, the latest Python 3.15 pre-release at the time of writing.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python315-sentinel-values-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-python315-sentinel-values-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; you’ll use to create sentinel values with Python 3.15’s new sentinel built-in and retire the unreadable object() idiom.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “Python 3.15 Preview: Sentinel Values” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/python315-sentinel-values/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #abe0e6;&quot; alt=&quot;A person with purple hair holds a notebook and slots a card labeled MISSING into a large machine that feeds out long paper printouts, beside control panels and a Python logo.&quot; src=&quot;https://files.realpython.com/media/Python-3.15-Preview-Sentinel-Values_Watermarked.4141cc1cbc76.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Python-3.15-Preview-Sentinel-Values_Watermarked.4141cc1cbc76.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Python-3.15-Preview-Sentinel-Values_Watermarked.4141cc1cbc76.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Python-3.15-Preview-Sentinel-Values_Watermarked.4141cc1cbc76.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Python-3.15-Preview-Sentinel-Values_Watermarked.4141cc1cbc76.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/python315-sentinel-values/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;Python 3.15 Preview: Sentinel Values&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Test your grasp of Python 3.15&#x27;s new sentinel built-in, from readable signatures and type hints to safe copying, pickling, and when to use one.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;understand-sentinel-values-in-python&quot;&gt;Understand Sentinel Values in Python&lt;a class=&quot;headerlink&quot; href=&quot;#understand-sentinel-values-in-python&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before you learn about the new built-in &lt;code&gt;sentinel&lt;/code&gt; &lt;a href=&quot;/ref/glossary/type/&quot; class=&quot;ref-link&quot;&gt;type&lt;/a&gt;, you’ll look at the problem it addresses in earlier Python versions. In this section, you’ll learn what a sentinel value is, recognize the ones you’ve been using for years without naming them, and see where existing approaches fall short. This context explains why Python adds &lt;code&gt;sentinel&lt;/code&gt; to its built-in types.&lt;/p&gt;
&lt;h3 id=&quot;know-what-a-sentinel-value-is&quot;&gt;Know What a Sentinel Value Is&lt;a class=&quot;headerlink&quot; href=&quot;#know-what-a-sentinel-value-is&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A &lt;a href=&quot;/ref/computer-science-glossary/sentinel-value/&quot; class=&quot;ref-link&quot;&gt;&lt;strong&gt;sentinel value&lt;/strong&gt;&lt;/a&gt; is a value that an &lt;a href=&quot;/ref/computer-science-glossary/algorithm/&quot; class=&quot;ref-link&quot;&gt;algorithm&lt;/a&gt; treats as a signal rather than as data. It marks a condition such as “terminating the &lt;a href=&quot;/ref/glossary/iteration/&quot; class=&quot;ref-link&quot;&gt;iteration&lt;/a&gt;,” “shutting down the worker &lt;a href=&quot;/ref/glossary/thread/&quot; class=&quot;ref-link&quot;&gt;thread&lt;/a&gt;,” or “nothing was passed.” A sentinel is a marker that your code branches on, and it doesn’t carry any information about the data you’re processing.&lt;/p&gt;
&lt;p&gt;Python uses sentinel values in many situations. For example, when you search a &lt;a href=&quot;https://realpython.com/python-strings/&quot;&gt;string&lt;/a&gt; and the target &lt;a href=&quot;https://realpython.com/python-string-contains-substring/&quot;&gt;substring&lt;/a&gt; isn’t there, you get &lt;code&gt;-1&lt;/code&gt; back:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello, World!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;z&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;In this example, &lt;code&gt;-1&lt;/code&gt; tells you that the substring isn’t there. In other words, your code should read it as a signal rather than as an index pointing to the target substring.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The example above shows that a sentinel can be an ordinary value that you’ve given a special meaning. The drawback is that the value can collide with your data. For example, &lt;code&gt;-1&lt;/code&gt; collides with &lt;a href=&quot;/ref/glossary/indexing/&quot; class=&quot;ref-link&quot;&gt;negative indices&lt;/a&gt;. You’ll learn more about this in the section &lt;a href=&quot;#explore-some-limitations-of-sentinels-in-python&quot;&gt;Explore Some Limitations of Sentinels in Python&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;A sentinel can also be a unique &lt;a href=&quot;/ref/glossary/object/&quot; class=&quot;ref-link&quot;&gt;object&lt;/a&gt; that you create for this purpose, ensuring that nothing else can ever equal it.&lt;/p&gt;
&lt;p&gt;The essential idea is that a sentinel value should stay distinct from every legitimate value your data can take. This way, a &lt;a href=&quot;/ref/glossary/loop/&quot; class=&quot;ref-link&quot;&gt;loop&lt;/a&gt; over your data can check each value and branch when it encounters the sentinel:&lt;/p&gt;
&lt;figure class=&quot;js-lightbox&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/diagram-sentinel-value-read-loop.0115fb190a54.svg&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/diagram-sentinel-value-read-loop.0115fb190a54.svg&quot; width=&quot;522&quot; height=&quot;501&quot; alt=&quot;Each value read is tested against the sentinel. A match ends the loop, while any other value is treated as data and processed before the next read.&quot; data-asset=&quot;7121&quot;&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;A Sentinel Value Ending a Read Loop&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Now that you know what a sentinel value is, you can start spotting the ones that Python has been handing you all along.&lt;/p&gt;
&lt;h3 id=&quot;spot-the-sentinels-python-already-uses&quot;&gt;Spot the Sentinels Python Already Uses&lt;a class=&quot;headerlink&quot; href=&quot;#spot-the-sentinels-python-already-uses&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You’ve probably been using sentinels since your early Python programs. Using &lt;a href=&quot;/ref/keywords/none/&quot; class=&quot;ref-link&quot;&gt;&lt;code&gt;None&lt;/code&gt;&lt;/a&gt; as the default value for &lt;a href=&quot;https://realpython.com/python-optional-arguments/&quot;&gt;optional arguments&lt;/a&gt; is a common example. It typically means “no value was passed.” In a data context, it may mean “no data.”&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&quot;/ref/glossary/standard-library/&quot; class=&quot;ref-link&quot;&gt;standard library&lt;/a&gt;, you’ll also find a variety of sentinels. Here are four &lt;a href=&quot;/ref/glossary/module/&quot; class=&quot;ref-link&quot;&gt;modules&lt;/a&gt; and some of their sentinel values:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;configparser&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;configparser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_UNSET&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;object object at 0x7f6d134cc6f0&amp;gt;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;inspect&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Parameter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;empty&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &#x27;inspect._empty&#x27;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NoDefault&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;typing.NoDefault&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;unittest.mock&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unittest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DEFAULT&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;sentinel.DEFAULT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Each of these four modules uses a different approach to sentinels:&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/python315-sentinel-values/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/python315-sentinel-values/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: Python 3.15 Preview: Sentinel Values</title>
      <id>https://realpython.com/quizzes/python315-sentinel-values/</id>
      <link href="https://realpython.com/quizzes/python315-sentinel-values/"/>
      <updated>2026-09-28T12:00:00+00:00</updated>
      <summary>Test your grasp of Python 3.15&#x27;s new sentinel built-in, from readable signatures and type hints to safe copying, pickling, and when to use one.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/python315-sentinel-values/&quot;&gt;Python 3.15 Preview: Sentinel Values&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit what sentinel values are, where the classic
&lt;code&gt;object()&lt;/code&gt; idiom falls short, and how Python 3.15&amp;rsquo;s built-in &lt;code&gt;sentinel&lt;/code&gt; type gives you
readable signatures, precise type hints, and identity that survives copying and pickling.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll also practice deciding when a sentinel beats &lt;code&gt;None&lt;/code&gt;, so you&amp;rsquo;ll know exactly which
&lt;code&gt;object()&lt;/code&gt; markers in your own code are worth replacing once you upgrade.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: Build a Python Turtle Game: Space Invaders Clone</title>
      <id>https://realpython.com/quizzes/build-python-turtle-game-space-invaders-clone/</id>
      <link href="https://realpython.com/quizzes/build-python-turtle-game-space-invaders-clone/"/>
      <updated>2026-09-28T12:00:00+00:00</updated>
      <summary>Practice building a game with Python&#x27;s turtle module: draw sprites, run a game loop, handle key presses, detect collisions, and set the frame rate.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/build-python-turtle-game-space-invaders-clone/&quot;&gt;Build a Python Turtle Game: Space Invaders Clone&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;turtle&lt;/code&gt; module ships with Python, so you can build an animated game without
installing anything extra. Writing one is also a practical way to see how the pieces of
any video game fit together.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how to set up a screen, draw and move
sprites, respond to key presses, run a game loop, detect collisions, and pace the game
with a fixed frame rate.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>How to Copy Objects in Python: Shallow vs Deep Copy Explained</title>
      <id>https://realpython.com/python-copy/</id>
      <link href="https://realpython.com/python-copy/"/>
      <updated>2026-09-27T14:00:00+00:00</updated>
      <summary>Understand the difference between shallow and deep copies in Python. Learn how to duplicate objects safely using the copy module and other techniques.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;When working with Python objects, you’ll often need to make copies rather than modify the originals. In this tutorial, you’ll explore various ways to copy objects in Python, including using the built-in &lt;code&gt;copy&lt;/code&gt; module. You’ll also learn the key differences between shallow and deep copies, with practical examples so you can safely duplicate objects in your own code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you’ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Shallow copying&lt;/strong&gt; creates a new object but references the same nested objects, leading to shared changes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deep copying&lt;/strong&gt; recursively duplicates all objects, ensuring full independence from the original.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python’s &lt;code&gt;copy&lt;/code&gt; module&lt;/strong&gt; provides the &lt;code&gt;copy()&lt;/code&gt; function for shallow copies and &lt;code&gt;deepcopy()&lt;/code&gt; for deep copies.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom classes&lt;/strong&gt; can implement &lt;code&gt;.__copy__()&lt;/code&gt; and &lt;code&gt;.__deepcopy__()&lt;/code&gt; for specific copying behavior.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/ref/glossary/assignment/&quot; class=&quot;ref-link&quot;&gt;Assignment&lt;/a&gt; in Python&lt;/strong&gt; binds variable names to objects without copying, unlike some lower-level languages.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Explore the nuances of copying objects in Python and learn how to apply these techniques to manage mutable data structures effectively.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-copy-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-python-copy-code&quot; markdown&gt;Click here to download the free sample code &lt;/a&gt; that you’ll use to learn about shallow vs deep copying in Python.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “Shallow vs Deep Copying of Python Objects” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/python-copy/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #e5c5ac;&quot; alt=&quot;Shallow vs Deep Copying of Python Objects&quot; src=&quot;https://files.realpython.com/media/Shallow-vs-Deep-Copying-of-Python-Objects_Watermarked.e6471b4627f8.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Shallow-vs-Deep-Copying-of-Python-Objects_Watermarked.e6471b4627f8.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Shallow-vs-Deep-Copying-of-Python-Objects_Watermarked.e6471b4627f8.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Shallow-vs-Deep-Copying-of-Python-Objects_Watermarked.e6471b4627f8.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Shallow-vs-Deep-Copying-of-Python-Objects_Watermarked.e6471b4627f8.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/python-copy/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;Shallow vs Deep Copying of Python Objects&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;In this quiz, you&#x27;ll test your understanding of Python&#x27;s copy module, which provides tools for creating shallow and deep copies of objects. This knowledge is crucial for managing complex, mutable data structures safely and effectively.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;getting-the-big-picture-of-object-copying&quot;&gt;Getting the Big Picture of Object Copying&lt;a class=&quot;headerlink&quot; href=&quot;#getting-the-big-picture-of-object-copying&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Copying an object means creating its &lt;strong&gt;exact duplicate&lt;/strong&gt; in memory. While there are many good reasons for doing so, at the end of the day, it allows you to &lt;em&gt;modify&lt;/em&gt; the cloned objects independently of each other.&lt;/p&gt;
&lt;p&gt;For example, a &lt;a href=&quot;https://realpython.com/python-getter-setter/&quot;&gt;getter method&lt;/a&gt; may return sensitive information like the balance of someone’s bank account. To prevent unauthorized modifications of the bank account’s state, whether accidental or intentional, you’ll typically return a copy of the original data as a &lt;a href=&quot;https://en.wikipedia.org/wiki/Defensive_programming&quot;&gt;defensive programming&lt;/a&gt; measure. That way, you’ll have two separate objects safely representing the same piece of information.&lt;/p&gt;
&lt;p&gt;Sometimes, you may need to work with multiple snapshots of the same data. In &lt;a href=&quot;https://en.wikipedia.org/wiki/3D_computer_graphics&quot;&gt;3D computer graphics&lt;/a&gt;, transformations like rotation and scaling rely on &lt;a href=&quot;https://en.wikipedia.org/wiki/Matrix_multiplication&quot;&gt;matrix multiplication&lt;/a&gt; to update a model’s vertices. Rather than permanently changing the original model, you can duplicate its vertices and apply transformations to the copy. This will allow you to animate the model in a non-destructive way.&lt;/p&gt;
&lt;p&gt;The following section provides an overview of the fundamental concepts and challenges associated with object copying in general. If you’d like to jump straight to &lt;a href=&quot;#understanding-shallow-and-deep-copying&quot;&gt;copying objects in Python&lt;/a&gt;, then feel free to skip ahead.&lt;/p&gt;
&lt;h3 id=&quot;scalar-vs-composite-types&quot;&gt;Scalar vs Composite Types&lt;a class=&quot;headerlink&quot; href=&quot;#scalar-vs-composite-types&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In programming, objects can be classified into two broad categories of data &lt;a href=&quot;/ref/glossary/type/&quot; class=&quot;ref-link&quot;&gt;types&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Scalar&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Composite&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Scalar_processor#Scalar_data_type&quot;&gt;Scalar data types&lt;/a&gt; represent simple, indivisible values that can’t be decomposed into smaller parts, much like atoms were once thought to be. Examples of scalars in Python include &lt;a href=&quot;https://realpython.com/python-numbers/&quot;&gt;numbers&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/python-datetime/&quot;&gt;dates&lt;/a&gt;, and &lt;a href=&quot;https://docs.python.org/3/library/uuid.html&quot;&gt;UUID-type identifiers&lt;/a&gt;:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuid4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dates&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1991&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ids&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuid4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuid4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuid4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Each of these objects holds a single value representing a basic unit of data. By combining these fundamental building blocks, you can create more complex data structures.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Composite_data_type&quot;&gt;Composite data types&lt;/a&gt;, on the other hand, are containers made up of other elements. Some of them are merely collections of scalar values, while others contain other composites or both, forming a complex hierarchy of objects:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;array&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;audio_frames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;h&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2644&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2814&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;audio_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;PCM&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;44100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15975&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28928&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;86&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15858&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;31999&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;In this case, the &lt;code&gt;&quot;h&quot;&lt;/code&gt; argument in the &lt;a href=&quot;https://docs.python.org/3/library/array.html&quot;&gt;&lt;code&gt;array.array()&lt;/code&gt;&lt;/a&gt; call specifies that the array will store numbers as two-byte signed integers. As you can see, a &lt;a href=&quot;https://realpython.com/python-array/&quot;&gt;Python array&lt;/a&gt; aggregates scalar numbers into a flat &lt;a href=&quot;/ref/glossary/sequence/&quot; class=&quot;ref-link&quot;&gt;sequence&lt;/a&gt;, whereas a &lt;a href=&quot;https://realpython.com/python-lists-tuples/&quot;&gt;list and tuple&lt;/a&gt; can contain deeply nested structures arranged in a particular way.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Python types can sometimes fall into a gray area. For example, strings have a dual nature, as they’re technically sequences of characters. At the same time, they behave like scalars in specific contexts because they don’t allow element-wise operations—you must treat them as a whole.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;These two categories of data types are closely related to the concept of &lt;strong&gt;object mutability&lt;/strong&gt;, which you’ll learn more about now.&lt;/p&gt;
&lt;h3 id=&quot;mutable-vs-immutable-objects&quot;&gt;Mutable vs Immutable Objects&lt;a class=&quot;headerlink&quot; href=&quot;#mutable-vs-immutable-objects&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In high-level programming languages like &lt;a href=&quot;https://realpython.com/java-vs-python/&quot;&gt;Java&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/python-vs-javascript/&quot;&gt;JavaScript&lt;/a&gt;, &lt;strong&gt;scalar types&lt;/strong&gt; typically represent read-only values that can’t change over time. Such objects don’t allow &lt;a href=&quot;https://en.wikipedia.org/wiki/In-place_algorithm&quot;&gt;in-place&lt;/a&gt; state mutation during their lifetime. So, if you want to modify a scalar value, then your only option is to disregard it and create another instance with a different value. In contrast, &lt;strong&gt;composite types&lt;/strong&gt; can be either &lt;a href=&quot;https://realpython.com/python-mutable-vs-immutable-types/&quot;&gt;mutable or immutable&lt;/a&gt;, depending on their implementation.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Immutable types have several advantages, including &lt;a href=&quot;https://realpython.com/python-thread-lock/&quot;&gt;thread safety&lt;/a&gt; and improved &lt;a href=&quot;https://en.wikipedia.org/wiki/Memory_footprint&quot;&gt;memory efficiency&lt;/a&gt;, as they let you reuse objects without copying. On the other hand, when &lt;a href=&quot;https://en.wikipedia.org/wiki/Algorithmic_efficiency&quot;&gt;performance&lt;/a&gt; is vital, mutable types can reduce the overhead associated with object creation, especially when you tend to modify your objects frequently.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/python-copy/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/python-copy/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Pipenv: A Guide to the Python Packaging Tool</title>
      <id>https://realpython.com/pipenv-guide/</id>
      <link href="https://realpython.com/pipenv-guide/"/>
      <updated>2026-09-27T14:00:00+00:00</updated>
      <summary>Pipenv replaces pip, virtualenv, and requirements.txt with a single tool. See what it solves and how to manage dependencies with it.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;Pipenv is a packaging tool for Python that solves some common problems associated with the typical workflow using &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt;, &lt;code&gt;virtualenv&lt;/code&gt;, and the good old &lt;code&gt;requirements.txt&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In addition to addressing some common issues, it consolidates and simplifies the development process to a single command line tool.&lt;/p&gt;
&lt;p&gt;This guide will go over what problems Pipenv solves and how to &lt;a href=&quot;https://realpython.com/courses/managing-python-dependencies/&quot;&gt;manage your Python dependencies&lt;/a&gt; with Pipenv. Additionally, it will cover how Pipenv fits in with previous methods for &lt;a href=&quot;https://realpython.com/python-modules-packages/&quot;&gt;package&lt;/a&gt; &lt;a href=&quot;/ref/best-practices/distribution/&quot; class=&quot;ref-link&quot;&gt;distribution&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/dependency-pitfalls-email-course/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-dependency-pitfalls-email-course&quot; markdown&gt;Click here to get access to a free 5-day class&lt;/a&gt; that shows you how to avoid common dependency management issues with tools like Pip, PyPI, Virtualenv, and requirements files.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;problems-that-pipenv-solves&quot;&gt;Problems that Pipenv Solves&lt;a class=&quot;headerlink&quot; href=&quot;#problems-that-pipenv-solves&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To understand the benefits of Pipenv, it’s important to walk through the current methods for packaging and &lt;a href=&quot;/ref/best-practices/dependency-management/&quot; class=&quot;ref-link&quot;&gt;dependency management&lt;/a&gt; in Python.&lt;/p&gt;
&lt;p&gt;Let’s start with a typical situation of handling third-party &lt;a href=&quot;/ref/glossary/package/&quot; class=&quot;ref-link&quot;&gt;packages&lt;/a&gt;. We’ll then build our way towards deploying a complete Python application.&lt;/p&gt;
&lt;h3 id=&quot;dependency-management-with-requirementstxt&quot;&gt;Dependency Management with &lt;code&gt;requirements.txt&lt;/code&gt;&lt;a class=&quot;headerlink&quot; href=&quot;#dependency-management-with-requirementstxt&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Imagine you’re working on a &lt;a href=&quot;https://realpython.com/intermediate-python-project-ideas/&quot;&gt;Python project&lt;/a&gt; that uses a third-party package like &lt;code&gt;flask&lt;/code&gt;. You’ll need to specify that requirement so that other developers and automated systems can run your application.&lt;/p&gt;
&lt;p&gt;So you decide to include the &lt;code&gt;flask&lt;/code&gt; &lt;a href=&quot;/ref/glossary/dependency/&quot; class=&quot;ref-link&quot;&gt;dependency&lt;/a&gt; in a &lt;code&gt;requirements.txt&lt;/code&gt; file:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pyreq&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--grey&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python Requirements&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;flask&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Great, everything works fine locally, and after hacking away on your app for a while, you decide to move it to production. Here’s where things get a little scary…&lt;/p&gt;
&lt;p&gt;The above &lt;code&gt;requirements.txt&lt;/code&gt; file doesn’t specify which version of &lt;code&gt;flask&lt;/code&gt; to use. In this case, &lt;code&gt;pip install -r requirements.txt&lt;/code&gt; will install the latest version by default. This is okay unless there are interface or behavior changes in the newest version that break our application.&lt;/p&gt;
&lt;p&gt;For the sake of this example, let’s say that a new version of &lt;code&gt;flask&lt;/code&gt; got released. However, it isn’t backward compatible with the version you used during development.&lt;/p&gt;
&lt;p&gt;Now, let’s say you deploy your application to production and do a &lt;code&gt;pip install -r requirements.txt&lt;/code&gt;. &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;Pip&lt;/a&gt; gets the latest, not-backward-compatible version of &lt;code&gt;flask&lt;/code&gt;, and just like that, your application breaks… in production.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“But hey, it worked on my machine!”&lt;/em&gt;—I’ve been there myself, and it’s not a great feeling.&lt;/p&gt;
&lt;p&gt;At this point, you know that the version of &lt;code&gt;flask&lt;/code&gt; you used during development worked fine. So, to fix things, you try to be a little more specific in your &lt;code&gt;requirements.txt&lt;/code&gt;. You add a &lt;em&gt;version specifier&lt;/em&gt; to the &lt;code&gt;flask&lt;/code&gt; dependency. This is also called &lt;em&gt;pinning&lt;/em&gt; a dependency:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pyreq&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--grey&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python Requirements&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;flask&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.12.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Pinning the &lt;code&gt;flask&lt;/code&gt; dependency to a specific version ensures that a &lt;code&gt;pip install -r requirements.txt&lt;/code&gt; sets up the exact version of &lt;code&gt;flask&lt;/code&gt; you used during development. But does it really?&lt;/p&gt;
&lt;p&gt;Keep in mind that &lt;code&gt;flask&lt;/code&gt; itself has dependencies as well (which &lt;code&gt;pip&lt;/code&gt; installs automatically). However, &lt;code&gt;flask&lt;/code&gt; itself doesn’t specify exact versions for its dependencies. For example, it allows any version of &lt;code&gt;Werkzeug&amp;gt;=0.14&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Again, for the sake of this example, let’s say a new version of &lt;code&gt;Werkzeug&lt;/code&gt; got released, but it introduces a show-stopper bug to your application.&lt;/p&gt;
&lt;p&gt;When you do &lt;code&gt;pip install -r requirements.txt&lt;/code&gt; in production this time, you will get &lt;code&gt;flask==0.12.1&lt;/code&gt; since you’ve pinned that requirement. However, unfortunately, you’ll get the latest, buggy version of &lt;code&gt;Werkzeug&lt;/code&gt;. Again, the product breaks in production.&lt;/p&gt;
&lt;p&gt;The real issue here is that &lt;strong&gt;the build isn’t deterministic&lt;/strong&gt;. What I mean by that is that, given the same input (the &lt;code&gt;requirements.txt&lt;/code&gt; file), pip doesn’t always produce the same environment. At the moment, you can’t easily replicate the exact environment you have on your development machine in production.&lt;/p&gt;
&lt;p&gt;The typical solution to this problem is to use &lt;code&gt;pip freeze&lt;/code&gt;. This command allows you to get exact versions for all 3rd party libraries currently installed, including the sub-dependencies pip installed automatically. So you can freeze everything in development to ensure that you have the same environment in production.&lt;/p&gt;
&lt;p&gt;Executing &lt;code&gt;pip freeze&lt;/code&gt; results in pinned dependencies you can add to a &lt;code&gt;requirements.txt&lt;/code&gt;:&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/pipenv-guide/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/pipenv-guide/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: Enhance Your Flask Web Project With a Database</title>
      <id>https://realpython.com/quizzes/flask-database/</id>
      <link href="https://realpython.com/quizzes/flask-database/"/>
      <updated>2026-09-27T12:00:00+00:00</updated>
      <summary>Test your understanding of Flask databases, environment variables, blueprints, SQLite schemas, and storing posts from a form.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/flask-database/&quot;&gt;Enhance Your Flask Web Project With a Database&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how to hide secrets in environment
variables, define a database schema, connect your Flask app to SQLite, and store
the posts that your users submit through a form.&lt;/p&gt;
&lt;p&gt;SQLite ships with Python, so you can build the whole project without installing a
database server.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python Inner Functions: What Are They Good For?</title>
      <id>https://realpython.com/inner-functions-what-are-they-good-for/</id>
      <link href="https://realpython.com/inner-functions-what-are-they-good-for/"/>
      <updated>2026-09-26T14:00:00+00:00</updated>
      <summary>Learn what a Python inner function is good for: accessing nonlocal names, building stateful closures, and writing your own decorators.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;Python inner functions are those you define inside other functions to access &lt;a href=&quot;/ref/keywords/nonlocal/&quot; class=&quot;ref-link&quot;&gt;&lt;code&gt;nonlocal&lt;/code&gt;&lt;/a&gt; names and bundle logic with its surrounding state. In this tutorial, you’ll learn how to create inner helper functions, build &lt;a href=&quot;/ref/glossary/closure/&quot; class=&quot;ref-link&quot;&gt;closures&lt;/a&gt; that retain state across calls, and implement decorators that modify the behavior or existing callables without changing the original implementation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you’ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inner functions access &lt;strong&gt;nonlocal names&lt;/strong&gt; from the enclosing &lt;a href=&quot;/ref/glossary/scope/&quot; class=&quot;ref-link&quot;&gt;scope&lt;/a&gt;, so you pass data in once and reuse it across calls.&lt;/li&gt;
&lt;li&gt;You can replace an &lt;strong&gt;inner helper function&lt;/strong&gt; with a &lt;strong&gt;non-public&lt;/strong&gt; function to enable code reuse.&lt;/li&gt;
&lt;li&gt;You can create a &lt;strong&gt;closure&lt;/strong&gt; by returning the inner function without calling it, which preserves the captured environment.&lt;/li&gt;
&lt;li&gt;You can &lt;strong&gt;modify the captured state&lt;/strong&gt; by declaring nonlocal variables that point to &lt;strong&gt;mutable objects&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You craft &lt;strong&gt;decorators&lt;/strong&gt; with nested functions that wrap a callable and extend its behavior transparently.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You will now move through focused examples that feature encapsulated helpers, stateful closures, and decorator patterns, allowing you to apply each technique with confidence in real Python projects.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-inner-functions-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-python-inner-functions-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; to practice inner functions in Python.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “Python Inner Functions: What Are They Good For?” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/inner-functions-what-are-they-good-for/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #ffc873;&quot; alt=&quot;Python Inner Functions&quot; src=&quot;https://files.realpython.com/media/Inner-Functions-What-Are-They-Good-For_Watermarked.995d44a06cdd.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Inner-Functions-What-Are-They-Good-For_Watermarked.995d44a06cdd.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Inner-Functions-What-Are-They-Good-For_Watermarked.995d44a06cdd.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Inner-Functions-What-Are-They-Good-For_Watermarked.995d44a06cdd.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Inner-Functions-What-Are-They-Good-For_Watermarked.995d44a06cdd.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/inner-functions-what-are-they-good-for/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;Python Inner Functions: What Are They Good For?&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Test inner functions, closures, nonlocal, and decorators in Python. Build confidence and learn to keep state across calls. Try the quiz now.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;creating-functions-within-functions-in-python&quot;&gt;Creating Functions Within Functions in Python&lt;a class=&quot;headerlink&quot; href=&quot;#creating-functions-within-functions-in-python&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A &lt;a href=&quot;/ref/glossary/function/&quot; class=&quot;ref-link&quot;&gt;function&lt;/a&gt; defined inside another function is known as an &lt;strong&gt;inner function&lt;/strong&gt; or a &lt;strong&gt;nested function&lt;/strong&gt;. Yes, in Python, you can define a function within another function. This type of function can access names defined in the &lt;a href=&quot;https://realpython.com/python-scope-legb-rule/#the-enclosing-scope&quot;&gt;enclosing scope&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here’s an example of how to create an inner function in Python:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;outer_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;inner_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello, World!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;inner_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outer_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Hello, World!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;In this example, you define &lt;code&gt;inner_func()&lt;/code&gt; inside &lt;code&gt;outer_func()&lt;/code&gt; to &lt;a href=&quot;https://realpython.com/python-print/&quot;&gt;print&lt;/a&gt; the &lt;code&gt;Hello, World!&lt;/code&gt; message to the screen. To do that, you call &lt;code&gt;inner_func()&lt;/code&gt; on the last line of &lt;code&gt;outer_func()&lt;/code&gt;. This is the quickest way to write and use an inner function in Python.&lt;/p&gt;
&lt;p&gt;Inner functions provide several interesting possibilities beyond what you see in the example above. The core feature of inner functions is their ability to access variables and objects from their enclosing function even after that function has returned. The enclosing function provides a &lt;a href=&quot;https://realpython.com/python-namespaces-scope/&quot;&gt;namespace&lt;/a&gt; that is accessible to the inner function:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;outer_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;who&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;inner_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;who&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;inner_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outer_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;World!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Hello, World!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Note how you can pass a &lt;a href=&quot;https://realpython.com/python-strings/&quot;&gt;string&lt;/a&gt; as an &lt;a href=&quot;/ref/glossary/argument/&quot; class=&quot;ref-link&quot;&gt;argument&lt;/a&gt; to &lt;code&gt;outer_func()&lt;/code&gt;, and &lt;code&gt;inner_func()&lt;/code&gt; can access that argument through the name &lt;code&gt;who&lt;/code&gt;. This name is defined in the &lt;a href=&quot;https://realpython.com/python-scope-legb-rule/#the-local-scope&quot;&gt;local scope&lt;/a&gt; of &lt;code&gt;outer_func()&lt;/code&gt;. The names defined in the local scope of an outer function are &lt;strong&gt;nonlocal names&lt;/strong&gt; from the inner function’s point of view.&lt;/p&gt;
&lt;p&gt;Here’s an example of a more realistic inner function:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;factorial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;TypeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;number must be an integer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ValueError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;number must be zero or positive&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;inner_factorial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inner_factorial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inner_factorial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;24&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;In &lt;code&gt;factorial()&lt;/code&gt;, you first validate the input data to ensure that the user provides an integer that is equal to or greater than zero. Then, you define a &lt;a href=&quot;/ref/glossary/recursion/&quot; class=&quot;ref-link&quot;&gt;recursive&lt;/a&gt; inner function called &lt;code&gt;inner_factorial()&lt;/code&gt;. This function performs the factorial calculation and &lt;a href=&quot;https://realpython.com/python-return-statement/&quot;&gt;returns&lt;/a&gt; the result. The final step is to call &lt;code&gt;inner_factorial()&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For a more detailed discussion on recursion and recursive functions, check out &lt;a href=&quot;https://realpython.com/python-thinking-recursively/&quot;&gt;Thinking Recursively in Python&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/python-recursion/&quot;&gt;Recursion in Python: An Introduction&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;An advantage of using the pattern in the example above is that you perform all the argument validation in the outer function, so you can skip error checking in the inner function and focus on the computation at hand.&lt;/p&gt;
&lt;h2 id=&quot;using-inner-functions-in-python&quot;&gt;Using Inner Functions in Python&lt;a class=&quot;headerlink&quot; href=&quot;#using-inner-functions-in-python&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The use cases of Python inner functions are varied. You can use them to provide &lt;a href=&quot;https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)&quot;&gt;encapsulation&lt;/a&gt;, hiding your functions from external access. You can also write quick helper inner functions. Finally, you can use inner functions to create &lt;a href=&quot;https://realpython.com/python-closure/&quot;&gt;closures&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/primer-on-python-decorators/&quot;&gt;decorators&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this section, you’ll learn about the former two use cases of inner functions, and in later sections, you’ll learn how to create &lt;a href=&quot;#retaining-state-in-a-closure&quot;&gt;closures&lt;/a&gt; and &lt;a href=&quot;#building-decorators-with-nested-functions-in-python&quot;&gt;decorators&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;providing-encapsulation&quot;&gt;Providing Encapsulation&lt;a class=&quot;headerlink&quot; href=&quot;#providing-encapsulation&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A common use case of inner functions arises when you need to protect or hide a given function from everything happening outside of it, so that the function is completely hidden from the global &lt;a href=&quot;https://realpython.com/python-scope-legb-rule/&quot;&gt;scope&lt;/a&gt;. This type of behavior is known as &lt;a href=&quot;/ref/glossary/encapsulation/&quot; class=&quot;ref-link&quot;&gt;&lt;strong&gt;encapsulation&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here’s an example that showcases the concept:&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/inner-functions-what-are-they-good-for/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/inner-functions-what-are-they-good-for/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Object-Oriented Programming (OOP) in Python</title>
      <id>https://realpython.com/python3-object-oriented-programming/</id>
      <link href="https://realpython.com/python3-object-oriented-programming/"/>
      <updated>2026-09-26T14:00:00+00:00</updated>
      <summary>Learn object-oriented programming in Python: the OOP paradigm, classes and inheritance, and how to instantiate objects from a class.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;Object-oriented programming (OOP) in Python helps you structure your code by grouping related data and behaviors into objects. You start by defining classes, which act as blueprints, and then create objects from them. OOP simplifies modeling real-world concepts in your programs and enables you to build systems that are more reusable and scalable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you’ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Object-oriented programming in Python&lt;/strong&gt; involves creating classes as blueprints for objects. These objects contain data and the methods needed to manipulate that data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The four key concepts of OOP in Python&lt;/strong&gt; are &lt;a href=&quot;/ref/glossary/encapsulation/&quot; class=&quot;ref-link&quot;&gt;encapsulation&lt;/a&gt;, inheritance, abstraction, and &lt;a href=&quot;/ref/glossary/polymorphism/&quot; class=&quot;ref-link&quot;&gt;polymorphism&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You &lt;strong&gt;create an object&lt;/strong&gt; in Python by &lt;strong&gt;instantiating a class&lt;/strong&gt;, which involves calling the class name followed by parentheses.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Class inheritance&lt;/strong&gt; in Python allows a class to inherit attributes and methods from another class, known as the parent class.&lt;/li&gt;
&lt;li&gt;You use super() in Python to call a method from the parent class, allowing you to &lt;strong&gt;extend or modify&lt;/strong&gt; inherited behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You’ll explore how to define classes, instantiate classes to create objects, and leverage inheritance to build robust systems in Python.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This tutorial is adapted from the chapter “Object-Oriented Programming (OOP)” in &lt;a href=&quot;https://realpython.com/products/python-basics-book/&quot;&gt;&lt;em&gt;Python Basics: A Practical Introduction to Python 3&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The book uses Python’s built-in &lt;a href=&quot;https://realpython.com/python-idle/&quot;&gt;IDLE&lt;/a&gt; editor to create and edit Python files and interact with the Python shell, so you’ll see occasional references to IDLE throughout this tutorial. If you don’t use IDLE, you can &lt;a href=&quot;https://realpython.com/run-python-scripts/&quot;&gt;run the example code&lt;/a&gt; from the editor and environment of your choice.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/object-oriented-programming-oop-in-python-3-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-object-oriented-programming-oop-in-python-3-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; that shows you how to do object-oriented programming with classes in Python 3.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “Object-Oriented Programming (OOP) in Python” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/python3-object-oriented-programming/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #abe0e6;&quot; alt=&quot;OOP in Python 3&quot; src=&quot;https://files.realpython.com/media/Object-Oriented-Programming-OOP-in-Python-3_Watermarked.0d29780806d5.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Object-Oriented-Programming-OOP-in-Python-3_Watermarked.0d29780806d5.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Object-Oriented-Programming-OOP-in-Python-3_Watermarked.0d29780806d5.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Object-Oriented-Programming-OOP-in-Python-3_Watermarked.0d29780806d5.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Object-Oriented-Programming-OOP-in-Python-3_Watermarked.0d29780806d5.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/python3-object-oriented-programming/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;Object-Oriented Programming (OOP) in Python&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Object-oriented programming (OOP) is a method of structuring a program by bundling related properties and behaviors into individual objects.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;what-is-object-oriented-programming-in-python&quot;&gt;What Is Object-Oriented Programming in Python?&lt;a class=&quot;headerlink&quot; href=&quot;#what-is-object-oriented-programming-in-python&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Object-oriented programming is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Programming_paradigm&quot;&gt;programming paradigm&lt;/a&gt; that provides a means of structuring programs so that properties and behaviors are bundled into individual &lt;strong&gt;objects&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For example, an object could represent a person with &lt;strong&gt;properties&lt;/strong&gt; like a name, age, and address and &lt;strong&gt;behaviors&lt;/strong&gt; such as walking, talking, breathing, and running. Or it could represent an &lt;a href=&quot;https://realpython.com/python-send-email/&quot;&gt;email&lt;/a&gt; with properties like a recipient list, subject, and body and behaviors like adding attachments and sending.&lt;/p&gt;
&lt;p&gt;Put another way, object-oriented programming is an approach for modeling concrete, real-world things, like cars, as well as relations between things, like companies and employees or students and teachers. OOP models real-world entities as software objects that have some data associated with them and can perform certain operations.&lt;/p&gt;
&lt;p&gt;OOP also exists in other programming languages and is often described to center around the four pillars, or &lt;strong&gt;four tenets of OOP&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Encapsulation&lt;/strong&gt; allows you to bundle data (attributes) and behaviors (methods) within a class to create a cohesive unit. By defining methods to control access to attributes and its modification, encapsulation helps maintain data integrity and promotes modular, secure code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Inheritance&lt;/strong&gt; enables the creation of hierarchical relationships between classes, allowing a &lt;a href=&quot;/ref/glossary/subclass/&quot; class=&quot;ref-link&quot;&gt;subclass&lt;/a&gt; to inherit attributes and methods from a parent class. This promotes code reuse and reduces duplication.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Abstraction&lt;/strong&gt; focuses on hiding implementation details and exposing only the essential functionality of an object. By enforcing a consistent &lt;a href=&quot;https://realpython.com/python-interface/&quot;&gt;interface&lt;/a&gt;, abstraction simplifies interactions with objects, allowing developers to focus on what an object does rather than how it achieves its functionality.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Polymorphism&lt;/strong&gt; allows you to treat objects of different types as instances of the same base type, as long as they implement a common interface or behavior. Python’s &lt;a href=&quot;https://realpython.com/duck-typing-python/&quot;&gt;duck typing&lt;/a&gt; make it especially suited for polymorphism, as it allows you to access attributes and methods on objects without needing to worry about their actual class.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In this tutorial you’ll take a practical approach to understanding OOP in Python. But keeping these four concepts of object-oriented programming in mind may help you to remember the information that you gather.&lt;/p&gt;
&lt;p&gt;The key takeaway is that objects are at the center of object-oriented programming in Python. In other programming paradigms, objects only represent the data. In OOP, they additionally inform the overall structure of the program.&lt;/p&gt;
&lt;h2 id=&quot;how-do-you-define-a-class-in-python&quot;&gt;How Do You Define a Class in Python?&lt;a class=&quot;headerlink&quot; href=&quot;#how-do-you-define-a-class-in-python&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In Python, you define a class by using the &lt;code&gt;class&lt;/code&gt; keyword followed by a name and a colon. Then you use &lt;code&gt;.__init__()&lt;/code&gt; to declare which attributes each instance of the class should have:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;python&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;fm&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;But what does all of that mean? And why do you even need classes in the first place? Take a step back and consider using built-in, primitive &lt;a href=&quot;https://realpython.com/courses/python-data-types/&quot;&gt;data structures&lt;/a&gt; as an alternative.&lt;/p&gt;
&lt;p&gt;Primitive data structures—like &lt;a href=&quot;https://realpython.com/python-numbers/&quot;&gt;numbers&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/python-strings/&quot;&gt;strings&lt;/a&gt;, and &lt;a href=&quot;https://realpython.com/python-list/&quot;&gt;lists&lt;/a&gt;—are designed to represent straightforward pieces of information, such as the cost of an apple, the name of a poem, or your favorite colors, respectively. What if you want to represent something more complex?&lt;/p&gt;
&lt;p&gt;For example, you might want to track employees in an organization. You need to store some basic information about each employee, such as their name, age, position, and the year they started working.&lt;/p&gt;
&lt;p&gt;One way to do this is to represent each employee as a &lt;a href=&quot;https://realpython.com/python-list/&quot;&gt;list&lt;/a&gt;:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;python&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;kirk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;James Kirk&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;34&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Captain&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2265&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;spock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Spock&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Science Officer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2254&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;mccoy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Leonard McCoy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Chief Medical Officer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2266&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;There are a number of issues with this approach.&lt;/p&gt;
&lt;p&gt;First, it can make larger code files more difficult to manage. If you reference &lt;code&gt;kirk[0]&lt;/code&gt; several lines away from where you declared the &lt;code&gt;kirk&lt;/code&gt; list, will you remember that the element with &lt;a href=&quot;https://realpython.com/python-strings/#string-indexing&quot;&gt;index&lt;/a&gt; &lt;code&gt;0&lt;/code&gt; is the employee’s name?&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/python3-object-oriented-programming/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/python3-object-oriented-programming/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: When Do You Use an Ellipsis in Python?</title>
      <id>https://realpython.com/quizzes/python-ellipsis/</id>
      <link href="https://realpython.com/quizzes/python-ellipsis/"/>
      <updated>2026-09-26T12:00:00+00:00</updated>
      <summary>Test your understanding of Python&#x27;s Ellipsis. Practice using three dots as a placeholder, in type hints, and in NumPy slicing.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/python-ellipsis/&quot;&gt;When Do You Use an Ellipsis in Python?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how &lt;code&gt;...&lt;/code&gt; relates to the &lt;code&gt;Ellipsis&lt;/code&gt; object,
how to use three dots as a placeholder when you write stubs, what they mean in &lt;code&gt;tuple&lt;/code&gt;
and &lt;code&gt;Callable&lt;/code&gt; type hints, and how they shorten your NumPy slicing syntax.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #312: Navigating AI in Open Source: Insights From Wagtail</title>
      <id>https://realpython.com/podcasts/rpp/312/</id>
      <link href="https://realpython.com/podcasts/rpp/312/"/>
      <updated>2026-09-25T12:00:00+00:00</updated>
      <summary>How should you manage AI contributions to an open-source project? How do you measure the impact of using AI tools for development, and what generative features do end users want from a content management system? This week on the show, we speak with Thibaud Colas and Meagen Voss from Wagtail about the complex considerations software organizations are currently facing.</summary>
      <content type="html">
        &lt;p&gt;How should you manage AI contributions to an open-source project? How do you measure the impact of using AI tools for development, and what generative features do end users want from a content management system? This week on the show, we speak with Thibaud Colas and Meagen Voss from Wagtail about the complex considerations software organizations are currently facing.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: Jupyter Notebook: An Introduction</title>
      <id>https://realpython.com/quizzes/jupyter-notebook-introduction/</id>
      <link href="https://realpython.com/quizzes/jupyter-notebook-introduction/"/>
      <updated>2026-09-25T12:00:00+00:00</updated>
      <summary>Test your understanding of Jupyter Notebook, from starting the server and running cells to exporting your work and adding extensions.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/jupyter-notebook-introduction/&quot;&gt;Jupyter Notebook: An Introduction&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Jupyter Notebook is an open source web application that lets you create and share
documents containing live code, equations, visualizations, and text. It&amp;rsquo;s a staple of
data science work, and it&amp;rsquo;s just as useful for teaching, prototyping, and keeping a
runnable lab notebook.&lt;/p&gt;
&lt;p&gt;By working through these questions, you&amp;rsquo;ll revisit how to start the notebook server,
how cells share state through a kernel, what each cell type is good for, and how to
export and extend your notebooks.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>How to Get Started With Jev in Python</title>
      <id>https://realpython.com/jev-python/</id>
      <link href="https://realpython.com/jev-python/"/>
      <updated>2026-09-24T14:00:00+00:00</updated>
      <summary>Connect a Python script to the Jev model with the TypeSafe SDK and OpenRouter, then replace brittle input checks with Noul, Score, and Choice answers.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;When your script asks a user a basic yes-or-no question, they might type &lt;code&gt;yes&lt;/code&gt;, &lt;code&gt;Y&lt;/code&gt;, &lt;code&gt;no!&lt;/code&gt;, or &lt;code&gt;yeah&lt;/code&gt;. As a programmer, you have to guess every way they might answer, so your Python script needs to account for that. With the newly released &lt;a href=&quot;/ref/ai-coding-tools/jev/&quot; class=&quot;ref-link&quot;&gt;Jev&lt;/a&gt; AI model, you can ease the load on your &lt;code&gt;if&lt;/code&gt; statements and try to make sense of all human replies.&lt;/p&gt;
&lt;p&gt;You’ll start with a small train station script that only accepts an uppercase &lt;code&gt;Y&lt;/code&gt; or &lt;code&gt;N&lt;/code&gt;. Then you’ll hand the station visitor’s answer to Jev, and finally ask three questions in one request to find out where each visitor should go:&lt;/p&gt;
&lt;figure class=&quot;js-lightbox&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/result_preview.deee80ce895e.2001e846e75b.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/result_preview.deee80ce895e.2001e846e75b.png&quot; width=&quot;1652&quot; height=&quot;865&quot; srcset=&quot;/cdn-cgi/image/width=413,format=auto/https://files.realpython.com/media/result_preview.deee80ce895e.2001e846e75b.png 413w, /cdn-cgi/image/width=550,format=auto/https://files.realpython.com/media/result_preview.deee80ce895e.2001e846e75b.png 550w, /cdn-cgi/image/width=826,format=auto/https://files.realpython.com/media/result_preview.deee80ce895e.2001e846e75b.png 826w, /cdn-cgi/image/width=1652,format=auto/https://files.realpython.com/media/result_preview.deee80ce895e.2001e846e75b.png 1652w&quot; sizes=&quot;(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)&quot; alt=&quot;Terminal window running jev_desk.py, where a visitor&#x27;s sentence about a suitcase left on a train yields a lost-and-found choice, a low assistance noul, and a high urgency score.&quot; data-asset=&quot;7553&quot;&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Three Typed Answers From a Single Jev Request&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;To follow along, you should be comfortable with &lt;a href=&quot;https://realpython.com/python-keyboard-input/&quot;&gt;reading user input from the keyboard&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/python-dicts/&quot;&gt;Python dictionaries&lt;/a&gt;. If you’ve worked with an &lt;a href=&quot;https://realpython.com/openrouter-api/&quot;&gt;AI model through the OpenRouter API&lt;/a&gt; before, then you’ll recognize the setup steps. But that’s not a requirement.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/jev-python-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-jev-python-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; you’ll use to connect a Python script to Jev with the TypeSafe SDK and OpenRouter.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “How to Get Started With Jev in Python” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/jev-python/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #ffc873;&quot; alt=&quot;A visitor talks into a station assistant machine with a Noul dial, a Score gauge, and a Choice switch, while two staff members read a clipboard and pull a lever.&quot; src=&quot;https://files.realpython.com/media/CHOSEN-jev-python-title-gen.1d360fd0e39b.png&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/CHOSEN-jev-python-title-gen.1d360fd0e39b.png 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/CHOSEN-jev-python-title-gen.1d360fd0e39b.png 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/CHOSEN-jev-python-title-gen.1d360fd0e39b.png 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/CHOSEN-jev-python-title-gen.1d360fd0e39b.png 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/jev-python/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;How to Get Started With Jev in Python&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Check your understanding of the Jev AI model in Python, from OpenRouter setup and Noul cutoffs to Choice and Score answers.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;a class=&quot;headerlink&quot; href=&quot;#prerequisites&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Jev is a model by &lt;a href=&quot;https://typesafe.ai&quot;&gt;TypeSafe AI&lt;/a&gt;, and like many AI companies, TypeSafe AI publishes a &lt;a href=&quot;https://docs.typesafe.ai/sdk/python/&quot;&gt;Python SDK&lt;/a&gt; for its model. Instead of sending a &lt;a href=&quot;/ref/ai-coding-glossary/prompt/&quot; class=&quot;ref-link&quot;&gt;prompt&lt;/a&gt; and getting prose back, as you do with &lt;a href=&quot;/ref/ai-coding-glossary/llm/&quot; class=&quot;ref-link&quot;&gt;LLMs&lt;/a&gt; like &lt;a href=&quot;/ref/ai-coding-tools/claude/&quot; class=&quot;ref-link&quot;&gt;Claude&lt;/a&gt; or &lt;a href=&quot;/ref/ai-coding-tools/chatgpt/&quot; class=&quot;ref-link&quot;&gt;ChatGPT&lt;/a&gt;, Jev answers every question in a &lt;a href=&quot;/ref/ai-coding-glossary/structured-output/&quot; class=&quot;ref-link&quot;&gt;typed format&lt;/a&gt;. You get a number or a key from a set of options, which you can conveniently parse in your Python code.&lt;/p&gt;
&lt;p&gt;Your project needs at least Python 3.10 and the TypeSafe &lt;a href=&quot;/ref/computer-science-glossary/software-development-kit/&quot; class=&quot;ref-link&quot;&gt;SDK&lt;/a&gt;. You’ll manage both with &lt;a href=&quot;https://realpython.com/python-uv/&quot;&gt;&lt;code&gt;uv&lt;/code&gt;&lt;/a&gt; because &lt;code&gt;uv&lt;/code&gt; installs the right Python version for you and reads your dependencies from &lt;a href=&quot;/ref/glossary/pyproject-toml/&quot; class=&quot;ref-link&quot;&gt;&lt;code&gt;pyproject.toml&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you don’t have &lt;a href=&quot;/ref/tools/uv/&quot; class=&quot;ref-link&quot;&gt;&lt;code&gt;uv&lt;/code&gt;&lt;/a&gt; yet, then follow the &lt;a href=&quot;https://docs.astral.sh/uv/getting-started/installation/&quot;&gt;installation instructions&lt;/a&gt; for your operating system. Check that &lt;code&gt;uv --version&lt;/code&gt; works in your terminal before you continue.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;You also need an &lt;a href=&quot;/ref/glossary/api/&quot; class=&quot;ref-link&quot;&gt;API&lt;/a&gt; key to talk to Jev. You can get one straight from TypeSafe AI, but for this tutorial, you’ll use &lt;a href=&quot;https://openrouter.ai/&quot;&gt;OpenRouter&lt;/a&gt;. OpenRouter is a good place to try out a model without creating a separate account and entering your credit card details with every provider.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://realpython.com/courses/multiple-ai-models-openrouter-api/&quot;&gt;OpenRouter video course&lt;/a&gt; covers the platform in depth. For now, all you need is an OpenRouter account with a few dollars of credit on it and an API key from the &lt;a href=&quot;https://openrouter.ai/settings/keys&quot;&gt;keys page&lt;/a&gt; of your account. Jev is cheap, but not free, so a request from an empty account fails.&lt;/p&gt;
&lt;p&gt;You don’t need to pick a model version. The SDK asks for &lt;code&gt;jev-latest&lt;/code&gt; by default, which OpenRouter resolves to the newest Jev release. If you’d rather pin a version so that your results stay reproducible, then you can pass an argument like &lt;code&gt;model=&quot;jev-1.13&quot;&lt;/code&gt; when you create the client later on.&lt;/p&gt;
&lt;h2 id=&quot;step-1-set-up-your-jev-python-project&quot;&gt;Step 1: Set Up Your Jev Python Project&lt;a class=&quot;headerlink&quot; href=&quot;#step-1-set-up-your-jev-python-project&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To get a feel for when Jev can come in handy, it’s a good idea to start with a script that doesn’t use any AI at all. The scenario takes place at a train station. A visitor walks up to the counter, and your script asks if they lost something.&lt;/p&gt;
&lt;p&gt;Create a new folder called &lt;code&gt;jev-python/&lt;/code&gt;, head over to it in your terminal, and add a file named &lt;code&gt;plain_python.py&lt;/code&gt;:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;python&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    &lt;span class=&quot;me-2&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Filename: &lt;/span&gt;&lt;code style=&quot;color: inherit; background: inherit;&quot;&gt;plain_python.py&lt;/code&gt;&lt;/span&gt;
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;linenos&quot;&gt; 1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;respond&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lost_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt; 2&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lost_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt; 3&lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;You can find the lost and found counter on the right.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt; 4&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt; 5&lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;What can I help you with?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt; 6&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt; 7&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt; 8&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt; 9&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Did you lose something? (Y/N) &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;10&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Y&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;11&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;12&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;N&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;13&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;14&lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Please answer with Y or N.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;15&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;17&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;lost_something&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;18&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;respond&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lost_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;19&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;linenos&quot;&gt;21&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;In &lt;strong&gt;line 9&lt;/strong&gt;, you ask the visitor if they lost something, and you want a clear answer. If the input is an uppercase &lt;code&gt;Y&lt;/code&gt; or &lt;code&gt;N&lt;/code&gt;, then &lt;code&gt;ask()&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;. Otherwise, you stay in the &lt;a href=&quot;https://realpython.com/python-while-loop/&quot;&gt;&lt;code&gt;while&lt;/code&gt; loop&lt;/a&gt; until you get one of the two letters.&lt;/p&gt;
&lt;p&gt;Run the script with &lt;code&gt;uv run&lt;/code&gt;, which picks a suitable Python &lt;a href=&quot;/ref/glossary/interpreter/&quot; class=&quot;ref-link&quot;&gt;interpreter&lt;/a&gt; for you:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;uv&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;run&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;plain_python.py
&lt;span class=&quot;go&quot;&gt;Did you lose something? (Y/N) y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Please answer with Y or N.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Did you lose something? (Y/N) Y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;You can find the lost and found counter on the right.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Even a lowercase &lt;code&gt;y&lt;/code&gt; doesn’t count. You could add &lt;code&gt;.upper()&lt;/code&gt; to the answer, so that lowercase input works, too. But now imagine that the visitor says, “Yeah, I’ve lost something.” Where does this stop? Every phrasing that a real person could come up with is another case that your script would need to handle.&lt;/p&gt;
&lt;p&gt;That’s where Jev comes into the picture. To work with Jev in Python, you need the TypeSafe SDK. Create a &lt;code&gt;pyproject.toml&lt;/code&gt; file next to your script and declare the &lt;a href=&quot;/ref/glossary/dependency/&quot; class=&quot;ref-link&quot;&gt;dependency&lt;/a&gt;:&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/jev-python/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/jev-python/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: How to Get Started With Jev in Python</title>
      <id>https://realpython.com/quizzes/jev-python/</id>
      <link href="https://realpython.com/quizzes/jev-python/"/>
      <updated>2026-09-24T12:00:00+00:00</updated>
      <summary>Check your understanding of the Jev AI model in Python, from OpenRouter setup and Noul cutoffs to Choice and Score answers.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/jev-python/&quot;&gt;How to Get Started With Jev in Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how to connect a Python script to Jev through OpenRouter, how to turn a &lt;code&gt;Noul&lt;/code&gt; score into a yes or a no with cutoffs, why the wording of your instructions matters, and how to read &lt;code&gt;Choice&lt;/code&gt; and &lt;code&gt;Score&lt;/code&gt; answers.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll also check that you can recognize the most common setup errors and how to fix them.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: The Terminal: First Steps and Useful Commands for Python Developers</title>
      <id>https://realpython.com/quizzes/terminal-commands/</id>
      <link href="https://realpython.com/quizzes/terminal-commands/"/>
      <updated>2026-09-24T12:00:00+00:00</updated>
      <summary>Test your grasp of terminal basics. Navigate your file system, create files, use virtual environments, install packages, and track code with Git.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/terminal-commands/&quot;&gt;The Terminal: First Steps and Useful Commands for Python Developers&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how to find your way around the file
system, create and inspect files, set up a virtual environment, install packages with
&lt;code&gt;pip&lt;/code&gt;, and take snapshots of your code with Git.&lt;/p&gt;
&lt;p&gt;The terminal rewards practice, so keep one open while you work through the questions.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Cursor vs Copilot: Which AI Editor Is Better for Python?</title>
      <id>https://realpython.com/cursor-vs-copilot/</id>
      <link href="https://realpython.com/cursor-vs-copilot/"/>
      <updated>2026-09-23T14:00:00+00:00</updated>
      <summary>Compare Cursor vs GitHub Copilot by building a Python project, testing agent workflows, debugging code, and evaluating AI-assisted development.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;Choosing between Cursor and GitHub Copilot comes down to how each editor fits your Python workflow, not which one lists more features. Cursor is a standalone AI code editor, while GitHub Copilot brings AI into Visual Studio Code. You’ll build the same Markdown note manager in both and see where they diverge.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you’ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Both editors offer &lt;strong&gt;Agent&lt;/strong&gt;, &lt;strong&gt;Plan&lt;/strong&gt;, and &lt;strong&gt;Ask&lt;/strong&gt; modes, so the differences show up in &lt;strong&gt;workflow&lt;/strong&gt; rather than in feature lists.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cursor&lt;/strong&gt; presents agent-generated changes as diffs and groups them in a dedicated review session, while &lt;strong&gt;Copilot&lt;/strong&gt; applies the edits inline and lets you inspect them before keeping or undoing them.&lt;/li&gt;
&lt;li&gt;Pointing both editors at the &lt;strong&gt;same model&lt;/strong&gt; is what separates editor differences from model differences.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Project conventions&lt;/strong&gt; live in &lt;code&gt;.cursor/rules/&lt;/code&gt; for Cursor and in &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; for Copilot.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To see how the differences play out, you’ll set up both editors, build and debug the same application in each, and compare how they handle code completion, multi-file refactoring, and code review.&lt;/p&gt;
&lt;p&gt;Before getting started, here’s a quick overview of which editor best fits different development workflows:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If you want to…&lt;/th&gt;
&lt;th&gt;Cursor&lt;/th&gt;
&lt;th&gt;GitHub Copilot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Work in a dedicated AI development environment with reviewable edits&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add AI to the &lt;a href=&quot;/ref/code-editors-ides/visual-studio-code/&quot; class=&quot;ref-link&quot;&gt;VS Code&lt;/a&gt; workflow you already use&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Choose &lt;a href=&quot;/ref/ai-coding-tools/cursor/&quot; class=&quot;ref-link&quot;&gt;Cursor&lt;/a&gt; if you want every AI edit staged for review before it touches your files. Choose &lt;a href=&quot;https://realpython.com/github-copilot-python/&quot;&gt;GitHub Copilot&lt;/a&gt; if you’d rather add AI to your existing VS Code setup.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/cursor-vs-copilot-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-cursor-vs-copilot-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; for the Markdown note manager you’ll build with Cursor and GitHub Copilot in this tutorial.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “Cursor vs Copilot: Which AI Editor Is Better for Python?” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/cursor-vs-copilot/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #abe5b2;&quot; alt=&quot;A person sitting between a desk labeled Cursor and a console labeled Copilot, holding up a checklist of green checkmarks and red crosses, next to a chip with the Python logo.&quot; src=&quot;https://files.realpython.com/media/Cursor-vs-Copilot-Which-AI-Coding-Assistant-is-Better-for-Python_Watermarked.bcfe70edf2fa.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Cursor-vs-Copilot-Which-AI-Coding-Assistant-is-Better-for-Python_Watermarked.bcfe70edf2fa.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Cursor-vs-Copilot-Which-AI-Coding-Assistant-is-Better-for-Python_Watermarked.bcfe70edf2fa.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Cursor-vs-Copilot-Which-AI-Coding-Assistant-is-Better-for-Python_Watermarked.bcfe70edf2fa.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Cursor-vs-Copilot-Which-AI-Coding-Assistant-is-Better-for-Python_Watermarked.bcfe70edf2fa.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/cursor-vs-copilot/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;Cursor vs Copilot: Which AI Editor Is Better for Python?&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Test your understanding of how Cursor and GitHub Copilot compare for Python across agent modes, code review, and project conventions.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;metrics-comparison-cursor-vs-github-copilot&quot;&gt;Metrics Comparison: Cursor vs GitHub Copilot&lt;a class=&quot;headerlink&quot; href=&quot;#metrics-comparison-cursor-vs-github-copilot&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The table below highlights some of the key differences between Cursor and GitHub Copilot before you start the hands-on comparison:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Cursor&lt;/th&gt;
&lt;th&gt;GitHub Copilot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;/ref/glossary/ide/&quot; class=&quot;ref-link&quot;&gt;IDE&lt;/a&gt; support&lt;/td&gt;
&lt;td&gt;Standalone &lt;a href=&quot;/ref/ai-coding-glossary/ai/&quot; class=&quot;ref-link&quot;&gt;AI&lt;/a&gt;-first editor built on VS Code&lt;/td&gt;
&lt;td&gt;Extension for VS Code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VS Code extension compatibility&lt;/td&gt;
&lt;td&gt;Supports most VS Code extensions, but some Microsoft-restricted ones, such as &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance&quot;&gt;Pylance&lt;/a&gt;, aren’t available&lt;/td&gt;
&lt;td&gt;Uses the VS Code extension ecosystem, including Microsoft extensions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code review workflow&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Ask&lt;/em&gt; mode, &lt;code&gt;/review&lt;/code&gt;, and Bugbot for reviewing code, uncommitted changes, and pull requests&lt;/td&gt;
&lt;td&gt;Integrated &lt;a href=&quot;https://realpython.com/github-copilot-code-review/&quot;&gt;Copilot code review&lt;/a&gt; for selected code, uncommitted changes, and pull requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro plan pricing&lt;/td&gt;
&lt;td&gt;$20/month, with usage-based Bugbot pricing&lt;/td&gt;
&lt;td&gt;$10/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best suited for&lt;/td&gt;
&lt;td&gt;Large, multi-file codebases and developers who frequently perform AI-assisted &lt;a href=&quot;/ref/best-practices/refactoring/&quot; class=&quot;ref-link&quot;&gt;refactoring&lt;/a&gt; and project-wide changes&lt;/td&gt;
&lt;td&gt;Developers who want a lightweight AI assistant integrated into their existing VS Code workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;The sections that follow focus on the practical experience of using each editor to build, validate, refactor, and review the same Python project.&lt;/p&gt;
&lt;h2 id=&quot;getting-started-installation&quot;&gt;Getting Started: Installation&lt;a class=&quot;headerlink&quot; href=&quot;#getting-started-installation&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You set up Cursor and GitHub Copilot in different ways, but the starting point is the same: you’ll need &lt;a href=&quot;https://realpython.com/installing-python/&quot;&gt;Python 3.12 or later&lt;/a&gt; installed on your system.&lt;/p&gt;
&lt;p&gt;Cursor is a standalone editor, while Copilot integrates directly into &lt;a href=&quot;https://realpython.com/python-development-visual-studio-code/&quot;&gt;VS Code&lt;/a&gt;. Both editors offer free plans. Cursor’s free plan is limited to its latest &lt;a href=&quot;https://cursor.com/docs/models/cursor-composer-2-5&quot;&gt;Composer model&lt;/a&gt;, while GitHub Copilot’s free plan uses automatic model selection only, with no manual model picker.&lt;/p&gt;
&lt;p&gt;To keep the comparison focused on the editors rather than differences between AI models, you’ll configure both editors to use &lt;a href=&quot;https://openrouter.ai/anthropic/claude-sonnet-5&quot;&gt;Claude Sonnet 5&lt;/a&gt;. Selecting the same model requires a Pro subscription for both Cursor and Copilot. You can follow this tutorial without Pro plans, but the two editors will then use different models, which adds another variable.&lt;/p&gt;
&lt;h3 id=&quot;installing-cursor&quot;&gt;Installing Cursor&lt;a class=&quot;headerlink&quot; href=&quot;#installing-cursor&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Head to the &lt;a href=&quot;https://cursor.com/downloads&quot;&gt;Cursor download page&lt;/a&gt; and download the installer for your operating system. When you launch Cursor for the first time, it can import your existing VS Code settings, extensions, themes, and keybindings, letting you get started without reconfiguring your environment.&lt;/p&gt;
&lt;p&gt;However, not every VS Code extension is available in Cursor. Microsoft’s &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance&quot;&gt;Pylance extension&lt;/a&gt;, for example, is licensed for use only with Microsoft products, so it won’t run in Cursor.&lt;/p&gt;
&lt;p&gt;If you’re new to Cursor, Real Python’s video course on &lt;a href=&quot;https://realpython.com/courses/tips-using-ai-coding-editor-cursor/&quot;&gt;Tips for Using the AI Coding Editor Cursor&lt;/a&gt; covers the multi-agent interface, project-aware chat, and inline edits, all of which provide useful background before you compare it with Copilot.&lt;/p&gt;
&lt;h3 id=&quot;enabling-github-copilot-in-vs-code&quot;&gt;Enabling GitHub Copilot in VS Code&lt;a class=&quot;headerlink&quot; href=&quot;#enabling-github-copilot-in-vs-code&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;GitHub Copilot adds AI assistance directly to VS Code, letting you build projects and speed up development without switching editors. Follow these steps to activate it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open VS Code.&lt;/li&gt;
&lt;li&gt;Open the &lt;em&gt;Extensions&lt;/em&gt; view and search for &lt;em&gt;GitHub Copilot Chat&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Select the &lt;em&gt;GitHub Copilot Chat&lt;/em&gt; extension and click &lt;em&gt;Enable AI Features&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The image below shows the extension page:&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/cursor-vs-copilot/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/cursor-vs-copilot/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Using the Claude API in Python</title>
      <id>https://realpython.com/courses/using-claude-api-python/</id>
      <link href="https://realpython.com/courses/using-claude-api-python/"/>
      <updated>2026-09-22T14:00:00+00:00</updated>
      <summary>Learn how to use the Claude API in Python to send prompts, control responses with system instructions, and get structured output.</summary>
      <content type="html">
        &lt;p&gt;The fastest way to use the Claude API in Python is to install &lt;code&gt;anthropic&lt;/code&gt;, set your API key, and call &lt;code&gt;client.messages.create()&lt;/code&gt;. You&amp;rsquo;ll have a working response in under a minute.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/ref/ai-coding-tools/claude/&quot; class=&quot;ref-link&quot;&gt;Claude&lt;/a&gt; is Anthropic&amp;rsquo;s &lt;a href=&quot;/ref/ai-coding-glossary/llm/&quot; class=&quot;ref-link&quot;&gt;large language model&lt;/a&gt;, accessible via a clean &lt;a href=&quot;https://realpython.com/api-integration-in-python/&quot;&gt;REST API&lt;/a&gt; with an official Python SDK. Unlike heavier AI frameworks that require you to wire up multiple components before you see any output, the &lt;code&gt;anthropic&lt;/code&gt; package gets you to a working response in a handful of lines.&lt;/p&gt;
&lt;p&gt;In this video course, you&amp;rsquo;ll install the &lt;code&gt;anthropic&lt;/code&gt; SDK, call Claude from Python, shape Claude&amp;rsquo;s behavior with a &lt;a href=&quot;/ref/ai-coding-glossary/system-prompt/&quot; class=&quot;ref-link&quot;&gt;system prompt&lt;/a&gt;, and then return structured &lt;a href=&quot;https://realpython.com/python-json/&quot;&gt;JSON&lt;/a&gt; output using &lt;a href=&quot;https://realpython.com/python-pydantic/&quot;&gt;Pydantic&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Claude&amp;rsquo;s 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 &lt;a href=&quot;/ref/ai-coding-glossary/token/&quot; class=&quot;ref-link&quot;&gt;tokens&lt;/a&gt; processed. Keep an eye on your usage in the Claude Console as you follow along.&lt;/p&gt;
&lt;p&gt;Each lesson 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.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python 3.15 Preview: frozendict</title>
      <id>https://realpython.com/python315-frozendict/</id>
      <link href="https://realpython.com/python315-frozendict/"/>
      <updated>2026-09-21T14:00:00+00:00</updated>
      <summary>Preview Python 3.15&#x27;s frozendict: build immutable mappings you can hash, cache, and share across threads, and learn where the freeze stops.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;Python 3.15 adds a &lt;code&gt;frozendict&lt;/code&gt; built-in, giving dictionaries the immutable counterpart that lists and sets have had for years. Freezing a mapping buys you two things. You get safety, since nothing can deliberately or accidentally mutate it once it’s built. You also get hashability, which opens doors that stay shut for a regular &lt;code&gt;dict&lt;/code&gt;. In this tutorial, you’ll use a frozen mapping as a dictionary key, a set member, and a cache argument.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you’ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Python 3.15&lt;/strong&gt; ships &lt;code&gt;frozendict&lt;/code&gt; as a &lt;strong&gt;built-in type&lt;/strong&gt;, so you never have to import anything to use it.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;frozendict&lt;/code&gt; is &lt;strong&gt;hashable&lt;/strong&gt; only when all of its &lt;strong&gt;keys and values&lt;/strong&gt; are hashable.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;frozendict&lt;/code&gt; &lt;strong&gt;doesn’t inherit&lt;/strong&gt; from &lt;code&gt;dict&lt;/code&gt;, so your existing &lt;code&gt;isinstance()&lt;/code&gt; checks won’t accept one.&lt;/li&gt;
&lt;li&gt;The freeze is &lt;strong&gt;shallow&lt;/strong&gt;, so a nested list stays mutable and drags the whole mapping’s hashability down with it.&lt;/li&gt;
&lt;li&gt;The augmented assignment operator (&lt;code&gt;|=&lt;/code&gt;) &lt;strong&gt;rebinds&lt;/strong&gt; your variable to a new object instead of mutating the old one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Along the way, you’ll trace the fourteen-year road that three separate &lt;a href=&quot;/ref/glossary/pep/&quot; class=&quot;ref-link&quot;&gt;PEPs&lt;/a&gt; took to get here, watch the mutation methods vanish from a real &lt;a href=&quot;/ref/glossary/repl/&quot; class=&quot;ref-link&quot;&gt;REPL&lt;/a&gt; session, and work through the cases where reaching for a frozen mapping pays off. You’ll also see exactly where immutability has its limits.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The examples in this tutorial use Python 3.15.0rc2, so some details may shift slightly before the &lt;a href=&quot;https://peps.python.org/pep-0790/&quot;&gt;final release&lt;/a&gt; on October 1.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python315-frozendict-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-python315-frozendict-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; you’ll use to build immutable mappings you can hash, cache, and share across threads with Python 3.15.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “Python 3.15 Preview: frozendict” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/python315-frozendict/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #ffc973;&quot; alt=&quot;A person operating a large machine labeled frozendict that encases documents in ice and sends them along a conveyor belt past a sign reading Safe and Hash, with a Python logo on the panel.&quot; src=&quot;https://files.realpython.com/media/Python-3.15-Preview-frozendict_Watermarked.7974ad8c175e.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Python-3.15-Preview-frozendict_Watermarked.7974ad8c175e.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Python-3.15-Preview-frozendict_Watermarked.7974ad8c175e.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Python-3.15-Preview-frozendict_Watermarked.7974ad8c175e.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Python-3.15-Preview-frozendict_Watermarked.7974ad8c175e.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/python315-frozendict/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;Python 3.15 Preview: frozendict&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Test your grasp of Python 3.15&#x27;s frozendict: build immutable mappings, hash them, and use them as dictionary keys.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;get-to-know-python-315s-new-frozendict-type&quot;&gt;Get to Know Python 3.15’s New &lt;code&gt;frozendict&lt;/code&gt; Type&lt;a class=&quot;headerlink&quot; href=&quot;#get-to-know-python-315s-new-frozendict-type&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Python’s &lt;a href=&quot;https://realpython.com/python-dicts/&quot;&gt;dictionaries&lt;/a&gt; have long been the odd ones out among the built-in data containers. For example, you can think of a &lt;a href=&quot;/ref/builtin-types/tuple/&quot; class=&quot;ref-link&quot;&gt;&lt;code&gt;tuple&lt;/code&gt;&lt;/a&gt; as a read-only counterpart to a &lt;a href=&quot;/ref/builtin-types/list/&quot; class=&quot;ref-link&quot;&gt;&lt;code&gt;list&lt;/code&gt;&lt;/a&gt; and a &lt;a href=&quot;/ref/builtin-types/frozenset/&quot; class=&quot;ref-link&quot;&gt;&lt;code&gt;frozenset&lt;/code&gt;&lt;/a&gt; as an immutable counterpart to a &lt;a href=&quot;/ref/builtin-types/set/&quot; class=&quot;ref-link&quot;&gt;&lt;code&gt;set&lt;/code&gt;&lt;/a&gt;. But until Python 3.15, nothing offered that immutable twin for a &lt;a href=&quot;/ref/builtin-types/dict/&quot; class=&quot;ref-link&quot;&gt;&lt;code&gt;dict&lt;/code&gt;&lt;/a&gt;. Python 3.15 finally closes that asymmetry with a new built-in type.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://peps.python.org/pep-0814/&quot;&gt;PEP 814&lt;/a&gt; adds &lt;code&gt;frozendict&lt;/code&gt; to the &lt;a href=&quot;/ref/stdlib/builtins/&quot; class=&quot;ref-link&quot;&gt;built-in namespace&lt;/a&gt; as an &lt;a href=&quot;/ref/glossary/immutable/&quot; class=&quot;ref-link&quot;&gt;immutable&lt;/a&gt; mapping type. It behaves like a dictionary whose contents are fixed once you build it, so you can read the mapping but never add, remove, or replace a key or a value. That restriction is what lets a frozen mapping be &lt;a href=&quot;/ref/glossary/hashable/&quot; class=&quot;ref-link&quot;&gt;hashable&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/python-thread-lock/&quot;&gt;safely shared across threads&lt;/a&gt;, and used in places a regular &lt;code&gt;dict&lt;/code&gt; can’t go.&lt;/p&gt;
&lt;p&gt;Why did that take until 2026? Dictionaries have been in Python since the beginning, and the need for a frozen one isn’t exactly new.&lt;/p&gt;
&lt;h3 id=&quot;trace-the-history-of-frozen-mappings&quot;&gt;Trace the History of Frozen Mappings&lt;a class=&quot;headerlink&quot; href=&quot;#trace-the-history-of-frozen-mappings&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/vstinner&quot;&gt;Victor Stinner&lt;/a&gt; first proposed a &lt;code&gt;frozendict&lt;/code&gt; built-in back in 2012. &lt;a href=&quot;https://peps.python.org/pep-0416/&quot;&gt;PEP 416&lt;/a&gt; laid out much the same design that eventually shipped, and &lt;a href=&quot;/ref/glossary/guido-van-rossum/&quot; class=&quot;ref-link&quot;&gt;Guido van Rossum&lt;/a&gt; rejected the PEP on the grounds that almost nobody was asking for one. The people who did use frozen mappings, he argued, treated them as a hint rather than a guarantee:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;According to Raymond Hettinger, use of frozendict is low. Those that do use it tend to use it as a hint only, such as declaring global or class-level “constants”: they aren’t really immutable, since anyone can still assign to the name.&lt;/p&gt;
&lt;p&gt;— &lt;em&gt;Guido van Rossum&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As things turned out, that rejection wasn’t a dead end. Guido closed the PEP by suggesting that exposing Python’s existing read-only dictionary proxy as a public type sounded worthwhile, and &lt;a href=&quot;https://docs.python.org/3/library/types.html#types.MappingProxyType&quot;&gt;&lt;code&gt;types.MappingProxyType&lt;/code&gt;&lt;/a&gt; arrived in &lt;a href=&quot;https://docs.python.org/3/whatsnew/3.3.html&quot;&gt;Python 3.3&lt;/a&gt; as a direct result. For over a decade, that proxy was the closest thing to an answer.&lt;/p&gt;
&lt;p&gt;Seven years later, &lt;a href=&quot;https://github.com/1st1&quot;&gt;Yury Selivanov&lt;/a&gt; tried a different angle. &lt;a href=&quot;https://peps.python.org/pep-0603/&quot;&gt;PEP 603&lt;/a&gt; proposed a &lt;code&gt;frozenmap&lt;/code&gt; type for the &lt;a href=&quot;/ref/stdlib/collections/&quot; class=&quot;ref-link&quot;&gt;&lt;code&gt;collections&lt;/code&gt;&lt;/a&gt; module, built on a &lt;a href=&quot;https://en.wikipedia.org/wiki/Hash_array_mapped_trie&quot;&gt;hash array mapped trie&lt;/a&gt; so that you could cheaply derive a modified copy. That PEP is still sitting in draft status today, never accepted and never formally rejected.&lt;/p&gt;
&lt;p&gt;Meanwhile, the community had long since stopped waiting for the &lt;a href=&quot;/ref/glossary/standard-library/&quot; class=&quot;ref-link&quot;&gt;standard library&lt;/a&gt; to catch up. Third-party &lt;a href=&quot;/ref/glossary/package/&quot; class=&quot;ref-link&quot;&gt;packages&lt;/a&gt; like &lt;a href=&quot;https://pypi.org/project/frozendict/&quot;&gt;&lt;code&gt;frozendict&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://pypi.org/project/immutables/&quot;&gt;&lt;code&gt;immutables&lt;/code&gt;&lt;/a&gt; filled the gap for anyone who needed an immutable mapping badly enough to add a dependency.&lt;/p&gt;
&lt;p&gt;What finally changed the calculus was &lt;a href=&quot;https://realpython.com/python313-free-threading-jit/&quot;&gt;free threading&lt;/a&gt;. When multiple &lt;a href=&quot;/ref/glossary/thread/&quot; class=&quot;ref-link&quot;&gt;threads&lt;/a&gt; genuinely run Python code at the same time, a mapping that nobody can mutate stops being a stylistic preference and starts being a &lt;a href=&quot;/ref/best-practices/concurrency/&quot; class=&quot;ref-link&quot;&gt;concurrency&lt;/a&gt; tool. PEP 814 landed for Python 3.15, fourteen years after the first attempt.&lt;/p&gt;
&lt;h3 id=&quot;compare-mappingproxytype-with-frozendict&quot;&gt;Compare &lt;code&gt;MappingProxyType&lt;/code&gt; With &lt;code&gt;frozendict&lt;/code&gt;&lt;a class=&quot;headerlink&quot; href=&quot;#compare-mappingproxytype-with-frozendict&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you’ve reached for &lt;code&gt;MappingProxyType&lt;/code&gt; before, then you might wonder what &lt;code&gt;frozendict&lt;/code&gt; adds, given that the proxy already blocks writes:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MappingProxyType&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;debug&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MappingProxyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readonly&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;mappingproxy({&#x27;debug&#x27;: False})&lt;/span&gt;

&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readonly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;debug&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&#x27;mappingproxy&#x27; object does not support item assignment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;The catch is that a proxy isn’t a copy. It’s a live view onto a dictionary that somebody else still owns, so changes to the original show straight through:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;debug&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readonly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;debug&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Nobody wrote through the proxy, and yet the value it reports changed. The proxy protects the object from &lt;em&gt;you&lt;/em&gt;, not from whoever handed it to you.&lt;/p&gt;
&lt;p&gt;The second limitation cuts deeper than the first. A proxy delegates hashing to whatever sits underneath it, so wrapping a dictionary leaves you with something you still can’t hash:&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/python315-frozendict/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/python315-frozendict/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python Statistics Fundamentals: How to Describe Your Data</title>
      <id>https://realpython.com/python-statistics/</id>
      <link href="https://realpython.com/python-statistics/"/>
      <updated>2026-09-19T14:00:00+00:00</updated>
      <summary>Calculate descriptive Python statistics and visualize your data using NumPy, SciPy, pandas, Matplotlib, and the built-in statistics library.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;In the era of big data and &lt;a href=&quot;https://realpython.com/python-ai-neural-network/&quot;&gt;artificial intelligence&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/tutorials/data-science/&quot;&gt;data science&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/tutorials/machine-learning/&quot;&gt;machine learning&lt;/a&gt; have become essential in many fields of science and technology. A necessary aspect of working with data is the ability to describe, summarize, and represent data visually. &lt;strong&gt;Python statistics libraries&lt;/strong&gt; are comprehensive, popular, and widely used tools that will assist you in working with data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this tutorial, you’ll learn:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What &lt;strong&gt;numerical quantities&lt;/strong&gt; you can use to describe and summarize your datasets&lt;/li&gt;
&lt;li&gt;How to &lt;strong&gt;calculate&lt;/strong&gt; descriptive statistics in pure Python&lt;/li&gt;
&lt;li&gt;How to get &lt;strong&gt;descriptive statistics&lt;/strong&gt; with available Python libraries&lt;/li&gt;
&lt;li&gt;How to &lt;strong&gt;visualize&lt;/strong&gt; your datasets&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-statistics-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-python-statistics-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; that shows you how to describe and summarize your data with NumPy, SciPy, pandas, and Python’s statistics module.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “Python Statistics Fundamentals: How to Describe Your Data” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/python-statistics/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #ffc873;&quot; alt=&quot;Python Statistics Fundamentals: How to Describe Your Data&quot; src=&quot;https://files.realpython.com/media/Descriptive-Statistics-in-Python_Watermarked.fec81e9a41f9.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Descriptive-Statistics-in-Python_Watermarked.fec81e9a41f9.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Descriptive-Statistics-in-Python_Watermarked.fec81e9a41f9.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Descriptive-Statistics-in-Python_Watermarked.fec81e9a41f9.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Descriptive-Statistics-in-Python_Watermarked.fec81e9a41f9.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/python-statistics/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;Python Statistics Fundamentals: How to Describe Your Data&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Check your understanding of descriptive statistics in Python, from means and spread to correlation, summaries, and plots that reveal your data.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;understanding-descriptive-statistics&quot;&gt;Understanding Descriptive Statistics&lt;a class=&quot;headerlink&quot; href=&quot;#understanding-descriptive-statistics&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Descriptive statistics&lt;/strong&gt; is about describing and summarizing data. It uses two main approaches:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The quantitative approach&lt;/strong&gt; describes and summarizes data numerically.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The visual approach&lt;/strong&gt; illustrates data with charts, plots, histograms, and other graphs.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can apply descriptive statistics to one or many datasets or &lt;a href=&quot;https://realpython.com/python-variables/&quot;&gt;variables&lt;/a&gt;. When you describe and summarize a single variable, you’re performing &lt;strong&gt;univariate analysis&lt;/strong&gt;. When you search for statistical relationships among a pair of variables, you’re doing a &lt;strong&gt;bivariate analysis&lt;/strong&gt;. Similarly, a &lt;strong&gt;multivariate analysis&lt;/strong&gt; is concerned with multiple variables at once.&lt;/p&gt;
&lt;h3 id=&quot;types-of-measures&quot;&gt;Types of Measures&lt;a class=&quot;headerlink&quot; href=&quot;#types-of-measures&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In this tutorial, you’ll learn about the following types of measures in descriptive statistics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Central tendency&lt;/strong&gt; tells you about the centers of the data. Useful measures include the mean, median, and mode.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Variability&lt;/strong&gt; tells you about the spread of the data. Useful measures include variance and standard deviation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Correlation or joint variability&lt;/strong&gt; tells you about the relation between a pair of variables in a dataset. Useful measures include covariance and the &lt;a href=&quot;https://realpython.com/numpy-scipy-pandas-correlation-python/&quot;&gt;correlation coefficient&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You’ll learn how to understand and calculate these measures with Python.&lt;/p&gt;
&lt;h3 id=&quot;population-and-samples&quot;&gt;Population and Samples&lt;a class=&quot;headerlink&quot; href=&quot;#population-and-samples&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In statistics, the &lt;strong&gt;population&lt;/strong&gt; is a set of all elements or items that you’re interested in. Populations are often vast, which makes them inappropriate for collecting and analyzing data. That’s why statisticians usually try to make some conclusions about a population by choosing and examining a representative subset of that population.&lt;/p&gt;
&lt;p&gt;This subset of a population is called a &lt;strong&gt;sample&lt;/strong&gt;. Ideally, the sample should preserve the essential statistical features of the population to a satisfactory extent. That way, you’ll be able to use the sample to glean conclusions about the population.&lt;/p&gt;
&lt;h3 id=&quot;outliers&quot;&gt;Outliers&lt;a class=&quot;headerlink&quot; href=&quot;#outliers&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;An &lt;strong&gt;outlier&lt;/strong&gt; is a data point that differs significantly from the majority of the data taken from a sample or population. There are many possible causes of outliers, but here are a few to start you off:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Natural variation&lt;/strong&gt; in data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Change&lt;/strong&gt; in the behavior of the observed system&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Errors&lt;/strong&gt; in data collection&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Data collection errors are a particularly prominent cause of outliers. For example, the limitations of measurement instruments or procedures can mean that the correct data is simply not obtainable. Other errors can be caused by miscalculations, data contamination, human error, and more.&lt;/p&gt;
&lt;p&gt;There isn’t a precise mathematical definition of outliers. You have to rely on experience, knowledge about the subject of interest, and common sense to determine if a data point is an outlier and how to handle it.&lt;/p&gt;
&lt;h2 id=&quot;choosing-python-statistics-libraries&quot;&gt;Choosing Python Statistics Libraries&lt;a class=&quot;headerlink&quot; href=&quot;#choosing-python-statistics-libraries&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are many Python statistics libraries out there for you to work with, but in this tutorial, you’ll be learning about some of the most popular and widely used ones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Python’s &lt;a href=&quot;https://docs.python.org/3/library/statistics.html&quot;&gt;&lt;code&gt;statistics&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; is a built-in Python library for descriptive statistics. You can use it if your datasets are not too large or if you can’t rely on importing other libraries.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://numpy.org/doc/stable/user/index.html&quot;&gt;NumPy&lt;/a&gt;&lt;/strong&gt; is a third-party library for numerical computing, optimized for working with single- and multi-dimensional &lt;a href=&quot;/ref/glossary/array/&quot; class=&quot;ref-link&quot;&gt;arrays&lt;/a&gt;. Its primary type is the array type called &lt;a href=&quot;https://numpy.org/doc/stable/reference/arrays.ndarray.html&quot;&gt;&lt;code&gt;ndarray&lt;/code&gt;&lt;/a&gt;. This library contains many &lt;a href=&quot;https://numpy.org/doc/stable/reference/routines.statistics.html&quot;&gt;routines&lt;/a&gt; for statistical analysis.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://docs.scipy.org/doc/scipy/&quot;&gt;SciPy&lt;/a&gt;&lt;/strong&gt; is a third-party library for scientific computing based on NumPy. It offers additional functionality compared to NumPy, including &lt;a href=&quot;https://docs.scipy.org/doc/scipy/reference/stats.html&quot;&gt;&lt;code&gt;scipy.stats&lt;/code&gt;&lt;/a&gt; for statistical analysis.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/&quot;&gt;pandas&lt;/a&gt;&lt;/strong&gt; is a third-party library for numerical computing based on NumPy. It excels in handling labeled one-dimensional (1D) data with &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html&quot;&gt;&lt;code&gt;Series&lt;/code&gt;&lt;/a&gt; objects and two-dimensional (2D) data with &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html&quot;&gt;&lt;code&gt;DataFrame&lt;/code&gt;&lt;/a&gt; objects.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://matplotlib.org/&quot;&gt;Matplotlib&lt;/a&gt;&lt;/strong&gt; is a third-party library for data visualization. It works well in combination with NumPy, SciPy, and pandas.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that, in many cases, &lt;code&gt;Series&lt;/code&gt; and &lt;a href=&quot;https://realpython.com/pandas-dataframe/&quot;&gt;&lt;code&gt;DataFrame&lt;/code&gt;&lt;/a&gt; objects can be used in place of NumPy arrays. Often, you might just pass them to a NumPy or &lt;a href=&quot;https://realpython.com/python-scipy-cluster-optimize/&quot;&gt;SciPy&lt;/a&gt; statistical &lt;a href=&quot;/ref/glossary/function/&quot; class=&quot;ref-link&quot;&gt;function&lt;/a&gt;. In addition, you can get the unlabeled data from a &lt;code&gt;Series&lt;/code&gt; or &lt;code&gt;DataFrame&lt;/code&gt; as a &lt;code&gt;np.ndarray&lt;/code&gt; object by calling &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.values.html&quot;&gt;&lt;code&gt;.values&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_numpy.html&quot;&gt;&lt;code&gt;.to_numpy()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/python-statistics/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/python-statistics/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>How to Review AI-Generated Python Code Efficiently</title>
      <id>https://realpython.com/review-ai-generated-code/</id>
      <link href="https://realpython.com/review-ai-generated-code/"/>
      <updated>2026-09-16T14:00:00+00:00</updated>
      <summary>Learn an efficient workflow to review AI-generated code in Python: run ruff, mypy, bandit, and pytest, then catch the bugs agents get wrong.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;To review AI-generated code efficiently, you need to put your attention where AI coding agents are most likely to be wrong. This makes your code reviews faster and more accurate.&lt;/p&gt;
&lt;p&gt;Reviewing an agent’s code isn’t fundamentally different from reviewing a teammate’s. A code review is the process of looking at a change to a codebase before accepting it, so you can confirm that the code does what it should and that it’s correct, secure, and maintainable. This responsibility doesn’t change when the author is an agent. What changes is the amount of code, how fast it arrives, and the mix of potential issues.&lt;/p&gt;
&lt;p&gt;An AI coding agent writes code faster than any human can read it, which makes you the bottleneck. Your job and responsibilities stay the same, but the volume and speed increase.&lt;/p&gt;
&lt;p&gt;To manage this, you need to review the code with a plan. You can’t read every line, so focus on the parts where the risk is highest.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; What you’re checking for is the same as with a teammate’s code, but it’s harder in practice because the code comes faster and in bigger chunks. As both the speed and size increase, you’re more likely to miss mistakes. Most people start to lose focus after about four hundred lines of code or an hour of work.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;AI-generated code also changes the kinds of mistakes you’ll find. The logic can look correct but be wrong. The code can call APIs or import packages that don’t exist. It can also skip edge cases. A piece of code with these types of issues can look fine at first glance.&lt;/p&gt;
&lt;p&gt;In this tutorial, you’ll learn a &lt;strong&gt;five-step workflow&lt;/strong&gt; to review AI-generated code in an efficient and repeatable way:&lt;/p&gt;
&lt;figure class=&quot;js-lightbox&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/diagram-review-ai-generated-code-workflow.3c5fd2868e14.svg&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/diagram-review-ai-generated-code-workflow.3c5fd2868e14.svg&quot; width=&quot;303&quot; height=&quot;511&quot; alt=&quot;Five review steps run top to bottom, looping back to the reading step on a false alarm and to the automated checks when a fix fails.&quot; data-asset=&quot;7268&quot;&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Five Steps, Two Feedback Loops&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;You start with the code’s intent, then run some automated checks. After that, you read what’s left, starting with the trickiest parts. At this stage, you catch the mistakes that agents often make. You’ll also confirm each problem by running the code before you fix it.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Cheat Sheet:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/review-ai-generated-code-cheatsheet/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-review-ai-generated-code-cheatsheet&quot; markdown&gt;Click here to download your free checklist for reviewing AI-generated code&lt;/a&gt; and keep every mistake worth hunting for within reach on your next review.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “How to Review AI-Generated Python Code Efficiently” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/review-ai-generated-code/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #e5c6aa;&quot; alt=&quot;A person seated with a magnifying glass inspects a long code printout beside a machine that feeds code through numbered filters into a junk tray, with a Python logo on its panel.&quot; src=&quot;https://files.realpython.com/media/Reviewing-AI-Generated-Code-Efficiently_Watermarked.8c62ca1e6824.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Reviewing-AI-Generated-Code-Efficiently_Watermarked.8c62ca1e6824.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Reviewing-AI-Generated-Code-Efficiently_Watermarked.8c62ca1e6824.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Reviewing-AI-Generated-Code-Efficiently_Watermarked.8c62ca1e6824.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Reviewing-AI-Generated-Code-Efficiently_Watermarked.8c62ca1e6824.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/review-ai-generated-code/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;How to Review AI-Generated Python Code Efficiently&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Test your understanding of how to review AI-generated Python code, from automated checks to the bugs that coding agents get wrong most often.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;a class=&quot;headerlink&quot; href=&quot;#prerequisites&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To follow along, you should be comfortable reading Python code and working with a &lt;a href=&quot;/ref/ai-coding-glossary/agent/&quot; class=&quot;ref-link&quot;&gt;coding agent&lt;/a&gt;, such as &lt;a href=&quot;/ref/ai-coding-tools/claude-code/&quot; class=&quot;ref-link&quot;&gt;Claude Code&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/github-copilot-cli/&quot;&gt;GitHub Copilot CLI&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/antigravity-cli/&quot;&gt;Antigravity CLI&lt;/a&gt;, and &lt;a href=&quot;https://realpython.com/opencode-guide/&quot;&gt;OpenCode&lt;/a&gt;. You’ll also get more from it if you’re already familiar with &lt;a href=&quot;https://realpython.com/debug-python-errors/&quot;&gt;debugging Python errors&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/python-type-checking/&quot;&gt;type checking&lt;/a&gt;, and reading a &lt;a href=&quot;https://realpython.com/how-to-use-git/#view-your-changes&quot;&gt;Git diff&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ideally, you’ll want to practice with some AI-generated code. You’ll learn the most when you run the workflow on a real agent pull request or a small project that an agent has generated. Use the Python version that the target project uses. For a new project, you can choose a recent one. Python &lt;a href=&quot;https://realpython.com/python314-new-features/&quot;&gt;3.14&lt;/a&gt; is a good choice.&lt;/p&gt;
&lt;p&gt;You’ll also need some tools to run quality checks on your code, such as linters, &lt;a href=&quot;/ref/glossary/static-type-checker/&quot; class=&quot;ref-link&quot;&gt;static type checkers&lt;/a&gt;, security scanners, and &lt;a href=&quot;/ref/computer-science-glossary/test-runner/&quot; class=&quot;ref-link&quot;&gt;test runners&lt;/a&gt;. You can install them into your project’s &lt;a href=&quot;/ref/glossary/virtual-environment/&quot; class=&quot;ref-link&quot;&gt;virtual environment&lt;/a&gt;. Here’s a minimal set of tools you can use:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(venv)&lt;/span&gt; &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;python&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;ruff&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;mypy&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bandit&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pytest&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pytest-cov&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pip-audit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;These are development dependencies, so they should stay separate from the packages your project needs to run. If you manage your project with &lt;a href=&quot;https://realpython.com/python-uv/&quot;&gt;&lt;code&gt;uv&lt;/code&gt;&lt;/a&gt;, then you can add them to a dedicated &lt;code&gt;dev&lt;/code&gt; dependency group instead:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;uv&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;add&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;--dev&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;ruff&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;mypy&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bandit&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pytest&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pytest-cov&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pip-audit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;If you prefer a faster type checker, swap &lt;code&gt;mypy&lt;/code&gt; for &lt;a href=&quot;https://realpython.com/python-ty/&quot;&gt;&lt;code&gt;ty&lt;/code&gt;&lt;/a&gt;, a newer alternative from the makers of Ruff.&lt;/p&gt;
&lt;p&gt;For the deeper maintainability checks, add the extended set when you need it:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(venv)&lt;/span&gt; &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;python&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pylint&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;radon&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;import-linter&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pydeps
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;You can configure the core tools in one place. This minimal configuration turns on the rules that matter most for AI-generated code:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;toml&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--grey&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;TOML&lt;/span&gt;
    &lt;span class=&quot;me-2&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Filename: &lt;/span&gt;&lt;code style=&quot;color: inherit; background: inherit;&quot;&gt;pyproject.toml&lt;/code&gt;&lt;/span&gt;
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[tool.ruff.lint]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;F&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;E&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;S&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;UP&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;DTZ&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[tool.mypy]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;strict&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[tool.coverage.run]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;branch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.8f1dcd28e216.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;You’ll also want a way to see what changed in the code. Most code reviews happen on a &lt;a href=&quot;https://realpython.com/how-to-use-github/&quot;&gt;GitHub&lt;/a&gt; pull request (PR). There, you can read the diff in the browser with a friendly user interface (UI).&lt;/p&gt;
&lt;p&gt;You can also read the diff locally in your terminal. The &lt;a href=&quot;https://cli.github.com/&quot;&gt;GitHub CLI&lt;/a&gt; tool prints a pull request’s changes with &lt;code&gt;gh pr diff&lt;/code&gt;, and when there’s no PR yet, &lt;a href=&quot;https://realpython.com/how-to-use-git/&quot;&gt;Git&lt;/a&gt; shows them with &lt;code&gt;git diff&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/review-ai-generated-code/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/review-ai-generated-code/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Automating EDA With fg-data-profiling</title>
      <id>https://realpython.com/courses/automating-eda-with-fg-data-profiling/</id>
      <link href="https://realpython.com/courses/automating-eda-with-fg-data-profiling/"/>
      <updated>2026-09-15T14:00:00+00:00</updated>
      <summary>Automate exploratory data analysis by transforming DataFrames into interactive reports with one command from fg-data-profiling.</summary>
      <content type="html">
        &lt;p&gt;The &lt;code&gt;fg-data-profiling&lt;/code&gt; package generates an exploratory data analysis (EDA) report with a few lines of code. The report provides a dataset and column-level analysis, including plots and summary statistics, to help you quickly understand your dataset. These reports can be exported to HTML or JSON so you can share them with other stakeholders.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this video course, you&amp;rsquo;ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;fg-data-profiling&lt;/code&gt; generates interactive reports&lt;/strong&gt; containing EDA results, including summary statistics, visualizations, correlation matrices, and data quality warnings from DataFrames.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;ProfileReport&lt;/code&gt; creates a profile&lt;/strong&gt; you can save with &lt;code&gt;.to_file()&lt;/code&gt; for HTML or JSON export, or display inline with &lt;code&gt;.to_notebook_iframe()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Setting &lt;code&gt;tsmode=True&lt;/code&gt; and specifying a date column with &lt;code&gt;sortby&lt;/code&gt; &lt;strong&gt;enables time series analysis&lt;/strong&gt;, including stationarity tests and seasonality detection.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &lt;code&gt;.compare()&lt;/code&gt; method generates side-by-side reports&lt;/strong&gt; highlighting distribution shifts and statistical differences between datasets.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To get the most out of this course, you&amp;rsquo;ll benefit from having knowledge of &lt;a href=&quot;https://realpython.com/learning-paths/pandas-data-science/&quot;&gt;pandas&lt;/a&gt;.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #311: Django Developers Survey Results &amp; Reproducible Python Builds</title>
      <id>https://realpython.com/podcasts/rpp/311/</id>
      <link href="https://realpython.com/podcasts/rpp/311/"/>
      <updated>2026-09-11T12:00:00+00:00</updated>
      <summary>What are the latest trends uncovered in the 2026 Django Developers Survey? How are Django users employing LLMs in their development process? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.</summary>
      <content type="html">
        &lt;p&gt;What are the latest trends uncovered in the 2026 Django Developers Survey? How are Django users employing LLMs in their development process? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python Timer Functions</title>
      <id>https://realpython.com/courses/python-timer-functions/</id>
      <link href="https://realpython.com/courses/python-timer-functions/"/>
      <updated>2026-09-08T14:00:00+00:00</updated>
      <summary>Learn how to time your Python code with the time module, then build a reusable Timer class that works as a context manager.</summary>
      <content type="html">
        &lt;p&gt;A timer is a powerful tool for monitoring the performance of your Python code. By using the &lt;code&gt;time.perf_counter()&lt;/code&gt; function, you can measure execution time with exceptional precision, making it ideal for benchmarking. Using a timer involves recording timestamps before and after a specific code block and calculating the time difference to determine how long your code took to run.&lt;/p&gt;
&lt;p&gt;In this video course, you&amp;rsquo;ll start with the timer functions in Python&amp;rsquo;s &lt;code&gt;time&lt;/code&gt; module and then abstract them into a reusable &lt;code&gt;Timer&lt;/code&gt; class. You&amp;rsquo;ll extend that class to track multiple timers, convert it to a data class for convenience, and finally turn it into a context manager so you can time a block of code using a single &lt;code&gt;with&lt;/code&gt; statement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;time.perf_counter()&lt;/code&gt;&lt;/strong&gt; is the best choice for accurate timing in Python due to its high resolution.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;process_time()&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;time()&lt;/code&gt;&lt;/strong&gt; measure different things, so picking the wrong one can skew your results.&lt;/li&gt;
&lt;li&gt;You can create a &lt;strong&gt;custom timer class&lt;/strong&gt; to encapsulate timing logic and reuse it across multiple parts of your program.&lt;/li&gt;
&lt;li&gt;Turning your timer into a &lt;strong&gt;data class&lt;/strong&gt; cuts down on boilerplate and makes it easier to configure.&lt;/li&gt;
&lt;li&gt;You can leverage &lt;strong&gt;context managers&lt;/strong&gt; to neatly measure execution time in specific code blocks, improving both resource management and code clarity.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Along the way, you&amp;rsquo;ll gain deeper insights into how &lt;a href=&quot;https://realpython.com/python-classes/&quot;&gt;classes&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/python-data-classes/&quot;&gt;data classes&lt;/a&gt;, and &lt;a href=&quot;https://realpython.com/python-with-statement/&quot;&gt;context managers&lt;/a&gt; work in Python.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #310: Performance Engineering: Profiling and Making Apps Fast by Default</title>
      <id>https://realpython.com/podcasts/rpp/310/</id>
      <link href="https://realpython.com/podcasts/rpp/310/"/>
      <updated>2026-09-04T12:00:00+00:00</updated>
      <summary>How do you plan for the performance of your Python applications? What does a performance budget entail, and where should you spend your resources? This week on the show, we speak with Den Odell about his new book &quot;Fast by Default: Practical Performance Engineering.&quot;</summary>
      <content type="html">
        &lt;p&gt;How do you plan for the performance of your Python applications? What does a performance budget entail, and where should you spend your resources? This week on the show, we speak with Den Odell about his new book &quot;Fast by Default: Practical Performance Engineering.&quot;&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>How to Get Started With Ollama</title>
      <id>https://realpython.com/courses/get-started-with-ollama/</id>
      <link href="https://realpython.com/courses/get-started-with-ollama/"/>
      <updated>2026-09-01T14:00:00+00:00</updated>
      <summary>Learn how to install Ollama, pull local models, and connect them to your Python code using the chat and text generation interfaces.</summary>
      <content type="html">
        &lt;p&gt;Integrating local large language models (LLMs) into your Python projects with Ollama is a great way to improve privacy, reduce costs, and build offline-capable AI-powered apps.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ollama&lt;/strong&gt; is an open-source platform that makes it straightforward to run modern LLMs locally on your machine. Once you&amp;rsquo;ve set up Ollama and pulled the models you want to use, you can connect to them from Python using the &lt;code&gt;ollama&lt;/code&gt; library.&lt;/p&gt;
&lt;p&gt;In this video course, you&amp;rsquo;ll integrate local LLMs into your Python projects using the Ollama platform and its Python SDK.&lt;/p&gt;
&lt;p&gt;First, you&amp;rsquo;ll set up Ollama and pull a couple of LLMs. Then, you&amp;rsquo;ll learn how to use chat and text generation from your Python code. These skills will enable you to build AI-powered apps that run locally, ensuring better privacy and reducing costs.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #309: Exploring Complex Systems &amp; Maintainable Data Science Pipelines</title>
      <id>https://realpython.com/podcasts/rpp/309/</id>
      <link href="https://realpython.com/podcasts/rpp/309/"/>
      <updated>2026-08-28T12:00:00+00:00</updated>
      <summary>What are the key characteristics of complex systems, and what are practical patterns for tackling complex coding problems? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.</summary>
      <content type="html">
        &lt;p&gt;What are the key characteristics of complex systems, and what are practical patterns for tackling complex coding problems? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Python print() Function: Go Beyond the Basics</title>
      <id>https://realpython.com/courses/python-print/</id>
      <link href="https://realpython.com/courses/python-print/"/>
      <updated>2026-08-25T14:00:00+00:00</updated>
      <summary>Learn about Python&#x27;s print() function, discover its lesser-known features, avoid common mistakes, and know when to use a better alternative.</summary>
      <content type="html">
        &lt;p&gt;If you&amp;rsquo;re like most Python users, including us, then you probably started your Python journey by learning about &lt;strong&gt;&lt;code&gt;print()&lt;/code&gt;&lt;/strong&gt;. It helped you write your very own &lt;code&gt;Hello World&lt;/code&gt; one-liner. You can use it to display formatted messages onto the screen and perhaps find some bugs. But if you think that&amp;rsquo;s all there is to know about Python&amp;rsquo;s &lt;code&gt;print()&lt;/code&gt;, then you&amp;rsquo;re missing out on a lot!&lt;/p&gt;
&lt;p&gt;Keep reading to take full advantage of this underappreciated little function. This course will get you up to speed with using Python &lt;code&gt;print()&lt;/code&gt; effectively. Prepare for a deep dive as you go through the sections. You may be surprised how much &lt;code&gt;print()&lt;/code&gt; has to offer!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll know how to:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Avoid common mistakes with Python&amp;rsquo;s &lt;code&gt;print()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Deal with newlines, character encodings, and buffering&lt;/li&gt;
&lt;li&gt;Write text to files&lt;/li&gt;
&lt;li&gt;Mock &lt;code&gt;print()&lt;/code&gt; in unit tests&lt;/li&gt;
&lt;li&gt;Build advanced user interfaces in the terminal&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;print()&lt;/code&gt; was a major addition to Python 3, in which it replaced the old &lt;code&gt;print&lt;/code&gt; statement available in Python 2.&lt;/p&gt;
&lt;p&gt;There were a number of good reasons for that, as you&amp;rsquo;ll see shortly. Although this tutorial focuses on Python 3, it does show the old way of printing in Python for reference.&lt;/p&gt;
&lt;/div&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #308: Navigating Silent Failures in AI: Strategies for Effective Oversight</title>
      <id>https://realpython.com/podcasts/rpp/308/</id>
      <link href="https://realpython.com/podcasts/rpp/308/"/>
      <updated>2026-08-21T12:00:00+00:00</updated>
      <summary>Why do AI systems silently fail? How can you set up a system that produces results while also reviewing and validating the work? This week on the show, Calvin Hendryx-Parker returns to discuss his recent talk &quot;Orchestrate Agentic AI: Context, Checklists, and No-Miss Reviews.&quot;</summary>
      <content type="html">
        &lt;p&gt;Why do AI systems silently fail? How can you set up a system that produces results while also reviewing and validating the work? This week on the show, Calvin Hendryx-Parker returns to discuss his recent talk &quot;Orchestrate Agentic AI: Context, Checklists, and No-Miss Reviews.&quot;&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Working With Python&#x27;s deque</title>
      <id>https://realpython.com/courses/working-with-pythons-deque/</id>
      <link href="https://realpython.com/courses/working-with-pythons-deque/"/>
      <updated>2026-08-18T14:00:00+00:00</updated>
      <summary>Learn how to use Python&#x27;s deque to efficiently append and pop items from both ends, build queues and stacks, and set maxlen for bounded history.</summary>
      <content type="html">
        &lt;p&gt;You can use Python&amp;rsquo;s &lt;code&gt;deque&lt;/code&gt; for efficient appends and pops at both ends of a sequence-like data type. These capabilities are critical when you need to implement queue and stack data structures that operate efficiently even under heavy workloads.&lt;/p&gt;
&lt;p&gt;In this video course, you&amp;rsquo;ll learn how &lt;code&gt;deque&lt;/code&gt; works, when to use it over a &lt;code&gt;list&lt;/code&gt;, and how to apply it in real code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;deque&lt;/code&gt; internally uses a &lt;strong&gt;doubly &lt;a href=&quot;/ref/computer-science-glossary/linked-list/&quot; class=&quot;ref-link&quot;&gt;linked list&lt;/a&gt;&lt;/strong&gt;, so end operations are &lt;em&gt;O(1)&lt;/em&gt; while random indexing is &lt;em&gt;O(n)&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;You can build a &lt;strong&gt;FIFO queue&lt;/strong&gt; with &lt;strong&gt;&lt;code&gt;.append()&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;.popleft()&lt;/code&gt;&lt;/strong&gt;, and a &lt;strong&gt;LIFO stack&lt;/strong&gt; with &lt;strong&gt;&lt;code&gt;.append()&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;.pop()&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;deque&lt;/code&gt; supports &lt;strong&gt;indexing&lt;/strong&gt; but doesn&amp;rsquo;t support &lt;strong&gt;slicing&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Passing a value to &lt;strong&gt;&lt;code&gt;maxlen&lt;/code&gt;&lt;/strong&gt; creates a bounded deque that &lt;strong&gt;drops items&lt;/strong&gt; from the opposite end when full.&lt;/li&gt;
&lt;li&gt;In CPython, &lt;strong&gt;&lt;code&gt;.append()&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;.appendleft()&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;.pop()&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;.popleft()&lt;/code&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;code&gt;len()&lt;/code&gt;&lt;/strong&gt; are &lt;strong&gt;thread-safe&lt;/strong&gt; for multithreaded use.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Up next, you&amp;rsquo;ll get started with &lt;code&gt;deque&lt;/code&gt;, benchmark it against &lt;code&gt;list&lt;/code&gt;, and explore how it shines in real-world use cases, such as queues, stacks, history buffers, and thread-safe producer-consumer setups.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #307: Improving NumPy Performance on Free-Threaded Python</title>
      <id>https://realpython.com/podcasts/rpp/307/</id>
      <link href="https://realpython.com/podcasts/rpp/307/"/>
      <updated>2026-08-14T12:00:00+00:00</updated>
      <summary>What bottlenecks were preventing NumPy from scaling on free-threaded Python? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.</summary>
      <content type="html">
        &lt;p&gt;What bottlenecks were preventing NumPy from scaling on free-threaded Python? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Coding With OpenCode: AI-Assisted Python</title>
      <id>https://realpython.com/courses/coding-with-opencode-ai/</id>
      <link href="https://realpython.com/courses/coding-with-opencode-ai/"/>
      <updated>2026-08-11T14:00:00+00:00</updated>
      <summary>Learn how to use OpenCode for AI-assisted Python coding, using a free Gemini API key to analyze and refactor code right in your terminal.</summary>
      <content type="html">
        &lt;p&gt;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 video course, you&amp;rsquo;ll 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.&lt;/p&gt;
&lt;p&gt;OpenCode works as a conversational assistant you explicitly direct. Ask it to analyze functions, refactor code, or explain issues. Press Enter to send your query, and you&amp;rsquo;ll get a response with full awareness of your project context. It supports more than seventy-five AI providers, including Anthropic, OpenAI, and Google Gemini.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re a Python developer who prefers working in the terminal, OpenCode offers deliberate, context-aware assistance and a customizable &lt;code&gt;AGENTS.md&lt;/code&gt; configuration file.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #306: Programmatically Developing LLM Prompts With DSPy</title>
      <id>https://realpython.com/podcasts/rpp/306/</id>
      <link href="https://realpython.com/podcasts/rpp/306/"/>
      <updated>2026-08-07T12:00:00+00:00</updated>
      <summary>How can you move from manually writing prompts for an LLM application toward defining them programmatically? This week on the show, Brett Kennedy returns to discuss his new book &quot;Building LLM Applications with DSPy.&quot;</summary>
      <content type="html">
        &lt;p&gt;How can you move from manually writing prompts for an LLM application toward defining them programmatically? This week on the show, Brett Kennedy returns to discuss his new book &quot;Building LLM Applications with DSPy.&quot;&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Sending Emails Using Python</title>
      <id>https://realpython.com/courses/sending-emails-using-python/</id>
      <link href="https://realpython.com/courses/sending-emails-using-python/"/>
      <updated>2026-08-04T14:00:00+00:00</updated>
      <summary>Learn how to send emails with Python using SMTP and smtplib, attach files, format HTML messages, and personalize bulk emails.</summary>
      <content type="html">
        &lt;p&gt;You probably found this video course because you want to send emails with Python to automate confirmation messages, password resets, or scheduled notifications. Python&amp;rsquo;s standard library covers the whole pipeline, from making a server connection to building the message and sending it to one or many recipients. This course walks through every step in working code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A safe testing setup uses a &lt;strong&gt;throwaway Gmail account&lt;/strong&gt; with an &lt;strong&gt;app password&lt;/strong&gt;, a local &lt;code&gt;aiosmtpd&lt;/code&gt; debug server, or a privacy-focused provider like Posteo or Proton Mail.&lt;/li&gt;
&lt;li&gt;A secure SMTP session uses &lt;code&gt;.SMTP_SSL()&lt;/code&gt; with &lt;code&gt;ssl.create_default_context()&lt;/code&gt;, which &lt;strong&gt;validates the server certificate&lt;/strong&gt; and &lt;strong&gt;encrypts&lt;/strong&gt; your credentials and message content.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;EmailMessage&lt;/code&gt; class from the &lt;code&gt;email&lt;/code&gt; package assembles &lt;strong&gt;plain text&lt;/strong&gt;, &lt;strong&gt;HTML alternatives&lt;/strong&gt;, &lt;strong&gt;file attachments&lt;/strong&gt;, and &lt;strong&gt;personalized fields&lt;/strong&gt; through &lt;code&gt;.set_content()&lt;/code&gt;, &lt;code&gt;.add_alternative()&lt;/code&gt;, and &lt;code&gt;.add_attachment()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Setting &lt;code&gt;msg[&quot;reply-to&quot;]&lt;/code&gt; or any other RFC 5322 header on an &lt;code&gt;EmailMessage&lt;/code&gt; routes &lt;strong&gt;replies&lt;/strong&gt; to a different mailbox than the sender address.&lt;/li&gt;
&lt;li&gt;For high-volume sending, &lt;strong&gt;transactional email services&lt;/strong&gt; like SendGrid, Mailgun, and Brevo provide deliverability, statistics, and &lt;strong&gt;API libraries&lt;/strong&gt; that go beyond what &lt;code&gt;smtplib&lt;/code&gt; alone offers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before you jump into the code, you&amp;rsquo;ll set up a throwaway email account or a local debug server so you can experiment freely without spamming real inboxes.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #305: Should You Understand Your Entire Python Codebase?</title>
      <id>https://realpython.com/podcasts/rpp/305/</id>
      <link href="https://realpython.com/podcasts/rpp/305/"/>
      <updated>2026-07-31T12:00:00+00:00</updated>
      <summary>Should you understand the entirety of your codebase? How familiar are you with Python&#x27;s built-in functions? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.</summary>
      <content type="html">
        &lt;p&gt;Should you understand the entirety of your codebase? How familiar are you with Python&#x27;s built-in functions? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Managing Imports With Python&#x27;s __all__</title>
      <id>https://realpython.com/courses/managing-imports-dunder-all/</id>
      <link href="https://realpython.com/courses/managing-imports-dunder-all/"/>
      <updated>2026-07-28T14:00:00+00:00</updated>
      <summary>Learn how Python&#x27;s dunder all variable controls wildcard imports and shapes the public API your packages and modules expose.</summary>
      <content type="html">
        &lt;p&gt;Python has something called &lt;strong&gt;wildcard imports&lt;/strong&gt;, which look like &lt;code&gt;from module import *&lt;/code&gt;. This type of import allows you to quickly get all the objects from a module into your namespace. However, using this import on a package can be confusing because it&amp;rsquo;s not clear what you want to import: subpackages, modules, objects? Python has the &lt;strong&gt;&lt;code&gt;__all__&lt;/code&gt;&lt;/strong&gt; variable to work around this issue.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;__all__&lt;/code&gt; variable is a list of strings where each string represents the name of a variable, function, class, or module that you want to expose to wildcard imports.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this video course, you&amp;rsquo;ll:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Understand &lt;strong&gt;wildcard imports&lt;/strong&gt; in Python&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;&lt;code&gt;__all__&lt;/code&gt;&lt;/strong&gt; to control the modules that you &lt;strong&gt;expose&lt;/strong&gt; to wildcard imports&lt;/li&gt;
&lt;li&gt;Control the &lt;strong&gt;names&lt;/strong&gt; that you expose in &lt;strong&gt;modules&lt;/strong&gt; and &lt;strong&gt;packages&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Explore &lt;strong&gt;other use cases&lt;/strong&gt; of the &lt;code&gt;__all__&lt;/code&gt; variable&lt;/li&gt;
&lt;li&gt;Learn some &lt;strong&gt;benefits&lt;/strong&gt; and &lt;strong&gt;best practices&lt;/strong&gt; of using &lt;code&gt;__all__&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To get the most out of this course, you should be familiar with a few Python concepts, including &lt;a href=&quot;https://realpython.com/python-modules-packages/&quot;&gt;modules and packages&lt;/a&gt;, and the &lt;a href=&quot;https://realpython.com/python-import/&quot;&gt;import&lt;/a&gt; system.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #304: Configuring a Versatile LLM Harness &amp; Scraping the Web With Scrapy</title>
      <id>https://realpython.com/podcasts/rpp/304/</id>
      <link href="https://realpython.com/podcasts/rpp/304/"/>
      <updated>2026-07-24T12:00:00+00:00</updated>
      <summary>Which is more important, the model or the &quot;harness&quot; around an LLM? What are ways to assemble an efficient agentic developer workflow? This week on the show, Ayan Pahwa joins us to discuss harnessing, web scraping, and self-hosting Python applications.</summary>
      <content type="html">
        &lt;p&gt;Which is more important, the model or the &quot;harness&quot; around an LLM? What are ways to assemble an efficient agentic developer workflow? This week on the show, Ayan Pahwa joins us to discuss harnessing, web scraping, and self-hosting Python applications.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: FastAPI: Python API Development With Light Speed</title>
      <id>https://realpython.com/learning-paths/fastapi/</id>
      <link href="https://realpython.com/learning-paths/fastapi/"/>
      <updated>2026-07-22T12:00:00+00:00</updated>
      <summary>Learn FastAPI from the ground up. Build REST APIs, serve web pages with Jinja2 templates, and create a complete URL shortener project in Python.</summary>
      <content type="html">
        &lt;p&gt;Learn FastAPI from the ground up. Build REST APIs, serve web pages with Jinja2 templates, and create a complete URL shortener project in Python.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #303: Free-Threaded Python&#x27;s History &amp; uv in Production</title>
      <id>https://realpython.com/podcasts/rpp/303/</id>
      <link href="https://realpython.com/podcasts/rpp/303/"/>
      <updated>2026-07-17T12:00:00+00:00</updated>
      <summary>How many attempts have been made to remove Python&#x27;s Global Interpreter Lock (GIL)? How do they compare to the current approach? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.</summary>
      <content type="html">
        &lt;p&gt;How many attempts have been made to remove Python&#x27;s Global Interpreter Lock (GIL)? How do they compare to the current approach? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Python Game Development</title>
      <id>https://realpython.com/learning-paths/python-game-development/</id>
      <link href="https://realpython.com/learning-paths/python-game-development/"/>
      <updated>2026-04-16T12:00:00+00:00</updated>
      <summary>Build Python games from command-line projects to 2D graphical games with turtle, Tkinter, Pygame, and Arcade.</summary>
      <content type="html">
        &lt;p&gt;Build Python games from command-line projects to 2D graphical games with turtle, Tkinter, Pygame, and Arcade.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: LLM Application Development With Python</title>
      <id>https://realpython.com/learning-paths/llm-application-development-python/</id>
      <link href="https://realpython.com/learning-paths/llm-application-development-python/"/>
      <updated>2026-03-19T12:00:00+00:00</updated>
      <summary>Build LLM-powered applications in Python. Call model APIs, craft prompts, add retrieval-augmented generation, create AI agents, and connect via MCP.</summary>
      <content type="html">
        &lt;p&gt;Build LLM-powered applications in Python. Call model APIs, craft prompts, add retrieval-augmented generation, create AI agents, and connect via MCP.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Python Coding With AI</title>
      <id>https://realpython.com/learning-paths/coding-with-ai/</id>
      <link href="https://realpython.com/learning-paths/coding-with-ai/"/>
      <updated>2025-12-07T12:00:00+00:00</updated>
      <summary>Use AI coding assistants to write, review, and debug Python code faster. Choose an editor-based assistant like Cursor or a terminal-based one like Claude Code, then make it part of your daily workflow.</summary>
      <content type="html">
        &lt;p&gt;Use AI coding assistants to write, review, and debug Python code faster. Choose an editor-based assistant like Cursor or a terminal-based one like Claude Code, then make it part of your daily workflow.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Ace Your Python Coding Interview</title>
      <id>https://realpython.com/learning-paths/python-interview/</id>
      <link href="https://realpython.com/learning-paths/python-interview/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Prepare for Python coding interviews with practice problems, tips for standing out, and resources from top PyCon talks and Python books.</summary>
      <content type="html">
        &lt;p&gt;Prepare for Python coding interviews with practice problems, tips for standing out, and resources from top PyCon talks and Python books.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Create Graphical User Interfaces (GUI)</title>
      <id>https://realpython.com/learning-paths/python-gui-programming/</id>
      <link href="https://realpython.com/learning-paths/python-gui-programming/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Build Python GUI applications with Tkinter, PyQt, wxPython, and Kivy. Learn layouts, event handling, threading, and database integration.</summary>
      <content type="html">
        &lt;p&gt;Build Python GUI applications with Tkinter, PyQt, wxPython, and Kivy. Learn layouts, event handling, threading, and database integration.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Python Data Structures</title>
      <id>https://realpython.com/learning-paths/basic-python-data-structures/</id>
      <link href="https://realpython.com/learning-paths/basic-python-data-structures/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Learn Python&#x27;s built-in data structures: strings, lists, tuples, dictionaries, sets, and bytes, plus sorting, copying, and comprehensions.</summary>
      <content type="html">
        &lt;p&gt;Learn Python&#x27;s built-in data structures: strings, lists, tuples, dictionaries, sets, and bytes, plus sorting, copying, and comprehensions.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Testing and Continuous Integration</title>
      <id>https://realpython.com/learning-paths/test-your-python-apps/</id>
      <link href="https://realpython.com/learning-paths/test-your-python-apps/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Learn how to test Python code with unittest, doctest, pytest, and mock objects. Set up continuous integration with GitHub Actions and Docker.</summary>
      <content type="html">
        &lt;p&gt;Learn how to test Python code with unittest, doctest, pytest, and mock objects. Set up continuous integration with GitHub Actions and Docker.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Exceptions, Logging, and Debugging</title>
      <id>https://realpython.com/learning-paths/exception-handling-logging-debugging/</id>
      <link href="https://realpython.com/learning-paths/exception-handling-logging-debugging/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Learn Python exception handling, logging, and debugging. Work with raise, built-in exceptions, the logging module, and pdb to write reliable code.</summary>
      <content type="html">
        &lt;p&gt;Learn Python exception handling, logging, and debugging. Work with raise, built-in exceptions, the logging module, and pdb to write reliable code.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Important Standard Library Modules</title>
      <id>https://realpython.com/learning-paths/standard-library-modules-you-should-know/</id>
      <link href="https://realpython.com/learning-paths/standard-library-modules-you-should-know/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Explore Python standard library modules including math, datetime, JSON, CSV, regex, subprocess, and argparse through hands-on tutorials and courses.</summary>
      <content type="html">
        &lt;p&gt;Explore Python standard library modules including math, datetime, JSON, CSV, regex, subprocess, and argparse through hands-on tutorials and courses.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  

</feed>
