Warning, /frameworks/syndication/autotests/atom/bug411626.xml is written in an unsupported language. File is not indexed.

0001 <?xml version="1.0" encoding="utf-8"?>
0002 <feed xmlns="http://www.w3.org/2005/Atom">
0003 
0004   <title>Real Python</title>
0005   <link href="https://realpython.com/atom.xml" rel="self"/>
0006   <link href="https://realpython.com/"/>
0007   <updated>2019-09-04T14:00:00+00:00</updated>
0008   <id>https://realpython.com/</id>
0009   <author>
0010     <name>Real Python</name>
0011   </author>
0012 
0013   
0014     <entry>
0015       <title>Python args and kwargs: Demystified</title>
0016       <id>https://realpython.com/python-kwargs-and-args/</id>
0017       <link href="https://realpython.com/python-kwargs-and-args/"/>
0018       <updated>2019-09-04T14:00:00+00:00</updated>
0019       <summary>In this step-by-step tutorial, you&#39;ll learn how to use args and kwargs in Python to add more flexibility to your functions. You&#39;ll also take a closer look at the single and double-asterisk unpacking operators, which you can use to unpack any iterable object in Python.</summary>
0020       <content type="html">
0021         &lt;p&gt;Sometimes, when you look at a function definition in Python, you might see that it takes two strange arguments: &lt;strong&gt;&lt;code&gt;*args&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;**kwargs&lt;/code&gt;&lt;/strong&gt;. If you&amp;rsquo;ve ever wondered what these peculiar variables are, or why your IDE defines them in &lt;code&gt;main()&lt;/code&gt;, then this article is for you. You&amp;rsquo;ll learn how to use args and kwargs in Python to add more flexibility to your functions.&lt;/p&gt;
0022 &lt;p&gt;&lt;strong&gt;By the end of the article, you&amp;rsquo;ll know:&lt;/strong&gt;&lt;/p&gt;
0023 &lt;ul&gt;
0024 &lt;li&gt;What &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt; actually mean&lt;/li&gt;
0025 &lt;li&gt;How to use &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt; in function definitions&lt;/li&gt;
0026 &lt;li&gt;How to use a single asterisk (&lt;code&gt;*&lt;/code&gt;) to unpack iterables&lt;/li&gt;
0027 &lt;li&gt;How to use two asterisks (&lt;code&gt;**&lt;/code&gt;) to unpack dictionaries&lt;/li&gt;
0028 &lt;/ul&gt;
0029 &lt;p&gt;This article assumes that you already know how to define Python functions and work with &lt;a href=&quot;https://realpython.com/lessons/mutable-data-structures-lists-dictionaries/&quot;&gt;lists and dictionaries&lt;/a&gt;.&lt;/p&gt;
0030 &lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-cheat-sheet-shortened&quot; data-focus=&quot;false&quot;&gt;Click here to get a Python Cheat Sheet&lt;/a&gt; and learn the basics of Python 3, like working with data types, dictionaries, lists, and Python functions.&lt;/p&gt;&lt;/div&gt;
0031 
0032 &lt;h2 id=&quot;passing-multiple-arguments-to-a-function&quot;&gt;Passing Multiple Arguments to a Function&lt;/h2&gt;
0033 &lt;p&gt;&lt;strong&gt;&lt;code&gt;*args&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;**kwargs&lt;/code&gt;&lt;/strong&gt; allow you to pass multiple arguments or keyword arguments to a function. Consider the following example. This is a simple function that takes two arguments and returns their sum:&lt;/p&gt;
0034 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0035     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
0036 &lt;/pre&gt;&lt;/div&gt;
0037 
0038 &lt;p&gt;This function works fine, but it&amp;rsquo;s limited to only two arguments. What if you need to sum a varying number of arguments, where the specific number of arguments passed is only determined at runtime? Wouldn&amp;rsquo;t it be great to create a function that could sum &lt;em&gt;all&lt;/em&gt; the integers passed to it, no matter how many there are?&lt;/p&gt;
0039 &lt;h2 id=&quot;using-the-python-args-variable-in-function-definitions&quot;&gt;Using the Python args Variable in Function Definitions&lt;/h2&gt;
0040 &lt;p&gt;There are a few ways you can pass a varying number of arguments to a function. The first way is often the most intuitive for people that have experience with collections. You simply pass a list or a &lt;a href=&quot;https://realpython.com/python-sets/&quot;&gt;set&lt;/a&gt; of all the arguments to your function. So for &lt;code&gt;my_sum()&lt;/code&gt;, you could pass a list of all the integers you need to add:&lt;/p&gt;
0041 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# sum_integers_list.py&lt;/span&gt;
0042 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_integers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0043     &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
0044     &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_integers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0045         &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
0046     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
0047 
0048 &lt;span class=&quot;n&quot;&gt;list_of_integers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0049 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list_of_integers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
0050 &lt;/pre&gt;&lt;/div&gt;
0051 
0052 &lt;p&gt;This implementation works, but whenever you call this function you&amp;rsquo;ll also need to create a list of arguments to pass to it. This can be inconvenient, especially if you don&amp;rsquo;t know up front all the values that should go into the list.&lt;/p&gt;
0053 &lt;p&gt;This is where &lt;code&gt;*args&lt;/code&gt; can be really useful, because it allows you to pass a varying number of positional arguments. Take the following example:&lt;/p&gt;
0054 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# sum_integers_args.py&lt;/span&gt;
0055 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0056     &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
0057     &lt;span class=&quot;c1&quot;&gt;# Iterating over the Python args tuple&lt;/span&gt;
0058     &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0059         &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
0060     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
0061 
0062 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
0063 &lt;/pre&gt;&lt;/div&gt;
0064 
0065 &lt;p&gt;In this example, you&amp;rsquo;re no longer passing a list to &lt;code&gt;my_sum()&lt;/code&gt;. Instead, you&amp;rsquo;re passing three different positional arguments. &lt;code&gt;my_sum()&lt;/code&gt; takes all the parameters that are provided in the input and packs them all into a single iterable object named &lt;code&gt;args&lt;/code&gt;.&lt;/p&gt;
0066 &lt;p&gt;Note that &lt;strong&gt;&lt;code&gt;args&lt;/code&gt; is just a name.&lt;/strong&gt; You&amp;rsquo;re not required to use the name &lt;code&gt;args&lt;/code&gt;. You can choose any name that you prefer, such as &lt;code&gt;integers&lt;/code&gt;:&lt;/p&gt;
0067 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# sum_integers_args_2.py&lt;/span&gt;
0068 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;integers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0069     &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
0070     &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;integers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0071         &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
0072     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
0073 
0074 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
0075 &lt;/pre&gt;&lt;/div&gt;
0076 
0077 &lt;p&gt;The function still works, even if you pass the iterable object as &lt;code&gt;integers&lt;/code&gt; instead of &lt;code&gt;args&lt;/code&gt;. All that matters here is that you use the &lt;strong&gt;unpacking operator&lt;/strong&gt; (&lt;code&gt;*&lt;/code&gt;).&lt;/p&gt;
0078 &lt;p&gt;Bear in mind that the iterable object you&amp;rsquo;ll get using the unpacking operator &lt;code&gt;*&lt;/code&gt; is &lt;a href=&quot;https://realpython.com/python-lists-tuples/&quot;&gt;not a &lt;code&gt;list&lt;/code&gt; but a &lt;code&gt;tuple&lt;/code&gt;&lt;/a&gt;. A &lt;code&gt;tuple&lt;/code&gt; is similar to a &lt;code&gt;list&lt;/code&gt; in that they both support slicing and iteration. However, tuples are very different in at least one aspect: lists are &lt;a href=&quot;https://realpython.com/courses/immutability-python/&quot;&gt;mutable&lt;/a&gt;, while tuples are not. To test this, run the following code. This script tries to change a value of a list:&lt;/p&gt;
0079 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# change_list.py&lt;/span&gt;
0080 &lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0081 &lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
0082 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0083 &lt;/pre&gt;&lt;/div&gt;
0084 
0085 &lt;p&gt;The value located at the very first index of the list should be updated to &lt;code&gt;9&lt;/code&gt;. If you execute this script, you will see that the list indeed gets modified:&lt;/p&gt;
0086 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python change_list.py
0087 &lt;span class=&quot;go&quot;&gt;[9, 2, 3]&lt;/span&gt;
0088 &lt;/pre&gt;&lt;/div&gt;
0089 
0090 &lt;p&gt;The first value is no longer &lt;code&gt;0&lt;/code&gt;, but the updated value &lt;code&gt;9&lt;/code&gt;. Now, try to do the same with a tuple:&lt;/p&gt;
0091 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# change_tuple.py&lt;/span&gt;
0092 &lt;span class=&quot;n&quot;&gt;my_tuple&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0093 &lt;span class=&quot;n&quot;&gt;my_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
0094 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0095 &lt;/pre&gt;&lt;/div&gt;
0096 
0097 &lt;p&gt;Here, you see the same values, except they&amp;rsquo;re held together as a tuple. If you try to execute this script, you will see that the Python interpreter returns an &lt;a href=&quot;https://realpython.com/python-exceptions/&quot;&gt;error&lt;/a&gt;:&lt;/p&gt;
0098 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python change_tuple.py
0099 &lt;span class=&quot;go&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
0100 &lt;span class=&quot;go&quot;&gt;  File &amp;quot;change_tuple.py&amp;quot;, line 3, in &amp;lt;module&amp;gt;&lt;/span&gt;
0101 &lt;span class=&quot;go&quot;&gt;    my_tuple[0] = 9&lt;/span&gt;
0102 &lt;span class=&quot;go&quot;&gt;TypeError: &amp;#39;tuple&amp;#39; object does not support item assignment&lt;/span&gt;
0103 &lt;/pre&gt;&lt;/div&gt;
0104 
0105 &lt;p&gt;This is because a tuple is an immutable object, and its values cannot be changed after assignment. Keep this in mind when you&amp;rsquo;re working with tuples and &lt;code&gt;*args&lt;/code&gt;.&lt;/p&gt;
0106 &lt;h2 id=&quot;using-the-python-kwargs-variable-in-function-definitions&quot;&gt;Using the Python kwargs Variable in Function Definitions&lt;/h2&gt;
0107 &lt;p&gt;Okay, now you&amp;rsquo;ve understood what &lt;code&gt;*args&lt;/code&gt; is for, but what about &lt;code&gt;**kwargs&lt;/code&gt;? &lt;code&gt;**kwargs&lt;/code&gt; works just like &lt;code&gt;*args&lt;/code&gt;, but instead of accepting positional arguments it accepts keyword (or &lt;strong&gt;named&lt;/strong&gt;) arguments. Take the following example:&lt;/p&gt;
0108 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# concatenate.py&lt;/span&gt;
0109 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;concatenate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0110     &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
0111     &lt;span class=&quot;c1&quot;&gt;# Iterating over the Python kwargs dictionary&lt;/span&gt;
0112     &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
0113         &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;
0114     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
0115 
0116 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;concatenate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Real&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Python&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Is&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Great&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
0117 &lt;/pre&gt;&lt;/div&gt;
0118 
0119 &lt;p&gt;When you execute the script above, &lt;code&gt;concatenate()&lt;/code&gt; will iterate through the Python kwargs &lt;a href=&quot;https://realpython.com/python-dicts/&quot;&gt;dictionary&lt;/a&gt; and concatenate all the values it finds:&lt;/p&gt;
0120 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python concatenate.py
0121 &lt;span class=&quot;go&quot;&gt;RealPythonIsGreat!&lt;/span&gt;
0122 &lt;/pre&gt;&lt;/div&gt;
0123 
0124 &lt;p&gt;Like &lt;code&gt;args&lt;/code&gt;, &lt;code&gt;kwargs&lt;/code&gt; is just a name that can be changed to whatever you want. Again, what is important here is the use of the &lt;strong&gt;unpacking operator&lt;/strong&gt; (&lt;code&gt;**&lt;/code&gt;).&lt;/p&gt;
0125 &lt;p&gt;So, the previous example could be written like this:&lt;/p&gt;
0126 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# concatenate_2.py&lt;/span&gt;
0127 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;concatenate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0128     &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
0129     &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
0130         &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;
0131     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
0132 
0133 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;concatenate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Real&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Python&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Is&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Great&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
0134 &lt;/pre&gt;&lt;/div&gt;
0135 
0136 &lt;p&gt;Note that in the example above the iterable object is a standard &lt;code&gt;dict&lt;/code&gt;. If you &lt;a href=&quot;https://realpython.com/iterate-through-dictionary-python/&quot;&gt;iterate over the dictionary&lt;/a&gt; and want to return its values, like in the example shown, then you must use &lt;code&gt;.values()&lt;/code&gt;.&lt;/p&gt;
0137 &lt;p&gt;In fact, if you forget to use this method, you will find yourself iterating through the &lt;strong&gt;keys&lt;/strong&gt; of your Python kwargs dictionary instead, like in the following example:&lt;/p&gt;
0138 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# concatenate_keys.py&lt;/span&gt;
0139 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;concatenate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0140     &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
0141     &lt;span class=&quot;c1&quot;&gt;# Iterating over the keys of the Python kwargs dictionary&lt;/span&gt;
0142     &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0143         &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;
0144     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
0145 
0146 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;concatenate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Real&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Python&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Is&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Great&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
0147 &lt;/pre&gt;&lt;/div&gt;
0148 
0149 &lt;p&gt;Now, if you try to execute this example, you&amp;rsquo;ll notice the following output:&lt;/p&gt;
0150 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python concatenate_keys.py
0151 &lt;span class=&quot;go&quot;&gt;abcde&lt;/span&gt;
0152 &lt;/pre&gt;&lt;/div&gt;
0153 
0154 &lt;p&gt;As you can see, if you don&amp;rsquo;t specify &lt;code&gt;.values()&lt;/code&gt;, your function will iterate over the keys of your Python kwargs dictionary, returning the wrong result.&lt;/p&gt;
0155 &lt;h2 id=&quot;ordering-arguments-in-a-function&quot;&gt;Ordering Arguments in a Function&lt;/h2&gt;
0156 &lt;p&gt;Now that you have learned what &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt; are for, you are ready to start writing functions that take a varying number of input arguments. But what if you want to create a function that takes a changeable number of both positional &lt;em&gt;and&lt;/em&gt; named arguments?&lt;/p&gt;
0157 &lt;p&gt;In this case, you have to bear in mind that &lt;strong&gt;order counts&lt;/strong&gt;. Just as non-default arguments have to precede default arguments, so &lt;code&gt;*args&lt;/code&gt; must come before &lt;code&gt;**kwargs&lt;/code&gt;.&lt;/p&gt;
0158 &lt;p&gt;To recap, the correct order for your parameters is:&lt;/p&gt;
0159 &lt;ol&gt;
0160 &lt;li&gt;Standard arguments&lt;/li&gt;
0161 &lt;li&gt;&lt;code&gt;*args&lt;/code&gt; arguments&lt;/li&gt;
0162 &lt;li&gt;&lt;code&gt;**kwargs&lt;/code&gt; arguments&lt;/li&gt;
0163 &lt;/ol&gt;
0164 &lt;p&gt;For example, this function definition is correct:&lt;/p&gt;
0165 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# correct_function_definition.py&lt;/span&gt;
0166 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0167     &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
0168 &lt;/pre&gt;&lt;/div&gt;
0169 
0170 &lt;p&gt;The &lt;code&gt;*args&lt;/code&gt; variable is appropriately listed before &lt;code&gt;**kwargs&lt;/code&gt;. But what if you try to modify the order of the arguments? For example, consider the following function:&lt;/p&gt;
0171 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# wrong_function_definition.py&lt;/span&gt;
0172 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0173     &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
0174 &lt;/pre&gt;&lt;/div&gt;
0175 
0176 &lt;p&gt;Now, &lt;code&gt;**kwargs&lt;/code&gt; comes before &lt;code&gt;*args&lt;/code&gt; in the function definition. If you try to run this example, you&amp;rsquo;ll receive an error from the interpreter:&lt;/p&gt;
0177 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python wrong_function_definition.py
0178 &lt;span class=&quot;go&quot;&gt;  File &amp;quot;wrong_function_definition.py&amp;quot;, line 2&lt;/span&gt;
0179 &lt;span class=&quot;go&quot;&gt;    def my_function(a, b, **kwargs, *args):&lt;/span&gt;
0180 &lt;span class=&quot;go&quot;&gt;                                    ^&lt;/span&gt;
0181 &lt;span class=&quot;go&quot;&gt;SyntaxError: invalid syntax&lt;/span&gt;
0182 &lt;/pre&gt;&lt;/div&gt;
0183 
0184 &lt;p&gt;In this case, since &lt;code&gt;*args&lt;/code&gt; comes after &lt;code&gt;**kwargs&lt;/code&gt;, the Python interpreter throws a &lt;code&gt;SyntaxError&lt;/code&gt;.&lt;/p&gt;
0185 &lt;h2 id=&quot;unpacking-with-the-asterisk-operators&quot;&gt;Unpacking With the Asterisk Operators: &lt;code&gt;*&lt;/code&gt; &amp;amp; &lt;code&gt;**&lt;/code&gt;&lt;/h2&gt;
0186 &lt;p&gt;You are now able to use &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt; to define Python functions that take a varying number of input arguments. Let&amp;rsquo;s go a little deeper to understand something more about the &lt;strong&gt;unpacking operators&lt;/strong&gt;.&lt;/p&gt;
0187 &lt;p&gt;The single and double asterisk unpacking operators were introduced in Python 2. As of the 3.5 release, they have become even more powerful, thanks to &lt;a href=&quot;https://www.python.org/dev/peps/pep-0448/&quot;&gt;PEP 448&lt;/a&gt;. In short, the unpacking operators are operators that unpack the values from iterable objects in Python. The single asterisk operator &lt;code&gt;*&lt;/code&gt; can be used on any iterable that Python provides, while the double asterisk operator &lt;code&gt;**&lt;/code&gt; can only be used on dictionaries.&lt;/p&gt;
0188 &lt;p&gt;Let&amp;rsquo;s start with an example:&lt;/p&gt;
0189 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# print_list.py&lt;/span&gt;
0190 &lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0191 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0192 &lt;/pre&gt;&lt;/div&gt;
0193 
0194 &lt;p&gt;This code defines a list and then prints it to the standard output:&lt;/p&gt;
0195 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python print_list.py
0196 &lt;span class=&quot;go&quot;&gt;[1, 2, 3]&lt;/span&gt;
0197 &lt;/pre&gt;&lt;/div&gt;
0198 
0199 &lt;p&gt;Note how the list is printed, along with the corresponding brackets and commas.&lt;/p&gt;
0200 &lt;p&gt;Now, try to prepend the unpacking operator &lt;code&gt;*&lt;/code&gt; to the name of your list:&lt;/p&gt;
0201 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# print_unpacked_list.py&lt;/span&gt;
0202 &lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0203 &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;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0204 &lt;/pre&gt;&lt;/div&gt;
0205 
0206 &lt;p&gt;Here, the &lt;code&gt;*&lt;/code&gt; operator tells &lt;code&gt;print()&lt;/code&gt; to unpack the list first.&lt;/p&gt;
0207 &lt;p&gt;In this case, the output is no longer the list itself, but rather &lt;em&gt;the content&lt;/em&gt; of the list:&lt;/p&gt;
0208 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python print_unpacked_list.py
0209 &lt;span class=&quot;go&quot;&gt;1 2 3&lt;/span&gt;
0210 &lt;/pre&gt;&lt;/div&gt;
0211 
0212 &lt;p&gt;Can you see the difference between this execution and the one from &lt;code&gt;print_list.py&lt;/code&gt;? Instead of a list, &lt;code&gt;print()&lt;/code&gt; has taken three separate arguments as the input.&lt;/p&gt;
0213 &lt;p&gt;Another thing you&amp;rsquo;ll notice is that in &lt;code&gt;print_unpacked_list.py&lt;/code&gt;, you used the unpacking operator &lt;code&gt;*&lt;/code&gt; to call a function, instead of in a function definition. In this case, &lt;code&gt;print()&lt;/code&gt; takes all the items of a list as though they were single arguments.&lt;/p&gt;
0214 &lt;p&gt;You can also use this method to call your own functions, but if your function requires a specific number of arguments, then the iterable you unpack must have the same number of arguments.&lt;/p&gt;
0215 &lt;p&gt;To test this behavior, consider this script:&lt;/p&gt;
0216 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# unpacking_call.py&lt;/span&gt;
0217 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0218     &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0219 
0220 &lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0221 &lt;span class=&quot;n&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0222 &lt;/pre&gt;&lt;/div&gt;
0223 
0224 &lt;p&gt;Here, &lt;code&gt;my_sum()&lt;/code&gt; explicitly states that &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, and &lt;code&gt;c&lt;/code&gt; are required arguments.&lt;/p&gt;
0225 &lt;p&gt;If you run this script, you&amp;rsquo;ll get the sum of the three numbers in &lt;code&gt;my_list&lt;/code&gt;:&lt;/p&gt;
0226 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python unpacking_call.py
0227 &lt;span class=&quot;go&quot;&gt;6&lt;/span&gt;
0228 &lt;/pre&gt;&lt;/div&gt;
0229 
0230 &lt;p&gt;The 3 elements in &lt;code&gt;my_list&lt;/code&gt; match up perfectly with the required arguments in &lt;code&gt;my_sum()&lt;/code&gt;.&lt;/p&gt;
0231 &lt;p&gt;Now look at the following script, where &lt;code&gt;my_list&lt;/code&gt; has 4 arguments instead of 3:&lt;/p&gt;
0232 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# wrong_unpacking_call.py&lt;/span&gt;
0233 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0234     &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0235 
0236 &lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0237 &lt;span class=&quot;n&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0238 &lt;/pre&gt;&lt;/div&gt;
0239 
0240 &lt;p&gt;In this example, &lt;code&gt;my_sum()&lt;/code&gt; still expects just three arguments, but the &lt;code&gt;*&lt;/code&gt; operator gets 4 items from the list. If you try to execute this script, you&amp;rsquo;ll see that the Python interpreter is unable to run it:&lt;/p&gt;
0241 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python wrong_unpacking_call.py
0242 &lt;span class=&quot;go&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
0243 &lt;span class=&quot;go&quot;&gt;  File &amp;quot;wrong_unpacking_call.py&amp;quot;, line 6, in &amp;lt;module&amp;gt;&lt;/span&gt;
0244 &lt;span class=&quot;go&quot;&gt;    my_sum(*my_list)&lt;/span&gt;
0245 &lt;span class=&quot;go&quot;&gt;TypeError: my_sum() takes 3 positional arguments but 4 were given&lt;/span&gt;
0246 &lt;/pre&gt;&lt;/div&gt;
0247 
0248 &lt;p&gt;When you use the &lt;code&gt;*&lt;/code&gt; operator to unpack a list and pass arguments to a function, it&amp;rsquo;s exactly as though you&amp;rsquo;re passing every single argument alone. This means that you can use multiple unpacking operators to get values from several lists and pass them all to a single function.&lt;/p&gt;
0249 &lt;p&gt;To test this behavior, consider the following example:&lt;/p&gt;
0250 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# sum_integers_args_3.py&lt;/span&gt;
0251 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0252     &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
0253     &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0254         &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
0255     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
0256 
0257 &lt;span class=&quot;n&quot;&gt;list1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0258 &lt;span class=&quot;n&quot;&gt;list2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0259 &lt;span class=&quot;n&quot;&gt;list3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0260 
0261 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
0262 &lt;/pre&gt;&lt;/div&gt;
0263 
0264 &lt;p&gt;If you run this example, all three lists are unpacked. Each individual item is passed to &lt;code&gt;my_sum()&lt;/code&gt;, resulting in the following output:&lt;/p&gt;
0265 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python sum_integers_args_3.py
0266 &lt;span class=&quot;go&quot;&gt;45&lt;/span&gt;
0267 &lt;/pre&gt;&lt;/div&gt;
0268 
0269 &lt;p&gt;There are other convenient uses of the unpacking operator. For example, say you need to split a list into three different parts. The output should show the first value, the last value, and all the values in between. With the unpacking operator, you can do this in just one line of code:&lt;/p&gt;
0270 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# extract_list_body.py&lt;/span&gt;
0271 &lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0272 
0273 &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_list&lt;/span&gt;
0274 
0275 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0276 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0277 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0278 &lt;/pre&gt;&lt;/div&gt;
0279 
0280 &lt;p&gt;In this example, &lt;code&gt;my_list&lt;/code&gt; contains 6 items. The first variable is assigned to &lt;code&gt;a&lt;/code&gt;, the last to &lt;code&gt;c&lt;/code&gt;, and all other values are packed into a new list &lt;code&gt;b&lt;/code&gt;. If you run the &lt;a href=&quot;https://realpython.com/run-python-scripts/&quot;&gt;script&lt;/a&gt;, &lt;code&gt;print()&lt;/code&gt; will show you that your three variables have the values you would expect:&lt;/p&gt;
0281 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python extract_list_body.py
0282 &lt;span class=&quot;go&quot;&gt;1&lt;/span&gt;
0283 &lt;span class=&quot;go&quot;&gt;[2, 3, 4, 5]&lt;/span&gt;
0284 &lt;span class=&quot;go&quot;&gt;6&lt;/span&gt;
0285 &lt;/pre&gt;&lt;/div&gt;
0286 
0287 &lt;p&gt;Another interesting thing you can do with the unpacking operator &lt;code&gt;*&lt;/code&gt; is to split the items of any iterable object. This could be very useful if you need to merge two lists, for instance:&lt;/p&gt;
0288 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# merging_lists.py&lt;/span&gt;
0289 &lt;span class=&quot;n&quot;&gt;my_first_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0290 &lt;span class=&quot;n&quot;&gt;my_second_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0291 &lt;span class=&quot;n&quot;&gt;my_merged_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_first_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_second_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0292 
0293 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_merged_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0294 &lt;/pre&gt;&lt;/div&gt;
0295 
0296 &lt;p&gt;The unpacking operator &lt;code&gt;*&lt;/code&gt; is prepended to both &lt;code&gt;my_first_list&lt;/code&gt; and &lt;code&gt;my_second_list&lt;/code&gt;.&lt;/p&gt;
0297 &lt;p&gt;If you run this script, you&amp;rsquo;ll see that the result is a merged list:&lt;/p&gt;
0298 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python merging_lists.py
0299 &lt;span class=&quot;go&quot;&gt;[1, 2, 3, 4, 5, 6]&lt;/span&gt;
0300 &lt;/pre&gt;&lt;/div&gt;
0301 
0302 &lt;p&gt;You can even merge two different dictionaries by using the unpacking operator &lt;code&gt;**&lt;/code&gt;:&lt;/p&gt;
0303 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# merging_dicts.py&lt;/span&gt;
0304 &lt;span class=&quot;n&quot;&gt;my_first_dict&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
0305 &lt;span class=&quot;n&quot;&gt;my_second_dict&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;C&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;D&amp;quot;&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;
0306 &lt;span class=&quot;n&quot;&gt;my_merged_dict&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_first_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_second_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
0307 
0308 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_merged_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0309 &lt;/pre&gt;&lt;/div&gt;
0310 
0311 &lt;p&gt;Here, the iterables to merge are &lt;code&gt;my_first_dict&lt;/code&gt; and &lt;code&gt;my_second_dict&lt;/code&gt;.&lt;/p&gt;
0312 &lt;p&gt;Executing this code outputs a merged dictionary:&lt;/p&gt;
0313 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python merging_dicts.py
0314 &lt;span class=&quot;go&quot;&gt;{&amp;#39;A&amp;#39;: 1, &amp;#39;B&amp;#39;: 2, &amp;#39;C&amp;#39;: 3, &amp;#39;D&amp;#39;: 4}&lt;/span&gt;
0315 &lt;/pre&gt;&lt;/div&gt;
0316 
0317 &lt;p&gt;Remember that the &lt;code&gt;*&lt;/code&gt; operator works on &lt;em&gt;any&lt;/em&gt; iterable object. It can also be used to unpack a &lt;a href=&quot;https://realpython.com/python-strings/&quot;&gt;string&lt;/a&gt;:&lt;/p&gt;
0318 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# string_to_list.py&lt;/span&gt;
0319 &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;RealPython&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0320 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0321 &lt;/pre&gt;&lt;/div&gt;
0322 
0323 &lt;p&gt;In Python, strings are iterable objects, so &lt;code&gt;*&lt;/code&gt; will unpack it and place all individual values in a list &lt;code&gt;a&lt;/code&gt;:&lt;/p&gt;
0324 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python string_to_list.py
0325 &lt;span class=&quot;go&quot;&gt;[&amp;#39;R&amp;#39;, &amp;#39;e&amp;#39;, &amp;#39;a&amp;#39;, &amp;#39;l&amp;#39;, &amp;#39;P&amp;#39;, &amp;#39;y&amp;#39;, &amp;#39;t&amp;#39;, &amp;#39;h&amp;#39;, &amp;#39;o&amp;#39;, &amp;#39;n&amp;#39;]&lt;/span&gt;
0326 &lt;/pre&gt;&lt;/div&gt;
0327 
0328 &lt;p&gt;The previous example seems great, but when you work with these operators it&amp;rsquo;s important to keep in mind the seventh rule of &lt;a href=&quot;https://www.python.org/dev/peps/pep-0020/&quot;&gt;&lt;em&gt;The Zen of Python&lt;/em&gt;&lt;/a&gt; by Tim Peters: &lt;em&gt;Readability counts&lt;/em&gt;.&lt;/p&gt;
0329 &lt;p&gt;To see why, consider the following example:&lt;/p&gt;
0330 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# mysterious_statement.py&lt;/span&gt;
0331 &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;RealPython&amp;quot;&lt;/span&gt;
0332 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0333 &lt;/pre&gt;&lt;/div&gt;
0334 
0335 &lt;p&gt;There&amp;rsquo;s the unpacking operator &lt;code&gt;*&lt;/code&gt;, followed by a variable, a comma, and an assignment. That&amp;rsquo;s a lot packed into one line! In fact, this code is no different from the previous example. It just takes the string &lt;code&gt;RealPython&lt;/code&gt; and assigns all the items to the new list &lt;code&gt;a&lt;/code&gt;, thanks to the unpacking operator &lt;code&gt;*&lt;/code&gt;.&lt;/p&gt;
0336 &lt;p&gt;The comma after the &lt;code&gt;a&lt;/code&gt; does the trick. When you use the unpacking operator with variable assignment, Python requires that your resulting variable is either a list or a tuple. With the trailing comma, you have actually defined a tuple with just one named variable &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;
0337 &lt;p&gt;While this is a neat trick, many Pythonistas would not consider this code to be very readable. As such, it&amp;rsquo;s best to use these kinds of constructions sparingly.&lt;/p&gt;
0338 &lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
0339 &lt;p&gt;You are now able to use &lt;strong&gt;&lt;code&gt;*args&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;**kwargs&lt;/code&gt;&lt;/strong&gt; to accept a changeable number of arguments in your functions. You have also learned something more about the unpacking operators. &lt;/p&gt;
0340 &lt;p&gt;You&amp;rsquo;ve learned:&lt;/p&gt;
0341 &lt;ul&gt;
0342 &lt;li&gt;What &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt; actually mean&lt;/li&gt;
0343 &lt;li&gt;How to use &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt; in function definitions&lt;/li&gt;
0344 &lt;li&gt;How to use a single asterisk (&lt;code&gt;*&lt;/code&gt;) to unpack iterables&lt;/li&gt;
0345 &lt;li&gt;How to use two asterisks (&lt;code&gt;**&lt;/code&gt;) to unpack dictionaries&lt;/li&gt;
0346 &lt;/ul&gt;
0347 &lt;p&gt;If you still have questions, don&amp;rsquo;t hesitate to reach out in the comments section below! To learn more about the use of the asterisks in Python, have a look at &lt;a href=&quot;https://treyhunner.com/2018/10/asterisks-in-python-what-they-are-and-how-to-use-them/&quot;&gt;Trey Hunner&amp;rsquo;s article on the subject&lt;/a&gt;.&lt;/p&gt;
0348         &lt;hr /&gt;
0349         &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;
0350       </content>
0351     </entry>
0352   
0353     <entry>
0354       <title>Lists and Tuples in Python</title>
0355       <id>https://realpython.com/courses/lists-tuples-python/</id>
0356       <link href="https://realpython.com/courses/lists-tuples-python/"/>
0357       <updated>2019-09-03T14:00:00+00:00</updated>
0358       <summary>In this course, you&#39;ll cover the important characteristics of lists and tuples in Python 3. You&#39;ll learn how to define them and how to manipulate them. When you&#39;re finished, you&#39;ll have a good feel for when and how to use these object types in a Python program.</summary>
0359       <content type="html">
0360         &lt;p&gt;In this course, you&amp;rsquo;ll learn about working with lists and tuples. &lt;strong&gt;Lists&lt;/strong&gt; and &lt;strong&gt;tuples&lt;/strong&gt; are arguably Python&amp;rsquo;s most versatile, useful &lt;a href=&quot;https://realpython.com/python-data-types/&quot;&gt;data types&lt;/a&gt;. You&amp;rsquo;ll find them in virtually every non-trivial Python program.&lt;/p&gt;
0361 &lt;p&gt;&lt;strong&gt;Here&amp;rsquo;s what you&amp;rsquo;ll learn in this tutorial:&lt;/strong&gt; You&amp;rsquo;ll cover the important characteristics of lists and tuples. You&amp;rsquo;ll learn how to define them and how to manipulate them.  When you&amp;rsquo;re finished, you&amp;rsquo;ll have a good feel for when and how to use these object types in a Python program.&lt;/p&gt;
0362 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
0363 &lt;p&gt;&lt;strong&gt;&lt;i class=&quot;fa fa-graduation-cap&quot; aria-hidden=&quot;true&quot;&gt;&lt;/i&gt; Take the Quiz:&lt;/strong&gt; Test your knowledge with our interactive “Python Lists and Tuples” quiz. Upon completion you will receive a score so you can track your learning progress over time:&lt;/p&gt;&lt;p class=&quot;text-center my-2&quot;&gt;&lt;a class=&quot;btn btn-primary&quot; href=&quot;/quizzes/python-lists-tuples/&quot; target=&quot;_blank&quot;&gt;Take the Quiz »&lt;/a&gt;&lt;/p&gt;
0364 &lt;/div&gt;
0365         &lt;hr /&gt;
0366         &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;
0367       </content>
0368     </entry>
0369   
0370     <entry>
0371       <title>Natural Language Processing With spaCy in Python</title>
0372       <id>https://realpython.com/natural-language-processing-spacy-python/</id>
0373       <link href="https://realpython.com/natural-language-processing-spacy-python/"/>
0374       <updated>2019-09-02T14:00:00+00:00</updated>
0375       <summary>In this step-by-step tutorial, you&#39;ll learn how to use spaCy. This free and open-source library for Natural Language Processing (NLP) in Python has a lot of built-in capabilities and is becoming increasingly popular for processing and analyzing data in NLP.</summary>
0376       <content type="html">
0377         &lt;p&gt;&lt;strong&gt;spaCy&lt;/strong&gt; is a free and open-source library for &lt;strong&gt;Natural Language Processing&lt;/strong&gt; (NLP) in Python with a lot of in-built capabilities. It&amp;rsquo;s becoming increasingly popular for processing and analyzing data in NLP. Unstructured textual data is produced at a large scale, and it&amp;rsquo;s important to process and derive insights from unstructured data. To do that, you need to represent the data in a format that can be understood by computers. NLP can help you do that.&lt;/p&gt;
0378 &lt;p&gt;&lt;strong&gt;In this tutorial, you&amp;rsquo;ll learn:&lt;/strong&gt;&lt;/p&gt;
0379 &lt;ul&gt;
0380 &lt;li&gt;What the foundational terms and concepts in NLP are&lt;/li&gt;
0381 &lt;li&gt;How to implement those concepts in spaCy&lt;/li&gt;
0382 &lt;li&gt;How to customize and extend built-in functionalities in spaCy&lt;/li&gt;
0383 &lt;li&gt;How to perform basic statistical analysis on a text&lt;/li&gt;
0384 &lt;li&gt;How to create a pipeline to process unstructured text&lt;/li&gt;
0385 &lt;li&gt;How to parse a sentence and extract meaningful insights from it&lt;/li&gt;
0386 &lt;/ul&gt;
0387 &lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-tricks-sample&quot; data-focus=&quot;false&quot;&gt;Click here to get access to a chapter from Python Tricks: The Book&lt;/a&gt; that shows you Python&#39;s best practices with simple examples you can apply instantly to write more beautiful + Pythonic code.&lt;/p&gt;&lt;/div&gt;
0388 
0389 &lt;h2 id=&quot;what-are-nlp-and-spacy&quot;&gt;What Are NLP and spaCy?&lt;/h2&gt;
0390 &lt;p&gt;&lt;strong&gt;NLP&lt;/strong&gt; is a subfield of &lt;strong&gt;Artificial Intelligence&lt;/strong&gt; and is concerned with interactions between computers and human languages. NLP is the process of analyzing, understanding, and deriving meaning from human languages for computers.&lt;/p&gt;
0391 &lt;p&gt;NLP helps you extract insights from unstructured text and has several use cases, such as:&lt;/p&gt;
0392 &lt;ul&gt;
0393 &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Automatic_summarization&quot;&gt;Automatic summarization&lt;/a&gt;&lt;/li&gt;
0394 &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Named-entity_recognition&quot;&gt;Named entity recognition&lt;/a&gt;&lt;/li&gt;
0395 &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Question_answering&quot;&gt;Question answering systems&lt;/a&gt;&lt;/li&gt;
0396 &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Sentiment_analysis&quot;&gt;Sentiment analysis&lt;/a&gt;&lt;/li&gt;
0397 &lt;/ul&gt;
0398 &lt;p&gt;spaCy is a free, open-source library for NLP in Python. It&amp;rsquo;s written in &lt;a href=&quot;https://cython.org/&quot;&gt;Cython&lt;/a&gt; and is designed to build information extraction or natural language understanding systems. It&amp;rsquo;s built for production use and provides a concise and user-friendly API.&lt;/p&gt;
0399 &lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;
0400 &lt;p&gt;In this section, you&amp;rsquo;ll install spaCy and then download data and models for the English language.&lt;/p&gt;
0401 &lt;h3 id=&quot;how-to-install-spacy&quot;&gt;How to Install spaCy&lt;/h3&gt;
0402 &lt;p&gt;spaCy can be installed using &lt;strong&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/strong&gt;, a Python package manager. You can use a &lt;strong&gt;virtual environment&lt;/strong&gt; to avoid depending on system-wide packages. To learn more about virtual environments and &lt;code&gt;pip&lt;/code&gt;, check out &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;What Is Pip? A Guide for New Pythonistas&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;Python Virtual Environments: A Primer&lt;/a&gt;.&lt;/p&gt;
0403 &lt;p&gt;Create a new virtual environment:&lt;/p&gt;
0404 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3 -m venv env
0405 &lt;/pre&gt;&lt;/div&gt;
0406 
0407 &lt;p&gt;Activate this virtual environment and install spaCy:&lt;/p&gt;
0408 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; ./env/bin/activate
0409 &lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; pip install spacy
0410 &lt;/pre&gt;&lt;/div&gt;
0411 
0412 &lt;h3 id=&quot;how-to-download-models-and-data&quot;&gt;How to Download Models and Data&lt;/h3&gt;
0413 &lt;p&gt;spaCy has &lt;a href=&quot;https://spaCy.io/models&quot;&gt;different types&lt;/a&gt; of models. The default model for the English language is &lt;code&gt;en_core_web_sm&lt;/code&gt;.&lt;/p&gt;
0414 &lt;p&gt;Activate the virtual environment created in the previous step and download models and data for the English language:&lt;/p&gt;
0415 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python -m spacy download en_core_web_sm
0416 &lt;/pre&gt;&lt;/div&gt;
0417 
0418 &lt;p&gt;Verify if the download was successful or not by loading it:&lt;/p&gt;
0419 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;spacy&lt;/span&gt;
0420 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;en_core_web_sm&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0421 &lt;/pre&gt;&lt;/div&gt;
0422 
0423 &lt;p&gt;If the &lt;code&gt;nlp&lt;/code&gt; object is created, then it means that spaCy was installed and that models and data were successfully downloaded.&lt;/p&gt;
0424 &lt;h2 id=&quot;using-spacy&quot;&gt;Using spaCy&lt;/h2&gt;
0425 &lt;p&gt;In this section, you&amp;rsquo;ll use spaCy for a given input string and a text file. Load the language model instance in spaCy:&lt;/p&gt;
0426 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;spacy&lt;/span&gt;
0427 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;en_core_web_sm&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0428 &lt;/pre&gt;&lt;/div&gt;
0429 
0430 &lt;p&gt;Here, the &lt;code&gt;nlp&lt;/code&gt; object is a language model instance. You can assume that, throughout this tutorial, &lt;code&gt;nlp&lt;/code&gt; refers to the language model loaded by &lt;code&gt;en_core_web_sm&lt;/code&gt;. Now you can use spaCy to read a string or a text file.&lt;/p&gt;
0431 &lt;h3 id=&quot;how-to-read-a-string&quot;&gt;How to Read a String&lt;/h3&gt;
0432 &lt;p&gt;You can use spaCy to create a processed &lt;a href=&quot;https://spaCy.io/api/doc&quot;&gt;Doc&lt;/a&gt; object, which is a container for accessing linguistic annotations, for a given input string:&lt;/p&gt;
0433 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;introduction_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;This tutorial is about Natural&amp;#39;&lt;/span&gt;
0434 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; Language Processing in Spacy.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0435 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;introduction_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;introduction_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0436 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Extract tokens for the given doc&lt;/span&gt;
0437 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;introduction_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
0438 &lt;span class=&quot;go&quot;&gt;[&amp;#39;This&amp;#39;, &amp;#39;tutorial&amp;#39;, &amp;#39;is&amp;#39;, &amp;#39;about&amp;#39;, &amp;#39;Natural&amp;#39;, &amp;#39;Language&amp;#39;,&lt;/span&gt;
0439 &lt;span class=&quot;go&quot;&gt;&amp;#39;Processing&amp;#39;, &amp;#39;in&amp;#39;, &amp;#39;Spacy&amp;#39;, &amp;#39;.&amp;#39;]&lt;/span&gt;
0440 &lt;/pre&gt;&lt;/div&gt;
0441 
0442 &lt;p&gt;In the above example, notice how the text is converted to an object that is understood by spaCy. You can use this method to convert any text into a processed &lt;code&gt;Doc&lt;/code&gt; object and deduce attributes, which will be covered in the coming sections.&lt;/p&gt;
0443 &lt;h3 id=&quot;how-to-read-a-text-file&quot;&gt;How to Read a Text File&lt;/h3&gt;
0444 &lt;p&gt;In this section, you&amp;rsquo;ll create a processed &lt;a href=&quot;https://spaCy.io/api/doc&quot;&gt;Doc&lt;/a&gt; object for a text file:&lt;/p&gt;
0445 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;introduction.txt&amp;#39;&lt;/span&gt;
0446 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;introduction_file_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
0447 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;introduction_file_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;introduction_file_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0448 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Extract tokens for the given doc&lt;/span&gt;
0449 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;introduction_file_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
0450 &lt;span class=&quot;go&quot;&gt;[&amp;#39;This&amp;#39;, &amp;#39;tutorial&amp;#39;, &amp;#39;is&amp;#39;, &amp;#39;about&amp;#39;, &amp;#39;Natural&amp;#39;, &amp;#39;Language&amp;#39;,&lt;/span&gt;
0451 &lt;span class=&quot;go&quot;&gt;&amp;#39;Processing&amp;#39;, &amp;#39;in&amp;#39;, &amp;#39;Spacy&amp;#39;, &amp;#39;.&amp;#39;, &amp;#39;\n&amp;#39;]&lt;/span&gt;
0452 &lt;/pre&gt;&lt;/div&gt;
0453 
0454 &lt;p&gt;This is how you can convert a text file into a processed &lt;code&gt;Doc&lt;/code&gt; object.&lt;/p&gt;
0455 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
0456 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;/p&gt;
0457 &lt;p&gt;You can assume that:&lt;/p&gt;
0458 &lt;ul&gt;
0459 &lt;li&gt;Variable names ending with the suffix &lt;strong&gt;&lt;code&gt;_text&lt;/code&gt;&lt;/strong&gt; are &lt;strong&gt;&lt;a href=&quot;https://realpython.com/python-encodings-guide/&quot;&gt;Unicode&lt;/a&gt; string objects&lt;/strong&gt;.&lt;/li&gt;
0460 &lt;li&gt;Variable name ending with the suffix &lt;strong&gt;&lt;code&gt;_doc&lt;/code&gt;&lt;/strong&gt; are &lt;strong&gt;spaCy&amp;rsquo;s language model objects&lt;/strong&gt;.&lt;/li&gt;
0461 &lt;/ul&gt;
0462 &lt;/div&gt;
0463 &lt;h2 id=&quot;sentence-detection&quot;&gt;Sentence Detection&lt;/h2&gt;
0464 &lt;p&gt;&lt;strong&gt;Sentence Detection&lt;/strong&gt; is the process of locating the start and end of sentences in a given text. This allows you to you divide a text into linguistically meaningful units. You&amp;rsquo;ll use these units when you&amp;rsquo;re processing your text to perform tasks such as &lt;strong&gt;part of speech tagging&lt;/strong&gt; and &lt;strong&gt;entity extraction&lt;/strong&gt;.&lt;/p&gt;
0465 &lt;p&gt;In spaCy, the &lt;code&gt;sents&lt;/code&gt; property is used to extract sentences. Here&amp;rsquo;s how you would extract the total number of sentences and the sentences for a given input text:&lt;/p&gt;
0466 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Gus Proto is a Python developer currently&amp;#39;&lt;/span&gt;
0467 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;              &lt;span class=&quot;s1&quot;&gt;&amp;#39; working for a London-based Fintech&amp;#39;&lt;/span&gt;
0468 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;              &lt;span class=&quot;s1&quot;&gt;&amp;#39; company. He is interested in learning&amp;#39;&lt;/span&gt;
0469 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;              &lt;span class=&quot;s1&quot;&gt;&amp;#39; Natural Language Processing.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0470 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0471 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sentences&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_doc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0472 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sentences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0473 &lt;span class=&quot;go&quot;&gt;2&lt;/span&gt;
0474 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sentence&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sentences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0475 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sentence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0476 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0477 &lt;span class=&quot;go&quot;&gt;&amp;#39;Gus Proto is a Python developer currently working for a&lt;/span&gt;
0478 &lt;span class=&quot;go&quot;&gt;London-based Fintech company.&amp;#39;&lt;/span&gt;
0479 &lt;span class=&quot;go&quot;&gt;&amp;#39;He is interested in learning Natural Language Processing.&amp;#39;&lt;/span&gt;
0480 &lt;/pre&gt;&lt;/div&gt;
0481 
0482 &lt;p&gt;In the above example, spaCy is correctly able to identify sentences in the English language, using a full stop(&lt;code&gt;.&lt;/code&gt;) as the sentence delimiter. You can also customize the sentence detection to detect sentences on custom delimiters.&lt;/p&gt;
0483 &lt;p&gt;Here&amp;rsquo;s an example, where an ellipsis(&lt;code&gt;...&lt;/code&gt;) is used as the delimiter:&lt;/p&gt;
0484 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;set_custom_boundaries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0485 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# Adds support to use `...` as the delimiter for sentence detection&lt;/span&gt;
0486 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
0487 &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;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;...&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0488 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_sent_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
0489 &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;doc&lt;/span&gt;
0490 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0491 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ellipsis_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Gus, can you, ... never mind, I forgot&amp;#39;&lt;/span&gt;
0492 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                 &lt;span class=&quot;s1&quot;&gt;&amp;#39; what I was saying. So, do you think&amp;#39;&lt;/span&gt;
0493 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                 &lt;span class=&quot;s1&quot;&gt;&amp;#39; we should ...&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0494 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Load a new model instance&lt;/span&gt;
0495 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom_nlp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;en_core_web_sm&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0496 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom_nlp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_pipe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_custom_boundaries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;parser&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0497 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom_ellipsis_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;custom_nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ellipsis_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0498 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom_ellipsis_sentences&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom_ellipsis_doc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0499 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sentence&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;custom_ellipsis_sentences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0500 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sentence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0501 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0502 &lt;span class=&quot;go&quot;&gt;Gus, can you, ...&lt;/span&gt;
0503 &lt;span class=&quot;go&quot;&gt;never mind, I forgot what I was saying.&lt;/span&gt;
0504 &lt;span class=&quot;go&quot;&gt;So, do you think we should ...&lt;/span&gt;
0505 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Sentence Detection with no customization&lt;/span&gt;
0506 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ellipsis_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ellipsis_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0507 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ellipsis_sentences&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ellipsis_doc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0508 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sentence&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ellipsis_sentences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0509 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sentence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0510 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0511 &lt;span class=&quot;go&quot;&gt;Gus, can you, ... never mind, I forgot what I was saying.&lt;/span&gt;
0512 &lt;span class=&quot;go&quot;&gt;So, do you think we should ...&lt;/span&gt;
0513 &lt;/pre&gt;&lt;/div&gt;
0514 
0515 &lt;p&gt;Note that &lt;code&gt;custom_ellipsis_sentences&lt;/code&gt; contain three sentences, whereas &lt;code&gt;ellipsis_sentences&lt;/code&gt; contains two sentences. These sentences are still obtained via the &lt;code&gt;sents&lt;/code&gt; attribute, as you saw before.&lt;/p&gt;
0516 &lt;h2 id=&quot;tokenization-in-spacy&quot;&gt;Tokenization in spaCy&lt;/h2&gt;
0517 &lt;p&gt;&lt;strong&gt;Tokenization&lt;/strong&gt; is the next step after sentence detection. It allows you to identify the basic units in your text. These basic units are called &lt;strong&gt;tokens&lt;/strong&gt;. Tokenization is useful because it breaks a text into meaningful units. These units are used for further analysis, like part of speech tagging.&lt;/p&gt;
0518 &lt;p&gt;In spaCy, you can print tokens by iterating on the &lt;code&gt;Doc&lt;/code&gt; object:&lt;/p&gt;
0519 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0520 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0521 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0522 &lt;span class=&quot;go&quot;&gt;Gus 0&lt;/span&gt;
0523 &lt;span class=&quot;go&quot;&gt;Proto 4&lt;/span&gt;
0524 &lt;span class=&quot;go&quot;&gt;is 10&lt;/span&gt;
0525 &lt;span class=&quot;go&quot;&gt;a 13&lt;/span&gt;
0526 &lt;span class=&quot;go&quot;&gt;Python 15&lt;/span&gt;
0527 &lt;span class=&quot;go&quot;&gt;developer 22&lt;/span&gt;
0528 &lt;span class=&quot;go&quot;&gt;currently 32&lt;/span&gt;
0529 &lt;span class=&quot;go&quot;&gt;working 42&lt;/span&gt;
0530 &lt;span class=&quot;go&quot;&gt;for 50&lt;/span&gt;
0531 &lt;span class=&quot;go&quot;&gt;a 54&lt;/span&gt;
0532 &lt;span class=&quot;go&quot;&gt;London 56&lt;/span&gt;
0533 &lt;span class=&quot;go&quot;&gt;- 62&lt;/span&gt;
0534 &lt;span class=&quot;go&quot;&gt;based 63&lt;/span&gt;
0535 &lt;span class=&quot;go&quot;&gt;Fintech 69&lt;/span&gt;
0536 &lt;span class=&quot;go&quot;&gt;company 77&lt;/span&gt;
0537 &lt;span class=&quot;go&quot;&gt;. 84&lt;/span&gt;
0538 &lt;span class=&quot;go&quot;&gt;He 86&lt;/span&gt;
0539 &lt;span class=&quot;go&quot;&gt;is 89&lt;/span&gt;
0540 &lt;span class=&quot;go&quot;&gt;interested 92&lt;/span&gt;
0541 &lt;span class=&quot;go&quot;&gt;in 103&lt;/span&gt;
0542 &lt;span class=&quot;go&quot;&gt;learning 106&lt;/span&gt;
0543 &lt;span class=&quot;go&quot;&gt;Natural 115&lt;/span&gt;
0544 &lt;span class=&quot;go&quot;&gt;Language 123&lt;/span&gt;
0545 &lt;span class=&quot;go&quot;&gt;Processing 132&lt;/span&gt;
0546 &lt;span class=&quot;go&quot;&gt;. 142&lt;/span&gt;
0547 &lt;/pre&gt;&lt;/div&gt;
0548 
0549 &lt;p&gt;Note how spaCy preserves the &lt;strong&gt;starting index&lt;/strong&gt; of the tokens. It&amp;rsquo;s useful for in-place word replacement. spaCy provides &lt;a href=&quot;https://spacy.io/api/token#attributes&quot;&gt;various attributes&lt;/a&gt; for the &lt;code&gt;Token&lt;/code&gt; class:&lt;/p&gt;
0550 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0551 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text_with_ws&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
0552 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;           &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_alpha&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_punct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_space&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
0553 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;           &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0554 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0555 &lt;span class=&quot;go&quot;&gt;Gus 0 Gus  True False False Xxx False&lt;/span&gt;
0556 &lt;span class=&quot;go&quot;&gt;Proto 4 Proto  True False False Xxxxx False&lt;/span&gt;
0557 &lt;span class=&quot;go&quot;&gt;is 10 is  True False False xx True&lt;/span&gt;
0558 &lt;span class=&quot;go&quot;&gt;a 13 a  True False False x True&lt;/span&gt;
0559 &lt;span class=&quot;go&quot;&gt;Python 15 Python  True False False Xxxxx False&lt;/span&gt;
0560 &lt;span class=&quot;go&quot;&gt;developer 22 developer  True False False xxxx False&lt;/span&gt;
0561 &lt;span class=&quot;go&quot;&gt;currently 32 currently  True False False xxxx False&lt;/span&gt;
0562 &lt;span class=&quot;go&quot;&gt;working 42 working  True False False xxxx False&lt;/span&gt;
0563 &lt;span class=&quot;go&quot;&gt;for 50 for  True False False xxx True&lt;/span&gt;
0564 &lt;span class=&quot;go&quot;&gt;a 54 a  True False False x True&lt;/span&gt;
0565 &lt;span class=&quot;go&quot;&gt;London 56 London True False False Xxxxx False&lt;/span&gt;
0566 &lt;span class=&quot;go&quot;&gt;- 62 - False True False - False&lt;/span&gt;
0567 &lt;span class=&quot;go&quot;&gt;based 63 based  True False False xxxx False&lt;/span&gt;
0568 &lt;span class=&quot;go&quot;&gt;Fintech 69 Fintech  True False False Xxxxx False&lt;/span&gt;
0569 &lt;span class=&quot;go&quot;&gt;company 77 company True False False xxxx False&lt;/span&gt;
0570 &lt;span class=&quot;go&quot;&gt;. 84 .  False True False . False&lt;/span&gt;
0571 &lt;span class=&quot;go&quot;&gt;He 86 He  True False False Xx True&lt;/span&gt;
0572 &lt;span class=&quot;go&quot;&gt;is 89 is  True False False xx True&lt;/span&gt;
0573 &lt;span class=&quot;go&quot;&gt;interested 92 interested  True False False xxxx False&lt;/span&gt;
0574 &lt;span class=&quot;go&quot;&gt;in 103 in  True False False xx True&lt;/span&gt;
0575 &lt;span class=&quot;go&quot;&gt;learning 106 learning  True False False xxxx False&lt;/span&gt;
0576 &lt;span class=&quot;go&quot;&gt;Natural 115 Natural  True False False Xxxxx False&lt;/span&gt;
0577 &lt;span class=&quot;go&quot;&gt;Language 123 Language  True False False Xxxxx False&lt;/span&gt;
0578 &lt;span class=&quot;go&quot;&gt;Processing 132 Processing True False False Xxxxx False&lt;/span&gt;
0579 &lt;span class=&quot;go&quot;&gt;. 142 . False True False . False&lt;/span&gt;
0580 &lt;/pre&gt;&lt;/div&gt;
0581 
0582 &lt;p&gt;In this example, some of the commonly required attributes are accessed:&lt;/p&gt;
0583 &lt;ul&gt;
0584 &lt;li&gt;&lt;strong&gt;&lt;code&gt;text_with_ws&lt;/code&gt;&lt;/strong&gt; prints token text with trailing space (if present).&lt;/li&gt;
0585 &lt;li&gt;&lt;strong&gt;&lt;code&gt;is_alpha&lt;/code&gt;&lt;/strong&gt; detects if the token consists of alphabetic characters or not.&lt;/li&gt;
0586 &lt;li&gt;&lt;strong&gt;&lt;code&gt;is_punct&lt;/code&gt;&lt;/strong&gt; detects if the token is a punctuation symbol or not.&lt;/li&gt;
0587 &lt;li&gt;&lt;strong&gt;&lt;code&gt;is_space&lt;/code&gt;&lt;/strong&gt; detects if the token is a space or not.&lt;/li&gt;
0588 &lt;li&gt;&lt;strong&gt;&lt;code&gt;shape_&lt;/code&gt;&lt;/strong&gt; prints out the shape of the word.&lt;/li&gt;
0589 &lt;li&gt;&lt;strong&gt;&lt;code&gt;is_stop&lt;/code&gt;&lt;/strong&gt; detects if the token is a stop word or not.&lt;/li&gt;
0590 &lt;/ul&gt;
0591 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
0592 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You&amp;rsquo;ll learn more about &lt;strong&gt;stop words&lt;/strong&gt; in the next section.&lt;/p&gt;
0593 &lt;/div&gt;
0594 &lt;p&gt;You can also customize the tokenization process to detect tokens on custom characters. This is often used for hyphenated words, which are words joined with hyphen. For example, &amp;ldquo;London-based&amp;rdquo; is a hyphenated word.&lt;/p&gt;
0595 &lt;p&gt;spaCy allows you to customize tokenization by updating the &lt;code&gt;tokenizer&lt;/code&gt; property on the &lt;code&gt;nlp&lt;/code&gt; object:&lt;/p&gt;
0596 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;re&lt;/span&gt;
0597 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;spacy&lt;/span&gt;
0598 &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;nn&quot;&gt;spacy.tokenizer&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tokenizer&lt;/span&gt;
0599 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom_nlp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;en_core_web_sm&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0600 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prefix_re&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;compile_prefix_regex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom_nlp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Defaults&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prefixes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0601 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;suffix_re&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;compile_suffix_regex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom_nlp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Defaults&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;suffixes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0602 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;infix_re&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&amp;#39;[-~]&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0603 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;customize_tokenizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0604 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# Adds support to use `-` as the delimiter for tokenization&lt;/span&gt;
0605 &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;Tokenizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prefix_search&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prefix_re&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
0606 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                     &lt;span class=&quot;n&quot;&gt;suffix_search&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;suffix_re&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
0607 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                     &lt;span class=&quot;n&quot;&gt;infix_finditer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;infix_re&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;finditer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
0608 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                     &lt;span class=&quot;n&quot;&gt;token_match&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;
0609 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                     &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0610 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0611 
0612 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom_nlp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;customize_tokenizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom_nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0613 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom_tokenizer_about_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;custom_nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0614 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;custom_tokenizer_about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
0615 &lt;span class=&quot;go&quot;&gt;[&amp;#39;Gus&amp;#39;, &amp;#39;Proto&amp;#39;, &amp;#39;is&amp;#39;, &amp;#39;a&amp;#39;, &amp;#39;Python&amp;#39;, &amp;#39;developer&amp;#39;, &amp;#39;currently&amp;#39;,&lt;/span&gt;
0616 &lt;span class=&quot;go&quot;&gt;&amp;#39;working&amp;#39;, &amp;#39;for&amp;#39;, &amp;#39;a&amp;#39;, &amp;#39;London&amp;#39;, &amp;#39;-&amp;#39;, &amp;#39;based&amp;#39;, &amp;#39;Fintech&amp;#39;,&lt;/span&gt;
0617 &lt;span class=&quot;go&quot;&gt;&amp;#39;company&amp;#39;, &amp;#39;.&amp;#39;, &amp;#39;He&amp;#39;, &amp;#39;is&amp;#39;, &amp;#39;interested&amp;#39;, &amp;#39;in&amp;#39;, &amp;#39;learning&amp;#39;,&lt;/span&gt;
0618 &lt;span class=&quot;go&quot;&gt;&amp;#39;Natural&amp;#39;, &amp;#39;Language&amp;#39;, &amp;#39;Processing&amp;#39;, &amp;#39;.&amp;#39;]&lt;/span&gt;
0619 &lt;/pre&gt;&lt;/div&gt;
0620 
0621 &lt;p&gt;In order for you to customize, you can pass various parameters to the &lt;code&gt;Tokenizer&lt;/code&gt; class:&lt;/p&gt;
0622 &lt;ul&gt;
0623 &lt;li&gt;&lt;strong&gt;&lt;code&gt;nlp.vocab&lt;/code&gt;&lt;/strong&gt; is a storage container for special cases and is used to handle cases like contractions and emoticons.&lt;/li&gt;
0624 &lt;li&gt;&lt;strong&gt;&lt;code&gt;prefix_search&lt;/code&gt;&lt;/strong&gt; is the function that is used to handle preceding punctuation, such as opening parentheses.&lt;/li&gt;
0625 &lt;li&gt;&lt;strong&gt;&lt;code&gt;infix_finditer&lt;/code&gt;&lt;/strong&gt; is the function that is used to handle non-whitespace separators, such as hyphens.&lt;/li&gt;
0626 &lt;li&gt;&lt;strong&gt;&lt;code&gt;suffix_search&lt;/code&gt;&lt;/strong&gt; is the function that is used to handle succeeding punctuation, such as closing parentheses.&lt;/li&gt;
0627 &lt;li&gt;&lt;strong&gt;&lt;code&gt;token_match&lt;/code&gt;&lt;/strong&gt; is an optional boolean function that is used to match strings that should never be split. It overrides the previous rules and is useful for entities like URLs or numbers.&lt;/li&gt;
0628 &lt;/ul&gt;
0629 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
0630 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; spaCy already detects hyphenated words as individual tokens. The above code is just an example to show how tokenization can be customized. It can be used for any other character.&lt;/p&gt;
0631 &lt;/div&gt;
0632 &lt;h2 id=&quot;stop-words&quot;&gt;Stop Words&lt;/h2&gt;
0633 &lt;p&gt;&lt;strong&gt;Stop words&lt;/strong&gt; are the most common words in a language. In the English language, some examples of stop words are &lt;code&gt;the&lt;/code&gt;, &lt;code&gt;are&lt;/code&gt;, &lt;code&gt;but&lt;/code&gt;, and &lt;code&gt;they&lt;/code&gt;. Most sentences need to contain stop words in order to be full sentences that make sense.&lt;/p&gt;
0634 &lt;p&gt;Generally, stop words are removed because they aren&amp;rsquo;t significant and distort the word frequency analysis. spaCy has a list of stop words for the English language:&lt;/p&gt;
0635 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;spacy&lt;/span&gt;
0636 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spacy_stopwords&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;en&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stop_words&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;STOP_WORDS&lt;/span&gt;
0637 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spacy_stopwords&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0638 &lt;span class=&quot;go&quot;&gt;326&lt;/span&gt;
0639 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stop_word&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spacy_stopwords&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
0640 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stop_word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0641 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0642 &lt;span class=&quot;go&quot;&gt;using&lt;/span&gt;
0643 &lt;span class=&quot;go&quot;&gt;becomes&lt;/span&gt;
0644 &lt;span class=&quot;go&quot;&gt;had&lt;/span&gt;
0645 &lt;span class=&quot;go&quot;&gt;itself&lt;/span&gt;
0646 &lt;span class=&quot;go&quot;&gt;once&lt;/span&gt;
0647 &lt;span class=&quot;go&quot;&gt;often&lt;/span&gt;
0648 &lt;span class=&quot;go&quot;&gt;is&lt;/span&gt;
0649 &lt;span class=&quot;go&quot;&gt;herein&lt;/span&gt;
0650 &lt;span class=&quot;go&quot;&gt;who&lt;/span&gt;
0651 &lt;span class=&quot;go&quot;&gt;too&lt;/span&gt;
0652 &lt;/pre&gt;&lt;/div&gt;
0653 
0654 &lt;p&gt;You can remove stop words from the input text:&lt;/p&gt;
0655 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0656 &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;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0657 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0658 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0659 &lt;span class=&quot;go&quot;&gt;Gus&lt;/span&gt;
0660 &lt;span class=&quot;go&quot;&gt;Proto&lt;/span&gt;
0661 &lt;span class=&quot;go&quot;&gt;Python&lt;/span&gt;
0662 &lt;span class=&quot;go&quot;&gt;developer&lt;/span&gt;
0663 &lt;span class=&quot;go&quot;&gt;currently&lt;/span&gt;
0664 &lt;span class=&quot;go&quot;&gt;working&lt;/span&gt;
0665 &lt;span class=&quot;go&quot;&gt;London&lt;/span&gt;
0666 &lt;span class=&quot;go&quot;&gt;-&lt;/span&gt;
0667 &lt;span class=&quot;go&quot;&gt;based&lt;/span&gt;
0668 &lt;span class=&quot;go&quot;&gt;Fintech&lt;/span&gt;
0669 &lt;span class=&quot;go&quot;&gt;company&lt;/span&gt;
0670 &lt;span class=&quot;go&quot;&gt;.&lt;/span&gt;
0671 &lt;span class=&quot;go&quot;&gt;interested&lt;/span&gt;
0672 &lt;span class=&quot;go&quot;&gt;learning&lt;/span&gt;
0673 &lt;span class=&quot;go&quot;&gt;Natural&lt;/span&gt;
0674 &lt;span class=&quot;go&quot;&gt;Language&lt;/span&gt;
0675 &lt;span class=&quot;go&quot;&gt;Processing&lt;/span&gt;
0676 &lt;span class=&quot;go&quot;&gt;.&lt;/span&gt;
0677 &lt;/pre&gt;&lt;/div&gt;
0678 
0679 &lt;p&gt;Stop words like &lt;code&gt;is&lt;/code&gt;, &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;the&lt;/code&gt;, and &lt;code&gt;in&lt;/code&gt; are not printed in the output above. You can also create a list of tokens not containing stop words:&lt;/p&gt;
0680 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_no_stopword_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;about_doc&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0681 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_no_stopword_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0682 &lt;span class=&quot;go&quot;&gt;[Gus, Proto, Python, developer, currently, working, London,&lt;/span&gt;
0683 &lt;span class=&quot;go&quot;&gt;-, based, Fintech, company, ., interested, learning, Natural,&lt;/span&gt;
0684 &lt;span class=&quot;go&quot;&gt;Language, Processing, .]&lt;/span&gt;
0685 &lt;/pre&gt;&lt;/div&gt;
0686 
0687 &lt;p&gt;&lt;code&gt;about_no_stopword_doc&lt;/code&gt; can be joined with spaces to form a sentence with no stop words.&lt;/p&gt;
0688 &lt;h2 id=&quot;lemmatization&quot;&gt;Lemmatization&lt;/h2&gt;
0689 &lt;p&gt;&lt;strong&gt;Lemmatization&lt;/strong&gt; is the process of reducing inflected forms of a word while still ensuring that the reduced form belongs to the language. This reduced form or root word is called a &lt;strong&gt;lemma&lt;/strong&gt;.&lt;/p&gt;
0690 &lt;p&gt;For example, &lt;em&gt;organizes&lt;/em&gt;, &lt;em&gt;organized&lt;/em&gt; and &lt;em&gt;organizing&lt;/em&gt; are all forms of &lt;em&gt;organize&lt;/em&gt;. Here, &lt;em&gt;organize&lt;/em&gt; is the lemma. The inflection of a word allows you to express different grammatical categories like tense (&lt;em&gt;organized&lt;/em&gt; vs &lt;em&gt;organize&lt;/em&gt;), number (&lt;em&gt;trains&lt;/em&gt; vs &lt;em&gt;train&lt;/em&gt;), and so on. Lemmatization is necessary because it helps you reduce the inflected forms of a word so that they can be analyzed as a single item. It can also help you &lt;strong&gt;normalize&lt;/strong&gt; the text.&lt;/p&gt;
0691 &lt;p&gt;spaCy has the attribute &lt;code&gt;lemma_&lt;/code&gt; on the &lt;code&gt;Token&lt;/code&gt; class. This attribute has the lemmatized form of a token:&lt;/p&gt;
0692 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conference_help_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Gus is helping organize a developer&amp;#39;&lt;/span&gt;
0693 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39;conference on Applications of Natural Language&amp;#39;&lt;/span&gt;
0694 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; Processing. He keeps organizing local Python meetups&amp;#39;&lt;/span&gt;
0695 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; and several internal talks at his workplace.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0696 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conference_help_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conference_help_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0697 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conference_help_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0698 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lemma_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0699 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0700 &lt;span class=&quot;go&quot;&gt;Gus Gus&lt;/span&gt;
0701 &lt;span class=&quot;go&quot;&gt;is be&lt;/span&gt;
0702 &lt;span class=&quot;go&quot;&gt;helping help&lt;/span&gt;
0703 &lt;span class=&quot;go&quot;&gt;organize organize&lt;/span&gt;
0704 &lt;span class=&quot;go&quot;&gt;a a&lt;/span&gt;
0705 &lt;span class=&quot;go&quot;&gt;developer developer&lt;/span&gt;
0706 &lt;span class=&quot;go&quot;&gt;conference conference&lt;/span&gt;
0707 &lt;span class=&quot;go&quot;&gt;on on&lt;/span&gt;
0708 &lt;span class=&quot;go&quot;&gt;Applications Applications&lt;/span&gt;
0709 &lt;span class=&quot;go&quot;&gt;of of&lt;/span&gt;
0710 &lt;span class=&quot;go&quot;&gt;Natural Natural&lt;/span&gt;
0711 &lt;span class=&quot;go&quot;&gt;Language Language&lt;/span&gt;
0712 &lt;span class=&quot;go&quot;&gt;Processing Processing&lt;/span&gt;
0713 &lt;span class=&quot;go&quot;&gt;. .&lt;/span&gt;
0714 &lt;span class=&quot;go&quot;&gt;He -PRON-&lt;/span&gt;
0715 &lt;span class=&quot;go&quot;&gt;keeps keep&lt;/span&gt;
0716 &lt;span class=&quot;go&quot;&gt;organizing organize&lt;/span&gt;
0717 &lt;span class=&quot;go&quot;&gt;local local&lt;/span&gt;
0718 &lt;span class=&quot;go&quot;&gt;Python Python&lt;/span&gt;
0719 &lt;span class=&quot;go&quot;&gt;meetups meetup&lt;/span&gt;
0720 &lt;span class=&quot;go&quot;&gt;and and&lt;/span&gt;
0721 &lt;span class=&quot;go&quot;&gt;several several&lt;/span&gt;
0722 &lt;span class=&quot;go&quot;&gt;internal internal&lt;/span&gt;
0723 &lt;span class=&quot;go&quot;&gt;talks talk&lt;/span&gt;
0724 &lt;span class=&quot;go&quot;&gt;at at&lt;/span&gt;
0725 &lt;span class=&quot;go&quot;&gt;his -PRON-&lt;/span&gt;
0726 &lt;span class=&quot;go&quot;&gt;workplace workplace&lt;/span&gt;
0727 &lt;span class=&quot;go&quot;&gt;. .&lt;/span&gt;
0728 &lt;/pre&gt;&lt;/div&gt;
0729 
0730 &lt;p&gt;In this example, &lt;code&gt;organizing&lt;/code&gt; reduces to its lemma form &lt;code&gt;organize&lt;/code&gt;. If you do not lemmatize the text, then &lt;code&gt;organize&lt;/code&gt; and &lt;code&gt;organizing&lt;/code&gt; will be counted as different tokens, even though they both have a similar meaning. Lemmatization helps you avoid duplicate words that have similar meanings.&lt;/p&gt;
0731 &lt;h2 id=&quot;word-frequency&quot;&gt;Word Frequency&lt;/h2&gt;
0732 &lt;p&gt;You can now convert a given text into tokens and perform statistical analysis over it. This analysis can give you various insights about word patterns, such as common words or unique words in the text:&lt;/p&gt;
0733 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;collections&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;
0734 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;complete_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Gus Proto is a Python developer currently&amp;#39;&lt;/span&gt;
0735 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39;working for a London-based Fintech company. He is&amp;#39;&lt;/span&gt;
0736 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; interested in learning Natural Language Processing.&amp;#39;&lt;/span&gt;
0737 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; There is a developer conference happening on 21 July&amp;#39;&lt;/span&gt;
0738 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; 2019 in London. It is titled &amp;quot;Applications of Natural&amp;#39;&lt;/span&gt;
0739 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; Language Processing&amp;quot;. There is a helpline number &amp;#39;&lt;/span&gt;
0740 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; available at +1-1234567891. Gus is helping organize it.&amp;#39;&lt;/span&gt;
0741 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; He keeps organizing local Python meetups and several&amp;#39;&lt;/span&gt;
0742 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; internal talks at his workplace. Gus is also presenting&amp;#39;&lt;/span&gt;
0743 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; a talk. The talk will introduce the reader about &amp;quot;Use&amp;#39;&lt;/span&gt;
0744 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; cases of Natural Language Processing in Fintech&amp;quot;.&amp;#39;&lt;/span&gt;
0745 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; Apart from his work, he is very passionate about music.&amp;#39;&lt;/span&gt;
0746 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; Gus is learning to play the Piano. He has enrolled &amp;#39;&lt;/span&gt;
0747 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; himself in the weekend batch of Great Piano Academy.&amp;#39;&lt;/span&gt;
0748 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; Great Piano Academy is situated in Mayfair or the City&amp;#39;&lt;/span&gt;
0749 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; of London and has world-class piano instructors.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0750 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0751 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;complete_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;complete_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0752 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Remove stop words and punctuation symbols&lt;/span&gt;
0753 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;complete_doc&lt;/span&gt;
0754 &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;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_stop&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_punct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0755 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word_freq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0756 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# 5 commonly occurring words with their frequencies&lt;/span&gt;
0757 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;common_words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word_freq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;most_common&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0758 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;common_words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0759 &lt;span class=&quot;go&quot;&gt;[(&amp;#39;Gus&amp;#39;, 4), (&amp;#39;London&amp;#39;, 3), (&amp;#39;Natural&amp;#39;, 3), (&amp;#39;Language&amp;#39;, 3), (&amp;#39;Processing&amp;#39;, 3)]&lt;/span&gt;
0760 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Unique words&lt;/span&gt;
0761 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;freq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word_freq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;freq&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;
0762 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0763 &lt;span class=&quot;go&quot;&gt;[&amp;#39;Proto&amp;#39;, &amp;#39;currently&amp;#39;, &amp;#39;working&amp;#39;, &amp;#39;based&amp;#39;, &amp;#39;company&amp;#39;,&lt;/span&gt;
0764 &lt;span class=&quot;go&quot;&gt;&amp;#39;interested&amp;#39;, &amp;#39;conference&amp;#39;, &amp;#39;happening&amp;#39;, &amp;#39;21&amp;#39;, &amp;#39;July&amp;#39;,&lt;/span&gt;
0765 &lt;span class=&quot;go&quot;&gt;&amp;#39;2019&amp;#39;, &amp;#39;titled&amp;#39;, &amp;#39;Applications&amp;#39;, &amp;#39;helpline&amp;#39;, &amp;#39;number&amp;#39;,&lt;/span&gt;
0766 &lt;span class=&quot;go&quot;&gt;&amp;#39;available&amp;#39;, &amp;#39;+1&amp;#39;, &amp;#39;1234567891&amp;#39;, &amp;#39;helping&amp;#39;, &amp;#39;organize&amp;#39;,&lt;/span&gt;
0767 &lt;span class=&quot;go&quot;&gt;&amp;#39;keeps&amp;#39;, &amp;#39;organizing&amp;#39;, &amp;#39;local&amp;#39;, &amp;#39;meetups&amp;#39;, &amp;#39;internal&amp;#39;,&lt;/span&gt;
0768 &lt;span class=&quot;go&quot;&gt;&amp;#39;talks&amp;#39;, &amp;#39;workplace&amp;#39;, &amp;#39;presenting&amp;#39;, &amp;#39;introduce&amp;#39;, &amp;#39;reader&amp;#39;,&lt;/span&gt;
0769 &lt;span class=&quot;go&quot;&gt;&amp;#39;Use&amp;#39;, &amp;#39;cases&amp;#39;, &amp;#39;Apart&amp;#39;, &amp;#39;work&amp;#39;, &amp;#39;passionate&amp;#39;, &amp;#39;music&amp;#39;, &amp;#39;play&amp;#39;,&lt;/span&gt;
0770 &lt;span class=&quot;go&quot;&gt;&amp;#39;enrolled&amp;#39;, &amp;#39;weekend&amp;#39;, &amp;#39;batch&amp;#39;, &amp;#39;situated&amp;#39;, &amp;#39;Mayfair&amp;#39;, &amp;#39;City&amp;#39;,&lt;/span&gt;
0771 &lt;span class=&quot;go&quot;&gt;&amp;#39;world&amp;#39;, &amp;#39;class&amp;#39;, &amp;#39;piano&amp;#39;, &amp;#39;instructors&amp;#39;]&lt;/span&gt;
0772 &lt;/pre&gt;&lt;/div&gt;
0773 
0774 &lt;p&gt;By looking at the common words, you can see that the text as a whole is probably about &lt;code&gt;Gus&lt;/code&gt;, &lt;code&gt;London&lt;/code&gt;, or &lt;code&gt;Natural Language Processing&lt;/code&gt;. This way, you can take any unstructured text and perform statistical analysis to know what it&amp;rsquo;s about.&lt;/p&gt;
0775 &lt;p&gt;Here&amp;rsquo;s another example of the same text with stop words:&lt;/p&gt;
0776 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words_all&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;complete_doc&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_punct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0777 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word_freq_all&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words_all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0778 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# 5 commonly occurring words with their frequencies&lt;/span&gt;
0779 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;common_words_all&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word_freq_all&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;most_common&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0780 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;common_words_all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0781 &lt;span class=&quot;go&quot;&gt;[(&amp;#39;is&amp;#39;, 10), (&amp;#39;a&amp;#39;, 5), (&amp;#39;in&amp;#39;, 5), (&amp;#39;Gus&amp;#39;, 4), (&amp;#39;of&amp;#39;, 4)]&lt;/span&gt;
0782 &lt;/pre&gt;&lt;/div&gt;
0783 
0784 &lt;p&gt;Four out of five of the most common words are stop words, which don&amp;rsquo;t tell you much about the text. If you consider stop words while doing word frequency analysis, then you won&amp;rsquo;t be able to derive meaningful insights from the input text. This is why removing stop words is so important.&lt;/p&gt;
0785 &lt;h2 id=&quot;part-of-speech-tagging&quot;&gt;Part of Speech Tagging&lt;/h2&gt;
0786 &lt;p&gt;&lt;strong&gt;Part of speech&lt;/strong&gt; or &lt;strong&gt;POS&lt;/strong&gt; is a grammatical role that explains how a particular word is used in a sentence. There are eight parts of speech:&lt;/p&gt;
0787 &lt;ol&gt;
0788 &lt;li&gt;Noun&lt;/li&gt;
0789 &lt;li&gt;Pronoun&lt;/li&gt;
0790 &lt;li&gt;Adjective&lt;/li&gt;
0791 &lt;li&gt;Verb&lt;/li&gt;
0792 &lt;li&gt;Adverb&lt;/li&gt;
0793 &lt;li&gt;Preposition&lt;/li&gt;
0794 &lt;li&gt;Conjunction&lt;/li&gt;
0795 &lt;li&gt;Interjection&lt;/li&gt;
0796 &lt;/ol&gt;
0797 &lt;p&gt;&lt;strong&gt;Part of speech tagging&lt;/strong&gt; is the process of assigning a &lt;strong&gt;POS tag&lt;/strong&gt; to each token depending on its usage in the sentence. POS tags are useful for assigning a syntactic category like &lt;strong&gt;noun&lt;/strong&gt; or &lt;strong&gt;verb&lt;/strong&gt; to each word.&lt;/p&gt;
0798 &lt;p&gt;In spaCy, POS tags are available as an attribute on the &lt;code&gt;Token&lt;/code&gt; object:&lt;/p&gt;
0799 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0800 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pos_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;explain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
0801 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0802 &lt;span class=&quot;go&quot;&gt;Gus NNP PROPN noun, proper singular&lt;/span&gt;
0803 &lt;span class=&quot;go&quot;&gt;Proto NNP PROPN noun, proper singular&lt;/span&gt;
0804 &lt;span class=&quot;go&quot;&gt;is VBZ VERB verb, 3rd person singular present&lt;/span&gt;
0805 &lt;span class=&quot;go&quot;&gt;a DT DET determiner&lt;/span&gt;
0806 &lt;span class=&quot;go&quot;&gt;Python NNP PROPN noun, proper singular&lt;/span&gt;
0807 &lt;span class=&quot;go&quot;&gt;developer NN NOUN noun, singular or mass&lt;/span&gt;
0808 &lt;span class=&quot;go&quot;&gt;currently RB ADV adverb&lt;/span&gt;
0809 &lt;span class=&quot;go&quot;&gt;working VBG VERB verb, gerund or present participle&lt;/span&gt;
0810 &lt;span class=&quot;go&quot;&gt;for IN ADP conjunction, subordinating or preposition&lt;/span&gt;
0811 &lt;span class=&quot;go&quot;&gt;a DT DET determiner&lt;/span&gt;
0812 &lt;span class=&quot;go&quot;&gt;London NNP PROPN noun, proper singular&lt;/span&gt;
0813 &lt;span class=&quot;go&quot;&gt;- HYPH PUNCT punctuation mark, hyphen&lt;/span&gt;
0814 &lt;span class=&quot;go&quot;&gt;based VBN VERB verb, past participle&lt;/span&gt;
0815 &lt;span class=&quot;go&quot;&gt;Fintech NNP PROPN noun, proper singular&lt;/span&gt;
0816 &lt;span class=&quot;go&quot;&gt;company NN NOUN noun, singular or mass&lt;/span&gt;
0817 &lt;span class=&quot;go&quot;&gt;. . PUNCT punctuation mark, sentence closer&lt;/span&gt;
0818 &lt;span class=&quot;go&quot;&gt;He PRP PRON pronoun, personal&lt;/span&gt;
0819 &lt;span class=&quot;go&quot;&gt;is VBZ VERB verb, 3rd person singular present&lt;/span&gt;
0820 &lt;span class=&quot;go&quot;&gt;interested JJ ADJ adjective&lt;/span&gt;
0821 &lt;span class=&quot;go&quot;&gt;in IN ADP conjunction, subordinating or preposition&lt;/span&gt;
0822 &lt;span class=&quot;go&quot;&gt;learning VBG VERB verb, gerund or present participle&lt;/span&gt;
0823 &lt;span class=&quot;go&quot;&gt;Natural NNP PROPN noun, proper singular&lt;/span&gt;
0824 &lt;span class=&quot;go&quot;&gt;Language NNP PROPN noun, proper singular&lt;/span&gt;
0825 &lt;span class=&quot;go&quot;&gt;Processing NNP PROPN noun, proper singular&lt;/span&gt;
0826 &lt;span class=&quot;go&quot;&gt;. . PUNCT punctuation mark, sentence closer&lt;/span&gt;
0827 &lt;/pre&gt;&lt;/div&gt;
0828 
0829 &lt;p&gt;Here, two attributes of the &lt;code&gt;Token&lt;/code&gt; class are accessed:&lt;/p&gt;
0830 &lt;ol&gt;
0831 &lt;li&gt;&lt;strong&gt;&lt;code&gt;tag_&lt;/code&gt;&lt;/strong&gt; lists the fine-grained part of speech.&lt;/li&gt;
0832 &lt;li&gt;&lt;strong&gt;&lt;code&gt;pos_&lt;/code&gt;&lt;/strong&gt; lists the coarse-grained part of speech.&lt;/li&gt;
0833 &lt;/ol&gt;
0834 &lt;p&gt;&lt;code&gt;spacy.explain&lt;/code&gt; gives descriptive details about a particular POS tag. spaCy provides a &lt;a href=&quot;https://spaCy.io/api/annotation#pos-tagging&quot;&gt;complete tag list&lt;/a&gt; along with an explanation for each tag.&lt;/p&gt;
0835 &lt;p&gt;Using POS tags, you can extract a particular category of words:&lt;/p&gt;
0836 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nouns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
0837 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adjectives&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
0838 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0839 &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;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pos_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;NOUN&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0840 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;nouns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0841 &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;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pos_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ADJ&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0842 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;adjectives&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0843 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0844 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nouns&lt;/span&gt;
0845 &lt;span class=&quot;go&quot;&gt;[developer, company]&lt;/span&gt;
0846 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adjectives&lt;/span&gt;
0847 &lt;span class=&quot;go&quot;&gt;[interested]&lt;/span&gt;
0848 &lt;/pre&gt;&lt;/div&gt;
0849 
0850 &lt;p&gt;You can use this to derive insights, remove the most common nouns, or see which adjectives are used for a particular noun.&lt;/p&gt;
0851 &lt;h2 id=&quot;visualization-using-displacy&quot;&gt;Visualization: Using displaCy&lt;/h2&gt;
0852 &lt;p&gt;spaCy comes with a built-in visualizer called &lt;strong&gt;displaCy&lt;/strong&gt;. You can use it to visualize a &lt;strong&gt;dependency parse&lt;/strong&gt; or &lt;strong&gt;named entities&lt;/strong&gt; in a browser or a &lt;a href=&quot;https://realpython.com/jupyter-notebook-introduction/&quot;&gt;Jupyter notebook&lt;/a&gt;.&lt;/p&gt;
0853 &lt;p&gt;You can use displaCy to find POS tags for tokens:&lt;/p&gt;
0854 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;spacy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;displacy&lt;/span&gt;
0855 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_interest_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;He is interested in learning&amp;#39;&lt;/span&gt;
0856 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; Natural Language Processing.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0857 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_interest_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_interest_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0858 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;displacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_interest_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;dep&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0859 &lt;/pre&gt;&lt;/div&gt;
0860 
0861 &lt;p&gt;The above code will spin a simple web server. You can see the visualization by opening &lt;a href=&quot;http://127.0.0.1:5000&quot;&gt;http://127.0.0.1:5000&lt;/a&gt; in your browser:&lt;/p&gt;
0862 &lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/displacy_pos_tags.45059f2bf851.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/displacy_pos_tags.45059f2bf851.png&quot; width=&quot;2630&quot; height=&quot;600&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/displacy_pos_tags.45059f2bf851.png&amp;amp;w=657&amp;amp;sig=a49d6b5a0e5952aea59c0241f61fb09440bb326b 657w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/displacy_pos_tags.45059f2bf851.png&amp;amp;w=1315&amp;amp;sig=858218e45ae1e23a87ad42204154aeae77c9cc0c 1315w, https://files.realpython.com/media/displacy_pos_tags.45059f2bf851.png 2630w&quot; sizes=&quot;75vw&quot; alt=&quot;Displacy: Part of Speech Tagging Demo&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;displaCy: Part of Speech Tagging Demo&lt;/figcaption&gt;&lt;/figure&gt;
0863 
0864 &lt;p&gt;In the image above, each token is assigned a POS tag written just below the token.&lt;/p&gt;
0865 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
0866 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Here&amp;rsquo;s how you can use displaCy in a Jupyter notebook:&lt;/p&gt;
0867 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;displacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_interest_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;dep&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;jupyter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0868 &lt;/pre&gt;&lt;/div&gt;
0869 
0870 &lt;/div&gt;
0871 &lt;h2 id=&quot;preprocessing-functions&quot;&gt;Preprocessing Functions&lt;/h2&gt;
0872 &lt;p&gt;You can create a &lt;strong&gt;preprocessing function&lt;/strong&gt; that takes text as input and applies the following operations:&lt;/p&gt;
0873 &lt;ul&gt;
0874 &lt;li&gt;Lowercases the text&lt;/li&gt;
0875 &lt;li&gt;Lemmatizes each token&lt;/li&gt;
0876 &lt;li&gt;Removes punctuation symbols&lt;/li&gt;
0877 &lt;li&gt;Removes stop words&lt;/li&gt;
0878 &lt;/ul&gt;
0879 &lt;p&gt;A preprocessing function converts text to an analyzable format. It&amp;rsquo;s necessary for most NLP tasks. Here&amp;rsquo;s an example:&lt;/p&gt;
0880 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_token_allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0881 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
0882 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;        Only allow valid tokens which are not stop words&lt;/span&gt;
0883 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;        and punctuation symbols.&lt;/span&gt;
0884 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
0885 &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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt;
0886 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_stop&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_punct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0887 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;
0888 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
0889 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0890 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;preprocess_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0891 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# Reduce token to its lowercase lemma form&lt;/span&gt;
0892 &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;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lemma_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
0893 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0894 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;complete_filtered_tokens&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;preprocess_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0895 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;complete_doc&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_token_allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
0896 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;complete_filtered_tokens&lt;/span&gt;
0897 &lt;span class=&quot;go&quot;&gt;[&amp;#39;gus&amp;#39;, &amp;#39;proto&amp;#39;, &amp;#39;python&amp;#39;, &amp;#39;developer&amp;#39;, &amp;#39;currently&amp;#39;, &amp;#39;work&amp;#39;,&lt;/span&gt;
0898 &lt;span class=&quot;go&quot;&gt;&amp;#39;london&amp;#39;, &amp;#39;base&amp;#39;, &amp;#39;fintech&amp;#39;, &amp;#39;company&amp;#39;, &amp;#39;interested&amp;#39;, &amp;#39;learn&amp;#39;,&lt;/span&gt;
0899 &lt;span class=&quot;go&quot;&gt;&amp;#39;natural&amp;#39;, &amp;#39;language&amp;#39;, &amp;#39;processing&amp;#39;, &amp;#39;developer&amp;#39;, &amp;#39;conference&amp;#39;,&lt;/span&gt;
0900 &lt;span class=&quot;go&quot;&gt;&amp;#39;happen&amp;#39;, &amp;#39;21&amp;#39;, &amp;#39;july&amp;#39;, &amp;#39;2019&amp;#39;, &amp;#39;london&amp;#39;, &amp;#39;title&amp;#39;,&lt;/span&gt;
0901 &lt;span class=&quot;go&quot;&gt;&amp;#39;applications&amp;#39;, &amp;#39;natural&amp;#39;, &amp;#39;language&amp;#39;, &amp;#39;processing&amp;#39;, &amp;#39;helpline&amp;#39;,&lt;/span&gt;
0902 &lt;span class=&quot;go&quot;&gt;&amp;#39;number&amp;#39;, &amp;#39;available&amp;#39;, &amp;#39;+1&amp;#39;, &amp;#39;1234567891&amp;#39;, &amp;#39;gus&amp;#39;, &amp;#39;help&amp;#39;,&lt;/span&gt;
0903 &lt;span class=&quot;go&quot;&gt;&amp;#39;organize&amp;#39;, &amp;#39;keep&amp;#39;, &amp;#39;organize&amp;#39;, &amp;#39;local&amp;#39;, &amp;#39;python&amp;#39;, &amp;#39;meetup&amp;#39;,&lt;/span&gt;
0904 &lt;span class=&quot;go&quot;&gt;&amp;#39;internal&amp;#39;, &amp;#39;talk&amp;#39;, &amp;#39;workplace&amp;#39;, &amp;#39;gus&amp;#39;, &amp;#39;present&amp;#39;, &amp;#39;talk&amp;#39;, &amp;#39;talk&amp;#39;,&lt;/span&gt;
0905 &lt;span class=&quot;go&quot;&gt;&amp;#39;introduce&amp;#39;, &amp;#39;reader&amp;#39;, &amp;#39;use&amp;#39;, &amp;#39;case&amp;#39;, &amp;#39;natural&amp;#39;, &amp;#39;language&amp;#39;,&lt;/span&gt;
0906 &lt;span class=&quot;go&quot;&gt;&amp;#39;processing&amp;#39;, &amp;#39;fintech&amp;#39;, &amp;#39;apart&amp;#39;, &amp;#39;work&amp;#39;, &amp;#39;passionate&amp;#39;, &amp;#39;music&amp;#39;,&lt;/span&gt;
0907 &lt;span class=&quot;go&quot;&gt;&amp;#39;gus&amp;#39;, &amp;#39;learn&amp;#39;, &amp;#39;play&amp;#39;, &amp;#39;piano&amp;#39;, &amp;#39;enrol&amp;#39;, &amp;#39;weekend&amp;#39;, &amp;#39;batch&amp;#39;,&lt;/span&gt;
0908 &lt;span class=&quot;go&quot;&gt;&amp;#39;great&amp;#39;, &amp;#39;piano&amp;#39;, &amp;#39;academy&amp;#39;, &amp;#39;great&amp;#39;, &amp;#39;piano&amp;#39;, &amp;#39;academy&amp;#39;,&lt;/span&gt;
0909 &lt;span class=&quot;go&quot;&gt;&amp;#39;situate&amp;#39;, &amp;#39;mayfair&amp;#39;, &amp;#39;city&amp;#39;, &amp;#39;london&amp;#39;, &amp;#39;world&amp;#39;, &amp;#39;class&amp;#39;,&lt;/span&gt;
0910 &lt;span class=&quot;go&quot;&gt;&amp;#39;piano&amp;#39;, &amp;#39;instructor&amp;#39;]&lt;/span&gt;
0911 &lt;/pre&gt;&lt;/div&gt;
0912 
0913 &lt;p&gt;Note that the &lt;code&gt;complete_filtered_tokens&lt;/code&gt; does not contain any stop word or punctuation symbols and consists of lemmatized lowercase tokens.&lt;/p&gt;
0914 &lt;h2 id=&quot;rule-based-matching-using-spacy&quot;&gt;Rule-Based Matching Using spaCy&lt;/h2&gt;
0915 &lt;p&gt;&lt;strong&gt;Rule-based matching&lt;/strong&gt; is one of the steps in extracting information from unstructured text. It&amp;rsquo;s used to identify and extract tokens and phrases according to patterns (such as lowercase) and grammatical features (such as part of speech).&lt;/p&gt;
0916 &lt;p&gt;Rule-based matching can use &lt;a href=&quot;https://en.wikipedia.org/wiki/Regular_expression&quot;&gt;regular expressions&lt;/a&gt; to extract entities (such as phone numbers) from an unstructured text. It&amp;rsquo;s different from extracting text using regular expressions only in the sense that regular expressions don&amp;rsquo;t consider the lexical and grammatical attributes of the text.&lt;/p&gt;
0917 &lt;p&gt;With rule-based matching, you can extract a first name and a last name, which are always &lt;strong&gt;proper nouns&lt;/strong&gt;:&lt;/p&gt;
0918 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;spacy.matcher&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Matcher&lt;/span&gt;
0919 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matcher&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Matcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0920 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_full_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nlp_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0921 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;pattern&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;POS&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;PROPN&amp;#39;&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;s1&quot;&gt;&amp;#39;POS&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;PROPN&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;
0922 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;matcher&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;FULL_NAME&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pattern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0923 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nlp_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0924 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0925 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0926 &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;span&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;
0927 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0928 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extract_full_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0929 &lt;span class=&quot;go&quot;&gt;&amp;#39;Gus Proto&amp;#39;&lt;/span&gt;
0930 &lt;/pre&gt;&lt;/div&gt;
0931 
0932 &lt;p&gt;In this example, &lt;code&gt;pattern&lt;/code&gt; is a list of objects that defines the combination of tokens to be matched. Both POS tags in it are &lt;code&gt;PROPN&lt;/code&gt; (proper noun). So, the &lt;code&gt;pattern&lt;/code&gt; consists of two objects in which the POS tags for both tokens should be &lt;code&gt;PROPN&lt;/code&gt;. This pattern is then added to &lt;code&gt;Matcher&lt;/code&gt; using &lt;code&gt;FULL_NAME&lt;/code&gt; and the the &lt;code&gt;match_id&lt;/code&gt;. Finally, matches are obtained with their starting and end indexes.&lt;/p&gt;
0933 &lt;p&gt;You can also use rule-based matching to extract phone numbers:&lt;/p&gt;
0934 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;spacy.matcher&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Matcher&lt;/span&gt;
0935 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matcher&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Matcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0936 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conference_org_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;There is a developer conference&amp;#39;&lt;/span&gt;
0937 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39;happening on 21 July 2019 in London. It is titled&amp;#39;&lt;/span&gt;
0938 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; &amp;quot;Applications of Natural Language Processing&amp;quot;.&amp;#39;&lt;/span&gt;
0939 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; There is a helpline number available&amp;#39;&lt;/span&gt;
0940 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; at (123) 456-789&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0941 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0942 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_phone_number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nlp_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
0943 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;pattern&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ORTH&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;(&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;SHAPE&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ddd&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
0944 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;               &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ORTH&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;)&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;SHAPE&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ddd&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
0945 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;               &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ORTH&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;OP&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;?&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
0946 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;               &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;SHAPE&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ddd&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;
0947 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;matcher&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;PHONE_NUMBER&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pattern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0948 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nlp_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0949 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0950 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
0951 &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;span&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;
0952 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0953 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conference_org_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conference_org_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0954 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extract_phone_number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conference_org_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0955 &lt;span class=&quot;go&quot;&gt;&amp;#39;(123) 456-789&amp;#39;&lt;/span&gt;
0956 &lt;/pre&gt;&lt;/div&gt;
0957 
0958 &lt;p&gt;In this example, only the pattern is updated in order to match phone numbers from the previous example. Here, some attributes of the token are also used:&lt;/p&gt;
0959 &lt;ul&gt;
0960 &lt;li&gt;&lt;strong&gt;&lt;code&gt;ORTH&lt;/code&gt;&lt;/strong&gt; gives the exact text of the token.&lt;/li&gt;
0961 &lt;li&gt;&lt;strong&gt;&lt;code&gt;SHAPE&lt;/code&gt;&lt;/strong&gt; transforms the token string to show orthographic features.&lt;/li&gt;
0962 &lt;li&gt;&lt;strong&gt;&lt;code&gt;OP&lt;/code&gt;&lt;/strong&gt; defines operators. Using &lt;code&gt;?&lt;/code&gt; as a value means that the pattern is optional, meaning it can match 0 or 1 times.&lt;/li&gt;
0963 &lt;/ul&gt;
0964 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
0965 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For simplicity, phone numbers are assumed to be of a particular format: &lt;code&gt;(123) 456-789&lt;/code&gt;. You can change this depending on your use case.&lt;/p&gt;
0966 &lt;/div&gt;
0967 &lt;p&gt;Rule-based matching helps you identify and extract tokens and phrases according to lexical patterns (such as lowercase) and grammatical features(such as part of speech).&lt;/p&gt;
0968 &lt;h2 id=&quot;dependency-parsing-using-spacy&quot;&gt;Dependency Parsing Using spaCy&lt;/h2&gt;
0969 &lt;p&gt;&lt;strong&gt;Dependency parsing&lt;/strong&gt; is the process of extracting the dependency parse of a sentence to represent its grammatical structure. It defines the dependency relationship between &lt;strong&gt;headwords&lt;/strong&gt; and their &lt;strong&gt;dependents&lt;/strong&gt;. The head of a sentence has no dependency and is called the &lt;strong&gt;root of the sentence&lt;/strong&gt;. The &lt;strong&gt;verb&lt;/strong&gt; is usually the head of the sentence. All other words are linked to the headword.&lt;/p&gt;
0970 &lt;p&gt;The dependencies can be mapped in a directed graph representation: &lt;/p&gt;
0971 &lt;ul&gt;
0972 &lt;li&gt;Words are the nodes.&lt;/li&gt;
0973 &lt;li&gt;The grammatical relationships are the edges.&lt;/li&gt;
0974 &lt;/ul&gt;
0975 &lt;p&gt;Dependency parsing helps you know what role a word plays in the text and how different words relate to each other. It&amp;rsquo;s also used in &lt;strong&gt;shallow parsing&lt;/strong&gt; and named entity recognition.&lt;/p&gt;
0976 &lt;p&gt;Here&amp;rsquo;s how you can use dependency parsing to see the relationships between words:&lt;/p&gt;
0977 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;piano_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Gus is learning piano&amp;#39;&lt;/span&gt;
0978 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;piano_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;piano_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0979 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;piano_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
0980 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dep_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0981 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
0982 &lt;span class=&quot;go&quot;&gt;Gus NNP learning nsubj&lt;/span&gt;
0983 &lt;span class=&quot;go&quot;&gt;is VBZ learning aux&lt;/span&gt;
0984 &lt;span class=&quot;go&quot;&gt;learning VBG learning ROOT&lt;/span&gt;
0985 &lt;span class=&quot;go&quot;&gt;piano NN learning dobj&lt;/span&gt;
0986 &lt;/pre&gt;&lt;/div&gt;
0987 
0988 &lt;p&gt;In this example, the sentence contains three relationships:&lt;/p&gt;
0989 &lt;ol&gt;
0990 &lt;li&gt;&lt;strong&gt;&lt;code&gt;nsubj&lt;/code&gt;&lt;/strong&gt; is the subject of the word. Its headword is a verb.&lt;/li&gt;
0991 &lt;li&gt;&lt;strong&gt;&lt;code&gt;aux&lt;/code&gt;&lt;/strong&gt; is an auxiliary word. Its headword is a verb.&lt;/li&gt;
0992 &lt;li&gt;&lt;strong&gt;&lt;code&gt;dobj&lt;/code&gt;&lt;/strong&gt; is the direct object of the verb. Its headword is a verb.&lt;/li&gt;
0993 &lt;/ol&gt;
0994 &lt;p&gt;There is a detailed &lt;a href=&quot;https://nlp.stanford.edu/software/dependencies_manual.pdf&quot;&gt;list of relationships&lt;/a&gt; with descriptions. You can use displaCy to visualize the dependency tree:&lt;/p&gt;
0995 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;displacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;piano_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;dep&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
0996 &lt;/pre&gt;&lt;/div&gt;
0997 
0998 &lt;p&gt;This code will produce a visualization that can be accessed by opening &lt;a href=&quot;http://127.0.0.1:5000&quot;&gt;http://127.0.0.1:5000&lt;/a&gt; in your browser:&lt;/p&gt;
0999 &lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/displacy_dependency_parse.de72f9b1d115.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/displacy_dependency_parse.de72f9b1d115.png&quot; width=&quot;1278&quot; height=&quot;596&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/displacy_dependency_parse.de72f9b1d115.png&amp;amp;w=319&amp;amp;sig=111728c07cf2e1f64b8419cfce8a5f880c244d03 319w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/displacy_dependency_parse.de72f9b1d115.png&amp;amp;w=639&amp;amp;sig=f90a72529d7bc2d2dd944af3c02bbf487b65aaf3 639w, https://files.realpython.com/media/displacy_dependency_parse.de72f9b1d115.png 1278w&quot; sizes=&quot;75vw&quot; alt=&quot;Displacy: Dependency Parse Demo&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;displaCy: Dependency Parse Demo&lt;/figcaption&gt;&lt;/figure&gt;
1000 
1001 &lt;p&gt;This image shows you that the subject of the sentence is the proper noun &lt;code&gt;Gus&lt;/code&gt; and that it has a &lt;code&gt;learn&lt;/code&gt; relationship with &lt;code&gt;piano&lt;/code&gt;.&lt;/p&gt;
1002 &lt;h2 id=&quot;navigating-the-tree-and-subtree&quot;&gt;Navigating the Tree and Subtree&lt;/h2&gt;
1003 &lt;p&gt;The dependency parse tree has all the properties of a &lt;a href=&quot;https://en.wikipedia.org/wiki/Tree_(data_structure)&quot;&gt;tree&lt;/a&gt;. This tree contains information about sentence structure and grammar and can be traversed in different ways to extract relationships.&lt;/p&gt;
1004 &lt;p&gt;spaCy provides attributes like &lt;code&gt;children&lt;/code&gt;, &lt;code&gt;lefts&lt;/code&gt;, &lt;code&gt;rights&lt;/code&gt;, and &lt;code&gt;subtree&lt;/code&gt; to navigate the parse tree:&lt;/p&gt;
1005 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;one_line_about_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Gus Proto is a Python developer&amp;#39;&lt;/span&gt;
1006 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; currently working for a London-based Fintech company&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1007 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;one_line_about_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;one_line_about_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1008 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Extract children of `developer`&lt;/span&gt;
1009 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;one_line_about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
1010 &lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;Python&amp;#39;, &amp;#39;working&amp;#39;]&lt;/span&gt;
1011 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Extract previous neighboring node of `developer`&lt;/span&gt;
1012 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;one_line_about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nbor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
1013 &lt;span class=&quot;go&quot;&gt;Python&lt;/span&gt;
1014 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Extract next neighboring node of `developer`&lt;/span&gt;
1015 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;one_line_about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nbor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
1016 &lt;span class=&quot;go&quot;&gt;currently&lt;/span&gt;
1017 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Extract all tokens on the left of `developer`&lt;/span&gt;
1018 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;one_line_about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lefts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
1019 &lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;Python&amp;#39;]&lt;/span&gt;
1020 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Extract tokens on the right of `developer`&lt;/span&gt;
1021 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;one_line_about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rights&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
1022 &lt;span class=&quot;go&quot;&gt;[&amp;#39;working&amp;#39;]&lt;/span&gt;
1023 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Print subtree of `developer`&lt;/span&gt;
1024 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;one_line_about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subtree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
1025 &lt;span class=&quot;go&quot;&gt;[a, Python, developer, currently, working, for, a, London, -,&lt;/span&gt;
1026 &lt;span class=&quot;go&quot;&gt;based, Fintech, company]&lt;/span&gt;
1027 &lt;/pre&gt;&lt;/div&gt;
1028 
1029 &lt;p&gt;You can construct a function that takes a subtree as an argument and returns a string by merging words in it:&lt;/p&gt;
1030 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;flatten_tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1031 &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;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text_with_ws&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
1032 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
1033 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Print flattened subtree of `developer`&lt;/span&gt;
1034 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatten_tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;one_line_about_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subtree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
1035 &lt;span class=&quot;go&quot;&gt;a Python developer currently working for a London-based Fintech company&lt;/span&gt;
1036 &lt;/pre&gt;&lt;/div&gt;
1037 
1038 &lt;p&gt;You can use this function to print all the tokens in a subtree.&lt;/p&gt;
1039 &lt;h2 id=&quot;shallow-parsing&quot;&gt;Shallow Parsing&lt;/h2&gt;
1040 &lt;p&gt;&lt;strong&gt;Shallow parsing&lt;/strong&gt;, or &lt;strong&gt;chunking&lt;/strong&gt;, is the process of extracting phrases from unstructured text. Chunking groups adjacent tokens into phrases on the basis of their POS tags. There are some standard well-known chunks such as noun phrases, verb phrases, and prepositional phrases.&lt;/p&gt;
1041 &lt;h3 id=&quot;noun-phrase-detection&quot;&gt;Noun Phrase Detection&lt;/h3&gt;
1042 &lt;p&gt;A noun phrase is a phrase that has a noun as its head. It could also include other kinds of words, such as adjectives, ordinals, determiners. Noun phrases are useful for explaining the context of the sentence. They help you infer &lt;em&gt;what&lt;/em&gt; is being talked about in the sentence.&lt;/p&gt;
1043 &lt;p&gt;spaCy has the property &lt;code&gt;noun_chunks&lt;/code&gt; on &lt;code&gt;Doc&lt;/code&gt; object. You can use it to extract noun phrases:&lt;/p&gt;
1044 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conference_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;There is a developer conference&amp;#39;&lt;/span&gt;
1045 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; happening on 21 July 2019 in London.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1046 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conference_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conference_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1047 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Extract Noun Phrases&lt;/span&gt;
1048 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conference_doc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;noun_chunks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1049 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1050 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
1051 &lt;span class=&quot;go&quot;&gt;a developer conference&lt;/span&gt;
1052 &lt;span class=&quot;go&quot;&gt;21 July&lt;/span&gt;
1053 &lt;span class=&quot;go&quot;&gt;London&lt;/span&gt;
1054 &lt;/pre&gt;&lt;/div&gt;
1055 
1056 &lt;p&gt;By looking at noun phrases, you can get information about your text. For example, &lt;code&gt;a developer conference&lt;/code&gt; indicates that the text mentions a conference, while the date &lt;code&gt;21 July&lt;/code&gt; lets you know that conference is scheduled for &lt;code&gt;21 July&lt;/code&gt;. You can figure out whether the conference is in the past or the future. &lt;code&gt;London&lt;/code&gt; tells you that the conference is in &lt;code&gt;London&lt;/code&gt;.&lt;/p&gt;
1057 &lt;h3 id=&quot;verb-phrase-detection&quot;&gt;Verb Phrase Detection&lt;/h3&gt;
1058 &lt;p&gt;A &lt;strong&gt;verb phrase&lt;/strong&gt; is a syntactic unit composed of at least one verb. This verb can be followed by other chunks, such as noun phrases. Verb phrases are useful for understanding the actions that nouns are involved in. &lt;/p&gt;
1059 &lt;p&gt;spaCy has no built-in functionality to extract verb phrases, so you&amp;rsquo;ll need a library called &lt;a href=&quot;https://chartbeat-labs.github.io/textacy/&quot;&gt;&lt;code&gt;textacy&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
1060 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
1061 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;/p&gt;
1062 &lt;p&gt;You can use &lt;code&gt;pip&lt;/code&gt; to install &lt;code&gt;textacy&lt;/code&gt;:&lt;/p&gt;
1063 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; pip install textacy
1064 &lt;/pre&gt;&lt;/div&gt;
1065 
1066 &lt;/div&gt;
1067 &lt;p&gt;Now that you have &lt;code&gt;textacy&lt;/code&gt; installed, you can use it to extract verb phrases based on grammar rules:&lt;/p&gt;
1068 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;textacy&lt;/span&gt;
1069 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_talk_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;The talk will introduce reader about Use&amp;#39;&lt;/span&gt;
1070 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                   &lt;span class=&quot;s1&quot;&gt;&amp;#39; cases of Natural Language Processing in&amp;#39;&lt;/span&gt;
1071 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                   &lt;span class=&quot;s1&quot;&gt;&amp;#39; Fintech&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1072 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pattern&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;(&amp;lt;VERB&amp;gt;?&amp;lt;ADV&amp;gt;*&amp;lt;VERB&amp;gt;+)&amp;#39;&lt;/span&gt;
1073 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_talk_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_spacy_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_talk_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1074 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                        &lt;span class=&quot;n&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;en_core_web_sm&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1075 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;verb_phrases&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extract&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pos_regex_matches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;about_talk_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pattern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1076 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Print all Verb Phrase&lt;/span&gt;
1077 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;verb_phrases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1078 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1079 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
1080 &lt;span class=&quot;go&quot;&gt;will introduce&lt;/span&gt;
1081 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Extract Noun Phrase to explain what nouns are involved&lt;/span&gt;
1082 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;about_talk_doc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;noun_chunks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1083 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1084 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
1085 &lt;span class=&quot;go&quot;&gt;The talk&lt;/span&gt;
1086 &lt;span class=&quot;go&quot;&gt;reader&lt;/span&gt;
1087 &lt;span class=&quot;go&quot;&gt;Use cases&lt;/span&gt;
1088 &lt;span class=&quot;go&quot;&gt;Natural Language Processing&lt;/span&gt;
1089 &lt;span class=&quot;go&quot;&gt;Fintech&lt;/span&gt;
1090 &lt;/pre&gt;&lt;/div&gt;
1091 
1092 &lt;p&gt;In this example, the verb phrase &lt;code&gt;introduce&lt;/code&gt; indicates that something will be introduced. By looking at noun phrases, you can see that there is a &lt;code&gt;talk&lt;/code&gt; that will &lt;code&gt;introduce&lt;/code&gt; the &lt;code&gt;reader&lt;/code&gt; to &lt;code&gt;use cases&lt;/code&gt; of &lt;code&gt;Natural Language Processing&lt;/code&gt; or &lt;code&gt;Fintech&lt;/code&gt;.&lt;/p&gt;
1093 &lt;p&gt;The above code extracts all the verb phrases &lt;a href=&quot;https://chartbeat-labs.github.io/textacy/api_reference/information_extraction.html?highlight=pos#textacy.extract.pos_regex_matches&quot;&gt;using a regular expression pattern&lt;/a&gt; of POS tags. You can tweak the pattern for verb phrases depending upon your use case.&lt;/p&gt;
1094 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
1095 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In the previous example, you could have also done dependency parsing to see what the &lt;a href=&quot;https://nlp.stanford.edu/software/dependencies_manual.pdf&quot;&gt;relationships&lt;/a&gt; between the words were.&lt;/p&gt;
1096 &lt;/div&gt;
1097 &lt;h2 id=&quot;named-entity-recognition&quot;&gt;Named Entity Recognition&lt;/h2&gt;
1098 &lt;p&gt;&lt;strong&gt;Named Entity Recognition&lt;/strong&gt; (NER) is the process of locating &lt;strong&gt;named entities&lt;/strong&gt; in unstructured text and then classifying them into pre-defined categories, such as person names, organizations, locations, monetary values, percentages, time expressions, and so on.&lt;/p&gt;
1099 &lt;p&gt;You can use &lt;strong&gt;NER&lt;/strong&gt; to know more about the meaning of your text. For example, you could use it to populate tags for a set of documents in order to improve the keyword search. You could also use it to categorize customer support tickets into relevant categories.&lt;/p&gt;
1100 &lt;p&gt;spaCy has the property &lt;code&gt;ents&lt;/code&gt; on &lt;code&gt;Doc&lt;/code&gt; objects. You can use it to extract named entities:&lt;/p&gt;
1101 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;piano_class_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Great Piano Academy is situated&amp;#39;&lt;/span&gt;
1102 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; in Mayfair or the City of London and has&amp;#39;&lt;/span&gt;
1103 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39; world-class piano instructors.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1104 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;piano_class_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;piano_class_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1105 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ent&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;piano_class_doc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1106 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end_char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1107 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;          &lt;span class=&quot;n&quot;&gt;ent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;explain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
1108 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
1109 &lt;span class=&quot;go&quot;&gt;Great Piano Academy 0 19 ORG Companies, agencies, institutions, etc.&lt;/span&gt;
1110 &lt;span class=&quot;go&quot;&gt;Mayfair 35 42 GPE Countries, cities, states&lt;/span&gt;
1111 &lt;span class=&quot;go&quot;&gt;the City of London 46 64 GPE Countries, cities, states&lt;/span&gt;
1112 &lt;/pre&gt;&lt;/div&gt;
1113 
1114 &lt;p&gt;In the above example, &lt;code&gt;ent&lt;/code&gt; is a &lt;a href=&quot;https://spacy.io/api/span&quot;&gt;&lt;code&gt;Span&lt;/code&gt;&lt;/a&gt; object with various attributes:&lt;/p&gt;
1115 &lt;ul&gt;
1116 &lt;li&gt;&lt;strong&gt;&lt;code&gt;text&lt;/code&gt;&lt;/strong&gt; gives the Unicode text representation of the entity.&lt;/li&gt;
1117 &lt;li&gt;&lt;strong&gt;&lt;code&gt;start_char&lt;/code&gt;&lt;/strong&gt; denotes the character offset for the start of the entity.&lt;/li&gt;
1118 &lt;li&gt;&lt;strong&gt;&lt;code&gt;end_char&lt;/code&gt;&lt;/strong&gt; denotes the character offset for the end of the entity.&lt;/li&gt;
1119 &lt;li&gt;&lt;strong&gt;&lt;code&gt;label_&lt;/code&gt;&lt;/strong&gt; gives the label of the entity.&lt;/li&gt;
1120 &lt;/ul&gt;
1121 &lt;p&gt;&lt;code&gt;spacy.explain&lt;/code&gt; gives descriptive details about an entity label. The spaCy model has a pre-trained &lt;a href=&quot;https://spaCy.io/api/annotation#named-entities&quot;&gt;list of entity classes&lt;/a&gt;. You can use displaCy to visualize these entities:&lt;/p&gt;
1122 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;displacy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;piano_class_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ent&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1123 &lt;/pre&gt;&lt;/div&gt;
1124 
1125 &lt;p&gt;If you open &lt;a href=&quot;http://127.0.0.1:5000&quot;&gt;http://127.0.0.1:5000&lt;/a&gt; in your browser, then you can see the visualization:&lt;/p&gt;
1126 &lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/displacy_ner.1fba6869638f.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/displacy_ner.1fba6869638f.png&quot; width=&quot;1930&quot; height=&quot;140&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/displacy_ner.1fba6869638f.png&amp;amp;w=482&amp;amp;sig=18b93b0aed61930a6eedd37dbd12fbbce22733d4 482w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/displacy_ner.1fba6869638f.png&amp;amp;w=965&amp;amp;sig=f6b3cfb460053397a23a0eb49ebc22cf05dd15ab 965w, https://files.realpython.com/media/displacy_ner.1fba6869638f.png 1930w&quot; sizes=&quot;75vw&quot; alt=&quot;Displacy: Named Entity Recognition Demo&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;displaCy: Named Entity Recognition Demo&lt;/figcaption&gt;&lt;/figure&gt;
1127 
1128 &lt;p&gt;You can use NER to redact people&amp;rsquo;s names from a text. For example, you might want to do this in order to hide personal information collected in a survey. You can use spaCy to do that:&lt;/p&gt;
1129 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;survey_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Out of 5 people surveyed, James Robert,&amp;#39;&lt;/span&gt;
1130 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;               &lt;span class=&quot;s1&quot;&gt;&amp;#39; Julie Fuller and Benjamin Brooks like&amp;#39;&lt;/span&gt;
1131 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;               &lt;span class=&quot;s1&quot;&gt;&amp;#39; apples. Kelly Cox and Matthew Evans&amp;#39;&lt;/span&gt;
1132 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;               &lt;span class=&quot;s1&quot;&gt;&amp;#39; like oranges.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1133 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
1134 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;replace_person_names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1135 &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;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ent_iob&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ent_type_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;PERSON&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1136 &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;s1&quot;&gt;&amp;#39;[REDACTED] &amp;#39;&lt;/span&gt;
1137 &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;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;
1138 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
1139 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;redact_names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nlp_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1140 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ent&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp_doc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1141 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;ent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;merge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
1142 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;tokens&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace_person_names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1143 &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;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1144 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
1145 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;survey_doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nlp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;survey_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1146 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redact_names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;survey_doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1147 &lt;span class=&quot;go&quot;&gt;&amp;#39;Out of 5 people surveyed, [REDACTED] , [REDACTED] and&amp;#39;&lt;/span&gt;
1148 &lt;span class=&quot;go&quot;&gt;&amp;#39; [REDACTED] like apples. [REDACTED] and [REDACTED]&amp;#39;&lt;/span&gt;
1149 &lt;span class=&quot;go&quot;&gt;&amp;#39; like oranges.&amp;#39;&lt;/span&gt;
1150 &lt;/pre&gt;&lt;/div&gt;
1151 
1152 &lt;p&gt;In this example, &lt;code&gt;replace_person_names()&lt;/code&gt; uses &lt;code&gt;ent_iob&lt;/code&gt;. It gives the IOB code of the named entity tag using &lt;a href=&quot;https://en.wikipedia.org/wiki/Inside%E2%80%93outside%E2%80%93beginning_(tagging)&quot;&gt;inside-outside-beginning (IOB) tagging&lt;/a&gt;. Here, it can assume a value other than zero, because zero means that no entity tag is set.&lt;/p&gt;
1153 &lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
1154 &lt;p&gt;spaCy is a powerful and advanced library that is gaining huge popularity for NLP applications due to its speed, ease of use, accuracy, and extensibility. Congratulations! You now know:&lt;/p&gt;
1155 &lt;ul&gt;
1156 &lt;li&gt;What the foundational terms and concepts in NLP are&lt;/li&gt;
1157 &lt;li&gt;How to implement those concepts in spaCy&lt;/li&gt;
1158 &lt;li&gt;How to customize and extend built-in functionalities in spaCy&lt;/li&gt;
1159 &lt;li&gt;How to perform basic statistical analysis on a text&lt;/li&gt;
1160 &lt;li&gt;How to create a pipeline to process unstructured text&lt;/li&gt;
1161 &lt;li&gt;How to parse a sentence and extract meaningful insights from it&lt;/li&gt;
1162 &lt;/ul&gt;
1163         &lt;hr /&gt;
1164         &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;
1165       </content>
1166     </entry>
1167   
1168     <entry>
1169       <title>PyCharm for Productive Python Development (Guide)</title>
1170       <id>https://realpython.com/pycharm-guide/</id>
1171       <link href="https://realpython.com/pycharm-guide/"/>
1172       <updated>2019-08-28T14:00:00+00:00</updated>
1173       <summary>In this step-by-step tutorial, you&#39;ll learn how you can use PyCharm to be a more productive Python developer. PyCharm makes debugging and visualization easy so you can focus on business logic and just get the job done.</summary>
1174       <content type="html">
1175         &lt;p&gt;As a programmer, you should be focused on the business logic and creating useful applications for your users. In doing that, &lt;a href=&quot;https://www.jetbrains.com/pycharm/&quot;&gt;PyCharm&lt;/a&gt; by &lt;a href=&quot;https://www.jetbrains.com/&quot;&gt;JetBrains&lt;/a&gt; saves you a lot of time by taking care of the routine and by making a number of other tasks such as debugging and visualization easy.   &lt;/p&gt;
1176 &lt;p&gt;&lt;strong&gt;In this article, you&amp;rsquo;ll learn about:&lt;/strong&gt;&lt;/p&gt;
1177 &lt;ul&gt;
1178 &lt;li&gt;Installing PyCharm&lt;/li&gt;
1179 &lt;li&gt;Writing code in PyCharm&lt;/li&gt;
1180 &lt;li&gt;Running your code in PyCharm&lt;/li&gt;
1181 &lt;li&gt;Debugging and testing your code in PyCharm&lt;/li&gt;
1182 &lt;li&gt;Editing an existing project in PyCharm&lt;/li&gt;
1183 &lt;li&gt;Searching and navigating in PyCharm&lt;/li&gt;
1184 &lt;li&gt;Using Version Control in PyCharm&lt;/li&gt;
1185 &lt;li&gt;Using Plugins and External Tools in PyCharm&lt;/li&gt;
1186 &lt;li&gt;Using PyCharm Professional features, such as Django support and Scientific mode&lt;/li&gt;
1187 &lt;/ul&gt;
1188 &lt;p&gt;This article assumes that you&amp;rsquo;re familiar with Python development and already have some form of Python installed on your system. Python 3.6 will be used for this tutorial. Screenshots and demos provided are for macOS. Because PyCharm runs on all major platforms, you may see slightly different UI elements and may need to modify certain commands.&lt;/p&gt;
1189 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
1190 &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;/p&gt;
1191 &lt;p&gt;PyCharm comes in three editions: &lt;/p&gt;
1192 &lt;ol&gt;
1193 &lt;li&gt;&lt;a href=&quot;https://www.jetbrains.com/pycharm-edu/&quot;&gt;PyCharm Edu&lt;/a&gt; is free and for educational purposes.  &lt;/li&gt;
1194 &lt;li&gt;&lt;a href=&quot;https://www.jetbrains.com/pycharm&quot;&gt;PyCharm Community&lt;/a&gt; is free as well and intended for pure Python development. &lt;/li&gt;
1195 &lt;li&gt;&lt;a href=&quot;https://www.jetbrains.com/pycharm&quot;&gt;PyCharm Professional&lt;/a&gt; is paid, has everything the Community edition has and also is very well suited for Web and Scientific development with support for such frameworks as Django and Flask, Database and SQL, and scientific tools such as Jupyter.&lt;/li&gt;
1196 &lt;/ol&gt;
1197 &lt;p&gt;For more details on their differences, check out the &lt;a href=&quot;https://www.jetbrains.com/pycharm/features/editions_comparison_matrix.html&quot;&gt;PyCharm Editions Comparison Matrix&lt;/a&gt; by JetBrains. The company also has &lt;a href=&quot;https://www.jetbrains.com/pycharm/buy/#edition=discounts&quot;&gt;special offers&lt;/a&gt; for students, teachers, open source projects, and other cases.&lt;/p&gt;
1198 &lt;/div&gt;
1199 &lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Clone Repo:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/alcazar-web-framework/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-alcazar-web-framework&quot; data-focus=&quot;false&quot;&gt;Click here to clone the repo you&#39;ll use&lt;/a&gt; to explore the project-focused features of PyCharm in this tutorial.&lt;/p&gt;&lt;/div&gt;
1200 
1201 &lt;h2 id=&quot;installing-pycharm&quot;&gt;Installing PyCharm&lt;/h2&gt;
1202 &lt;p&gt;This article will use PyCharm Community Edition 2019.1 as it&amp;rsquo;s free and available on every major platform. Only the section about the professional features will use PyCharm Professional Edition 2019.1.  &lt;/p&gt;
1203 &lt;p&gt;The recommended way of installing PyCharm is with the &lt;a href=&quot;https://www.jetbrains.com/toolbox/app/&quot;&gt;JetBrains Toolbox App&lt;/a&gt;. With its help, you&amp;rsquo;ll be able to install different JetBrains products or several versions of the same product, update, rollback, and easily remove any tool when necessary. You&amp;rsquo;ll also be able to quickly open any project in the right IDE and version.&lt;/p&gt;
1204 &lt;p&gt;To install the Toolbox App, refer to the &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/installation-guide.html#toolbox&quot;&gt;documentation&lt;/a&gt; by JetBrains. It will automatically give you the right instructions depending on your OS. In case it didn&amp;rsquo;t recognize your OS correctly, you can always find it from the drop down list on the top right section: &lt;/p&gt;
1205 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-jetbrains-os-list.231740335aaa.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-jetbrains-os-list.231740335aaa.png&quot; width=&quot;1010&quot; height=&quot;679&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-jetbrains-os-list.231740335aaa.png&amp;amp;w=252&amp;amp;sig=e331b2eb15a3c8b9396327dedc700bd2bcbbc9e3 252w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-jetbrains-os-list.231740335aaa.png&amp;amp;w=505&amp;amp;sig=4a0a0527b968050fb042a0565f5d6970d72ee1f9 505w, https://files.realpython.com/media/pycharm-jetbrains-os-list.231740335aaa.png 1010w&quot; sizes=&quot;75vw&quot; alt=&quot;List of OSes in the JetBrains website&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1206 &lt;p&gt;After installing, launch the app and accept the user agreement. Under the &lt;em&gt;Tools&lt;/em&gt; tab, you&amp;rsquo;ll see a list of available products. Find PyCharm Community there and click &lt;em&gt;Install&lt;/em&gt;:&lt;/p&gt;
1207 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-toolbox-installed-pycharm.cdcf1b52bc02.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border w-33&quot; src=&quot;https://files.realpython.com/media/pycharm-toolbox-installed-pycharm.cdcf1b52bc02.png&quot; width=&quot;337&quot; height=&quot;537&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-toolbox-installed-pycharm.cdcf1b52bc02.png&amp;amp;w=84&amp;amp;sig=5f1e571c6c7bed958efddaec87d6ac5168713217 84w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-toolbox-installed-pycharm.cdcf1b52bc02.png&amp;amp;w=168&amp;amp;sig=0a76111939657ae01eaa8203b24c0c2e4fff5ee6 168w, https://files.realpython.com/media/pycharm-toolbox-installed-pycharm.cdcf1b52bc02.png 337w&quot; sizes=&quot;75vw&quot; alt=&quot;PyCharm installed with the Toolbox app&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1208 &lt;p&gt;Voilà! You have PyCharm available on your machine. If you don&amp;rsquo;t want to use the Toolbox app, then you can also do a &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/installation-guide.html#standalone&quot;&gt;stand-alone installation of PyCharm&lt;/a&gt;.&lt;/p&gt;
1209 &lt;p&gt;Launch PyCharm, and you&amp;rsquo;ll see the import settings popup:&lt;/p&gt;
1210 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-import-settings-popup.4e360260c697.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/pycharm-import-settings-popup.4e360260c697.png&quot; width=&quot;416&quot; height=&quot;156&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-import-settings-popup.4e360260c697.png&amp;amp;w=104&amp;amp;sig=4920753cc035f162c505253937453e1aa7cc4d26 104w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-import-settings-popup.4e360260c697.png&amp;amp;w=208&amp;amp;sig=b65b1226bcc172a811d7cd1e00cd600408fba092 208w, https://files.realpython.com/media/pycharm-import-settings-popup.4e360260c697.png 416w&quot; sizes=&quot;75vw&quot; alt=&quot;PyCharm Import Settings Popup&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1211 &lt;p&gt;PyCharm will automatically detect that this is a fresh install and choose &lt;em&gt;Do not import settings&lt;/em&gt; for you. Click &lt;em&gt;OK&lt;/em&gt;, and PyCharm will ask you to select a keymap scheme. Leave the default and click &lt;em&gt;Next: UI Themes&lt;/em&gt; on the bottom right:&lt;/p&gt;
1212 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-keymap-scheme.c8115fda9bdd.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/pycharm-keymap-scheme.c8115fda9bdd.png&quot; width=&quot;805&quot; height=&quot;666&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-keymap-scheme.c8115fda9bdd.png&amp;amp;w=201&amp;amp;sig=644595a94c07780a552f76abbfc5fe526b3c9459 201w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-keymap-scheme.c8115fda9bdd.png&amp;amp;w=402&amp;amp;sig=64c348872c1519bc4148e3dbbac2550ed6c0fa30 402w, https://files.realpython.com/media/pycharm-keymap-scheme.c8115fda9bdd.png 805w&quot; sizes=&quot;75vw&quot; alt=&quot;PyCharm Keymap Scheme&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1213 &lt;p&gt;PyCharm will then ask you to choose a dark theme called Darcula or a light theme. Choose whichever you prefer and click &lt;em&gt;Next: Launcher Script&lt;/em&gt;:  &lt;/p&gt;
1214 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-set-ui-theme.c48aac8e3fe0.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-set-ui-theme.c48aac8e3fe0.png&quot; width=&quot;803&quot; height=&quot;666&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-set-ui-theme.c48aac8e3fe0.png&amp;amp;w=200&amp;amp;sig=6998b85afd9e2ca1503624ba55b904f4051f1ffe 200w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-set-ui-theme.c48aac8e3fe0.png&amp;amp;w=401&amp;amp;sig=a6480f0b0073f0680068828fc2f0f5c8ee55cbdb 401w, https://files.realpython.com/media/pycharm-set-ui-theme.c48aac8e3fe0.png 803w&quot; sizes=&quot;75vw&quot; alt=&quot;PyCharm Set UI Theme Page&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1215 &lt;p&gt;I&amp;rsquo;ll be using the dark theme Darcula throughout this tutorial. You can find and install other themes as &lt;a href=&quot;#using-plugins-and-external-tools-in-pycharm&quot;&gt;plugins&lt;/a&gt;, or you can also &lt;a href=&quot;https://blog.codota.com/5-best-intellij-themes/&quot;&gt;import them&lt;/a&gt;.&lt;/p&gt;
1216 &lt;p&gt;On the next page, leave the defaults and click &lt;em&gt;Next: Featured plugins&lt;/em&gt;. There, PyCharm will show you a list of plugins you may want to install because most users like to use them. Click &lt;em&gt;Start using PyCharm&lt;/em&gt;, and now you are ready to write some code!&lt;/p&gt;
1217 &lt;h2 id=&quot;writing-code-in-pycharm&quot;&gt;Writing Code in PyCharm&lt;/h2&gt;
1218 &lt;p&gt;In PyCharm, you do everything in the context of a &lt;strong&gt;project&lt;/strong&gt;. Thus, the first thing you need to do is create one.&lt;/p&gt;
1219 &lt;p&gt;After installing and opening PyCharm, you are on the welcome screen. Click &lt;em&gt;Create New Project&lt;/em&gt;, and you&amp;rsquo;ll see the &lt;em&gt;New Project&lt;/em&gt; popup:&lt;/p&gt;
1220 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-new-project.cc35f3aa1056.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-new-project.cc35f3aa1056.png&quot; width=&quot;664&quot; height=&quot;480&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-new-project.cc35f3aa1056.png&amp;amp;w=166&amp;amp;sig=6423b68127eae8ca93165323df4884844265f5e3 166w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-new-project.cc35f3aa1056.png&amp;amp;w=332&amp;amp;sig=50d660be9a42904b1161bd76df1ab9ddd77e2132 332w, https://files.realpython.com/media/pycharm-new-project.cc35f3aa1056.png 664w&quot; sizes=&quot;75vw&quot; alt=&quot;New Project in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1221 &lt;p&gt;Specify the project location and expand the &lt;em&gt;Project Interpreter&lt;/em&gt; drop down. Here, you have options to create a new project interpreter or reuse an existing one. Choose &lt;em&gt;New environment using&lt;/em&gt;. Right next to it, you have a drop down list to select one of &lt;em&gt;Virtualenv&lt;/em&gt;, &lt;em&gt;Pipenv&lt;/em&gt;, or &lt;em&gt;Conda&lt;/em&gt;, which are the tools that help to keep dependencies required by different projects separate by creating isolated Python environments for them. &lt;/p&gt;
1222 &lt;p&gt;You are free to select whichever you like, but &lt;em&gt;Virtualenv&lt;/em&gt; is used for this tutorial. If you choose to, you can specify the environment location and choose the base interpreter from the list, which is a list of Python interpreters (such as Python2.7 and Python3.6) installed on your system. Usually, the defaults are fine. Then you have to select boxes to inherit global site-packages to your new environment and make it available to all other projects. Leave them unselected.  &lt;/p&gt;
1223 &lt;p&gt;Click &lt;em&gt;Create&lt;/em&gt; on the bottom right and you will see the new project created:&lt;/p&gt;
1224 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-project-created.99dffd1d4e9a.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-project-created.99dffd1d4e9a.png&quot; width=&quot;1174&quot; height=&quot;734&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-project-created.99dffd1d4e9a.png&amp;amp;w=293&amp;amp;sig=d6394f174acab8ee63eb6ce0360d0174857f7afb 293w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-project-created.99dffd1d4e9a.png&amp;amp;w=587&amp;amp;sig=2fd8ea44cc0ad15f015aab687018ec7ad8861a53 587w, https://files.realpython.com/media/pycharm-project-created.99dffd1d4e9a.png 1174w&quot; sizes=&quot;75vw&quot; alt=&quot;Project created in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1225 &lt;p&gt;You will also see a small &lt;em&gt;Tip of the Day&lt;/em&gt; popup where PyCharm gives you one trick to learn at each startup. Go ahead and close this popup.&lt;/p&gt;
1226 &lt;p&gt;It is now time to start a new Python program. Type &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-n&quot;&gt;N&lt;/kbd&gt;&lt;/span&gt; if you are on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-insert&quot;&gt;Ins&lt;/kbd&gt;&lt;/span&gt; if you are on Windows or Linux. Then, choose &lt;em&gt;Python File&lt;/em&gt;. You can also select &lt;em&gt;File → New&lt;/em&gt; from the menu. Name the new file &lt;code&gt;guess_game.py&lt;/code&gt; and click &lt;em&gt;OK&lt;/em&gt;. You will see a PyCharm window similar to the following:&lt;/p&gt;
1227 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-new-file.7ea9902d73ea.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-new-file.7ea9902d73ea.png&quot; width=&quot;1172&quot; height=&quot;734&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-new-file.7ea9902d73ea.png&amp;amp;w=293&amp;amp;sig=b1ee432e97d642aea67818cc7280971247196a62 293w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-new-file.7ea9902d73ea.png&amp;amp;w=586&amp;amp;sig=3563b00140a3edd3f1df0e522d5069f6efcb62d3 586w, https://files.realpython.com/media/pycharm-new-file.7ea9902d73ea.png 1172w&quot; sizes=&quot;75vw&quot; alt=&quot;PyCharm New File&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1228 &lt;p&gt;For our test code, let&amp;rsquo;s quickly code up a simple guessing game in which the program chooses a number that the user has to guess. For every guess, the program will tell if the user&amp;rsquo;s guess was smaller or bigger than the secret number. The game ends when the user guesses the number. Here&amp;rsquo;s the code for the game:&lt;/p&gt;
1229 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;
1230 &lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
1231 &lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
1232 &lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;random_int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1233 &lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;
1234 &lt;span class=&quot;lineno&quot;&gt; 6 &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;
1235 &lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;user_guess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;What number did we guess (0-100)?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
1236 &lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;
1237 &lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_guess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1238 &lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;You found the number (&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{random_int}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;). Congrats!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1239 &lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
1240 &lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;
1241 &lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_guess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1242 &lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Your number is less than the number we guessed.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1243 &lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
1244 &lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;
1245 &lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_guess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1246 &lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Your number is more than the number we guessed.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1247 &lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
1248 &lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;
1249 &lt;span class=&quot;lineno&quot;&gt;21 &lt;/span&gt;
1250 &lt;span class=&quot;lineno&quot;&gt;22 &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;s1&quot;&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1251 &lt;span class=&quot;lineno&quot;&gt;23 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
1252 &lt;/pre&gt;&lt;/div&gt;
1253 
1254 &lt;p&gt;Type this code directly rather than copying and pasting. You&amp;rsquo;ll see something like this:&lt;/p&gt;
1255 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/typing-guess-game.fcaedeb8ece2.gif&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/typing-guess-game.fcaedeb8ece2.gif&quot; width=&quot;528&quot; height=&quot;480&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/typing-guess-game.fcaedeb8ece2.gif&amp;amp;w=132&amp;amp;sig=7e5eb20fb9ae97b1cea80380f9ad00f35dd76707 132w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/typing-guess-game.fcaedeb8ece2.gif&amp;amp;w=264&amp;amp;sig=eb242bca301203a38741a986d7847cf0f3ef4cff 264w, https://files.realpython.com/media/typing-guess-game.fcaedeb8ece2.gif 528w&quot; sizes=&quot;75vw&quot; alt=&quot;Typing Guessing Game&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1256 &lt;p&gt;As you can see, PyCharm provides &lt;a href=&quot;https://www.jetbrains.com/pycharm/features/coding_assistance.html&quot;&gt;Intelligent Coding Assistance&lt;/a&gt; with code completion, code inspections, on-the-fly error highlighting, and quick-fix suggestions. In particular, note how when you typed &lt;code&gt;main&lt;/code&gt; and then hit tab, PyCharm auto-completed the whole &lt;code&gt;main&lt;/code&gt; clause for you. &lt;/p&gt;
1257 &lt;p&gt;Also note how, if you forget to type &lt;code&gt;if&lt;/code&gt; before the condition, append &lt;code&gt;.if&lt;/code&gt;, and then hit &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-tab&quot;&gt;Tab&lt;/kbd&gt;&lt;/span&gt;, PyCharm fixes the &lt;code&gt;if&lt;/code&gt; clause for you. The same is true with &lt;code&gt;True.while&lt;/code&gt;. That&amp;rsquo;s &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/settings-postfix-completion.html&quot;&gt;PyCharm&amp;rsquo;s Postfix completions&lt;/a&gt; working for you to help reduce backward caret jumps.&lt;/p&gt;
1258 &lt;h2 id=&quot;running-code-in-pycharm&quot;&gt;Running Code in PyCharm&lt;/h2&gt;
1259 &lt;p&gt;Now that you&amp;rsquo;ve coded up the game, it&amp;rsquo;s time for you to run it.&lt;/p&gt;
1260 &lt;p&gt;You have three ways of running this program:&lt;/p&gt;
1261 &lt;ol&gt;
1262 &lt;li&gt;Use the shortcut &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-r&quot;&gt;R&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-f10&quot;&gt;F10&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux.&lt;/li&gt;
1263 &lt;li&gt;Right-click the background and choose &lt;em&gt;Run &amp;lsquo;guess_game&amp;rsquo;&lt;/em&gt; from the menu.&lt;/li&gt;
1264 &lt;li&gt;Since this program has the &lt;code&gt;__main__&lt;/code&gt; clause, you can click on the little green arrow to the left of the &lt;code&gt;__main__&lt;/code&gt; clause and choose &lt;em&gt;Run &amp;lsquo;guess_game&amp;rsquo;&lt;/em&gt; from there.&lt;/li&gt;
1265 &lt;/ol&gt;
1266 &lt;p&gt;Use any one of the options above to run the program, and you&amp;rsquo;ll see the Run Tool pane appear at the bottom of the window, with your code output showing:&lt;/p&gt;
1267 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-running-script.33fb830f45b4.gif&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-running-script.33fb830f45b4.gif&quot; width=&quot;1068&quot; height=&quot;720&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-running-script.33fb830f45b4.gif&amp;amp;w=267&amp;amp;sig=44be962297881f8ae66557c19905a55202ee14de 267w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-running-script.33fb830f45b4.gif&amp;amp;w=534&amp;amp;sig=000552999cea7a9ce79eeec2f9db7361e9585d77 534w, https://files.realpython.com/media/pycharm-running-script.33fb830f45b4.gif 1068w&quot; sizes=&quot;75vw&quot; alt=&quot;Running a script in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1268 &lt;p&gt;Play the game for a little bit to see if you can find the number guessed. Pro tip: start with 50.   &lt;/p&gt;
1269 &lt;h2 id=&quot;debugging-in-pycharm&quot;&gt;Debugging in PyCharm&lt;/h2&gt;
1270 &lt;p&gt;Did you find the number? If so, you may have seen something weird after you found the number. Instead of printing the congratulations message and exiting, the program seems to start over. That&amp;rsquo;s a bug right there. To discover why the program starts over, you&amp;rsquo;ll now debug the program.&lt;/p&gt;
1271 &lt;p&gt;First, place a breakpoint by clicking on the blank space to the left of line number 8:&lt;/p&gt;
1272 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-debug-breakpoint.55cf93c49859.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-debug-breakpoint.55cf93c49859.png&quot; width=&quot;1042&quot; height=&quot;710&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-debug-breakpoint.55cf93c49859.png&amp;amp;w=260&amp;amp;sig=e714eeae34fad6c0e5889bee0f236f9c30e100a0 260w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-debug-breakpoint.55cf93c49859.png&amp;amp;w=521&amp;amp;sig=7c4692a273d49a627785a715fd0a08d4c8120649 521w, https://files.realpython.com/media/pycharm-debug-breakpoint.55cf93c49859.png 1042w&quot; sizes=&quot;75vw&quot; alt=&quot;Debug breakpoint in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1273 &lt;p&gt;This will be the point where the program will be suspended, and you can start exploring what went wrong from there on. Next, choose one of the following three ways to start debugging:&lt;/p&gt;
1274 &lt;ol&gt;
1275 &lt;li&gt;Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-d&quot;&gt;D&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-f9&quot;&gt;F9&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux.&lt;/li&gt;
1276 &lt;li&gt;Right-click the background and choose &lt;em&gt;Debug &amp;lsquo;guess_game&amp;rsquo;&lt;/em&gt;.&lt;/li&gt;
1277 &lt;li&gt;Click on the little green arrow to the left of the &lt;code&gt;__main__&lt;/code&gt; clause and choose &lt;em&gt;Debug &amp;lsquo;guess_game&lt;/em&gt; from there.&lt;/li&gt;
1278 &lt;/ol&gt;
1279 &lt;p&gt;Afterwards, you&amp;rsquo;ll see a &lt;em&gt;Debug&lt;/em&gt; window open at the bottom:&lt;/p&gt;
1280 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-debugging-start.04246b743469.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-debugging-start.04246b743469.png&quot; width=&quot;1043&quot; height=&quot;711&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-debugging-start.04246b743469.png&amp;amp;w=260&amp;amp;sig=cea78f8df9a7f183330e3610c90a2abeab879923 260w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-debugging-start.04246b743469.png&amp;amp;w=521&amp;amp;sig=6ae0fe4515cf7f0d52cbcda986eb9c52d0a602ee 521w, https://files.realpython.com/media/pycharm-debugging-start.04246b743469.png 1043w&quot; sizes=&quot;75vw&quot; alt=&quot;Start of debugging in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1281 &lt;p&gt;Follow the steps below to debug the program:&lt;/p&gt;
1282 &lt;ol&gt;
1283 &lt;li&gt;
1284 &lt;p&gt;Notice that the current line is highlighted in blue.&lt;/p&gt;
1285 &lt;/li&gt;
1286 &lt;li&gt;
1287 &lt;p&gt;See that &lt;code&gt;random_int&lt;/code&gt; and its value are listed in the Debug window. Make a note of this number. (In the picture, the number is 85.)&lt;/p&gt;
1288 &lt;/li&gt;
1289 &lt;li&gt;
1290 &lt;p&gt;Hit &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-f8&quot;&gt;F8&lt;/kbd&gt;&lt;/span&gt; to execute the current line and step &lt;em&gt;over&lt;/em&gt; to the next one. You can also use &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-f7&quot;&gt;F7&lt;/kbd&gt;&lt;/span&gt; to step &lt;em&gt;into&lt;/em&gt; the function in the current line, if necessary. As you continue executing the statements, the changes in the variables will be automatically reflected in the Debugger window.&lt;/p&gt;
1291 &lt;/li&gt;
1292 &lt;li&gt;
1293 &lt;p&gt;Notice that there is the Console tab right next to the Debugger tab that opened. This Console tab and the Debugger tab are mutually exclusive. In the Console tab, you will be interacting with your program, and in the Debugger tab you will do the debugging actions.&lt;/p&gt;
1294 &lt;/li&gt;
1295 &lt;li&gt;
1296 &lt;p&gt;Switch to the Console tab to enter your guess.&lt;/p&gt;
1297 &lt;/li&gt;
1298 &lt;li&gt;
1299 &lt;p&gt;Type the number shown, and then hit &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;.&lt;/p&gt;
1300 &lt;/li&gt;
1301 &lt;li&gt;
1302 &lt;p&gt;Switch back to the Debugger tab.&lt;/p&gt;
1303 &lt;/li&gt;
1304 &lt;li&gt;
1305 &lt;p&gt;Hit &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-f8&quot;&gt;F8&lt;/kbd&gt;&lt;/span&gt; again to evaluate the &lt;code&gt;if&lt;/code&gt; statement. Notice that you are now on line 14. But wait a minute! Why didn&amp;rsquo;t it go to the line 11? The reason is that the &lt;code&gt;if&lt;/code&gt; statement on line 10 evaluated to &lt;code&gt;False&lt;/code&gt;. But why did it evaluate to &lt;code&gt;False&lt;/code&gt; when you entered the number that was chosen?&lt;/p&gt;
1306 &lt;/li&gt;
1307 &lt;li&gt;
1308 &lt;p&gt;Look carefully at line 10 and notice that we are comparing &lt;code&gt;user_guess&lt;/code&gt; with the wrong thing. Instead of comparing it with &lt;code&gt;random_int&lt;/code&gt;, we are comparing it with &lt;code&gt;randint&lt;/code&gt;, the function that was imported from the &lt;code&gt;random&lt;/code&gt; package.&lt;/p&gt;
1309 &lt;/li&gt;
1310 &lt;li&gt;
1311 &lt;p&gt;Change it to &lt;code&gt;random_int&lt;/code&gt;, restart the debugging, and follow the same steps again. You will see that, this time, it will go to line 11, and line 10 will evaluate to &lt;code&gt;True&lt;/code&gt;:&lt;/p&gt;
1312 &lt;/li&gt;
1313 &lt;/ol&gt;
1314 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-debugging-scripts.bb5a077da438.gif&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-debugging-scripts.bb5a077da438.gif&quot; width=&quot;1092&quot; height=&quot;720&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-debugging-scripts.bb5a077da438.gif&amp;amp;w=273&amp;amp;sig=fc5de269fbc13ea5c1d8be4ca7f525e04a4bb68c 273w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-debugging-scripts.bb5a077da438.gif&amp;amp;w=546&amp;amp;sig=4719f69fd6e78ed3e68f16a9355d00d0edd85a26 546w, https://files.realpython.com/media/pycharm-debugging-scripts.bb5a077da438.gif 1092w&quot; sizes=&quot;75vw&quot; alt=&quot;Debugging Script in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1315 &lt;p&gt;Congratulations! You fixed the bug.&lt;/p&gt;
1316 &lt;h2 id=&quot;testing-in-pycharm&quot;&gt;Testing in PyCharm&lt;/h2&gt;
1317 &lt;p&gt;No application is reliable without unit tests. PyCharm helps you write and run them very quickly and comfortably. By default, &lt;a href=&quot;https://docs.python.org/3/library/unittest.html&quot;&gt;&lt;code&gt;unittest&lt;/code&gt;&lt;/a&gt; is used as the test runner, but PyCharm also supports other testing frameworks such as &lt;a href=&quot;http://www.pytest.org/en/latest/&quot;&gt;&lt;code&gt;pytest&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://nose.readthedocs.io/en/latest/&quot;&gt;&lt;code&gt;nose&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://docs.python.org/3/library/doctest.html&quot;&gt;&lt;code&gt;doctest&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/tox-support.html&quot;&gt;&lt;code&gt;tox&lt;/code&gt;&lt;/a&gt;, and &lt;a href=&quot;https://twistedmatrix.com/trac/wiki/TwistedTrial&quot;&gt;&lt;code&gt;trial&lt;/code&gt;&lt;/a&gt;. You can, for example, enable &lt;code&gt;pytest&lt;/code&gt; for your project like this:&lt;/p&gt;
1318 &lt;ol&gt;
1319 &lt;li&gt;Open the &lt;em&gt;Settings/Preferences → Tools → Python Integrated Tools&lt;/em&gt; settings dialog.&lt;/li&gt;
1320 &lt;li&gt;Select &lt;code&gt;pytest&lt;/code&gt; in the Default test runner field.&lt;/li&gt;
1321 &lt;li&gt;Click &lt;em&gt;OK&lt;/em&gt; to save the settings. &lt;/li&gt;
1322 &lt;/ol&gt;
1323 &lt;p&gt;For this example, we&amp;rsquo;ll be using the default test runner &lt;code&gt;unittest&lt;/code&gt;. &lt;/p&gt;
1324 &lt;p&gt;In the same project, create a file called &lt;code&gt;calculator.py&lt;/code&gt; and put the following &lt;code&gt;Calculator&lt;/code&gt; class in it:&lt;/p&gt;
1325 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1326 &lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add&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;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1327 &lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
1328 &lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;
1329 &lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;multiply&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;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1330 &lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
1331 &lt;/pre&gt;&lt;/div&gt;
1332 
1333 &lt;p&gt;PyCharm makes it very easy to create tests for your existing code. With the &lt;code&gt;calculator.py&lt;/code&gt; file open, execute any one of the following that you like:&lt;/p&gt;
1334 &lt;ul&gt;
1335 &lt;li&gt;Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-t&quot;&gt;T&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-t&quot;&gt;T&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux.&lt;/li&gt;
1336 &lt;li&gt;Right-click in the background of the class and then choose &lt;em&gt;Go To&lt;/em&gt; and &lt;em&gt;Test&lt;/em&gt;.&lt;/li&gt;
1337 &lt;li&gt;On the main menu, choose &lt;em&gt;Navigate → Test&lt;/em&gt;.&lt;/li&gt;
1338 &lt;/ul&gt;
1339 &lt;p&gt;Choose &lt;em&gt;Create New Test&amp;hellip;&lt;/em&gt;, and you will see the following window:&lt;/p&gt;
1340 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-create-tests.9a6cea78f9c6.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-create-tests.9a6cea78f9c6.png&quot; width=&quot;500&quot; height=&quot;402&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-create-tests.9a6cea78f9c6.png&amp;amp;w=125&amp;amp;sig=0c50b83f35578fd8004dce9e7d55fcd3b09a1967 125w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-create-tests.9a6cea78f9c6.png&amp;amp;w=250&amp;amp;sig=f6740142e71d2d2f6196ffbe341ae09bc9a64453 250w, https://files.realpython.com/media/pycharm-create-tests.9a6cea78f9c6.png 500w&quot; sizes=&quot;75vw&quot; alt=&quot;Create tests in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1341 &lt;p&gt;Leave the defaults of &lt;em&gt;Target directory&lt;/em&gt;, &lt;em&gt;Test file name&lt;/em&gt;, and &lt;em&gt;Test class name&lt;/em&gt;. Select both of the methods and click &lt;em&gt;OK&lt;/em&gt;. Voila! PyCharm automatically created a file called &lt;code&gt;test_calculator.py&lt;/code&gt; and created the following stub tests for you in it:&lt;/p&gt;
1342 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;unittest&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;
1343 &lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
1344 &lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1345 &lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_add&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;
1346 &lt;span class=&quot;lineno&quot;&gt; 5 &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;fail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
1347 &lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;
1348 &lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_multiply&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;
1349 &lt;span class=&quot;lineno&quot;&gt; 8 &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;fail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
1350 &lt;/pre&gt;&lt;/div&gt;
1351 
1352 &lt;p&gt;Run the tests using one of the methods below:&lt;/p&gt;
1353 &lt;ul&gt;
1354 &lt;li&gt;Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-r&quot;&gt;R&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-f10&quot;&gt;F10&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux.&lt;/li&gt;
1355 &lt;li&gt;Right-click the background and choose &lt;em&gt;Run &amp;lsquo;Unittests for test_calculator.py&amp;rsquo;&lt;/em&gt;.&lt;/li&gt;
1356 &lt;li&gt;Click on the little green arrow to the left of the test class name and choose &lt;em&gt;Run &amp;lsquo;Unittests for test_calculator.py&amp;rsquo;&lt;/em&gt;.&lt;/li&gt;
1357 &lt;/ul&gt;
1358 &lt;p&gt;You&amp;rsquo;ll see the tests window open on the bottom with all the tests failing:&lt;/p&gt;
1359 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-failed-tests.810aa9c365cb.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-failed-tests.810aa9c365cb.png&quot; width=&quot;972&quot; height=&quot;645&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-failed-tests.810aa9c365cb.png&amp;amp;w=243&amp;amp;sig=cb7ef285c20ed83b9771a91cc38d77342e4d3745 243w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-failed-tests.810aa9c365cb.png&amp;amp;w=486&amp;amp;sig=aaec55471da2d168048783b9c4e573f5ce876de4 486w, https://files.realpython.com/media/pycharm-failed-tests.810aa9c365cb.png 972w&quot; sizes=&quot;75vw&quot; alt=&quot;Failed tests in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1360 &lt;p&gt;Notice that you have the hierarchy of the test results on the left and the output of the terminal on the right. &lt;/p&gt;
1361 &lt;p&gt;Now, implement &lt;code&gt;test_add&lt;/code&gt; by changing the code to the following:&lt;/p&gt;
1362 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;unittest&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;
1363 &lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
1364 &lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Calculator&lt;/span&gt;
1365 &lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;
1366 &lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1367 &lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_add&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;
1368 &lt;span class=&quot;lineno&quot;&gt; 7 &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;calculator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
1369 &lt;span class=&quot;lineno&quot;&gt; 8 &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;assertEqual&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;calculator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1370 &lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;
1371 &lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_multiply&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;
1372 &lt;span class=&quot;lineno&quot;&gt;11 &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;fail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
1373 &lt;/pre&gt;&lt;/div&gt;
1374 
1375 &lt;p&gt;Run the tests again, and you&amp;rsquo;ll see that one test passed and the other failed. Explore the options to show passed tests, to show ignored tests, to sort tests alphabetically, and to sort tests by duration:&lt;/p&gt;
1376 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-running-tests.6077562207ba.gif&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-running-tests.6077562207ba.gif&quot; width=&quot;1092&quot; height=&quot;720&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-running-tests.6077562207ba.gif&amp;amp;w=273&amp;amp;sig=e2238425e1cfb9a9a298741244f3021f3984dbf8 273w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-running-tests.6077562207ba.gif&amp;amp;w=546&amp;amp;sig=85203afd5ff2189fdfadad0960da514b03063953 546w, https://files.realpython.com/media/pycharm-running-tests.6077562207ba.gif 1092w&quot; sizes=&quot;75vw&quot; alt=&quot;Running tests in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1377 &lt;p&gt;Note that the &lt;code&gt;sleep(0.1)&lt;/code&gt; method that you see in the GIF above is intentionally used to make one of the tests slower so that sorting by duration works. &lt;/p&gt;
1378 &lt;h2 id=&quot;editing-an-existing-project-in-pycharm&quot;&gt;Editing an Existing Project in PyCharm&lt;/h2&gt;
1379 &lt;p&gt;These single file projects are great for examples, but you&amp;rsquo;ll often work on much larger projects over a longer period of time. In this section, you&amp;rsquo;ll take a look at how PyCharm works with a larger project. &lt;/p&gt;
1380 &lt;p&gt;To explore the project-focused features of PyCharm, you&amp;rsquo;ll use the Alcazar web framework that was built for learning purposes. To continue following along, clone the repo locally:&lt;/p&gt;
1381 &lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Clone Repo:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/alcazar-web-framework/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-alcazar-web-framework&quot; data-focus=&quot;false&quot;&gt;Click here to clone the repo you&#39;ll use&lt;/a&gt; to explore the project-focused features of PyCharm in this tutorial.&lt;/p&gt;&lt;/div&gt;
1382 
1383 &lt;p&gt;Once you have a project locally, open it in PyCharm using one of the following methods:&lt;/p&gt;
1384 &lt;ul&gt;
1385 &lt;li&gt;Click &lt;em&gt;File → Open&lt;/em&gt; on the main menu.&lt;/li&gt;
1386 &lt;li&gt;Click &lt;em&gt;Open&lt;/em&gt; on the &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/welcome-screen.html&quot;&gt;Welcome Screen&lt;/a&gt; if you are there.&lt;/li&gt;
1387 &lt;/ul&gt;
1388 &lt;p&gt;After either of these steps, find the folder containing the project on your computer and open it.&lt;/p&gt;
1389 &lt;p&gt;If this project contains a &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;virtual environment&lt;/a&gt;, then PyCharm will automatically use this virtual environment and make it the project interpreter.&lt;/p&gt;
1390 &lt;p&gt;If you need to configure a different &lt;code&gt;virtualenv&lt;/code&gt;, then open &lt;em&gt;Preferences&lt;/em&gt; on Mac by pressing &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-comma&quot;&gt;,&lt;/kbd&gt;&lt;/span&gt; or &lt;em&gt;Settings&lt;/em&gt; on Windows or Linux by pressing &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-s&quot;&gt;S&lt;/kbd&gt;&lt;/span&gt; and find the &lt;em&gt;Project: ProjectName&lt;/em&gt; section. Open the drop-down and choose &lt;em&gt;Project Interpreter&lt;/em&gt;:&lt;/p&gt;
1391 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-project-interpreter.57282306555a.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-project-interpreter.57282306555a.png&quot; width=&quot;1083&quot; height=&quot;723&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-project-interpreter.57282306555a.png&amp;amp;w=270&amp;amp;sig=286643bc473f648bbcce27338c980eb023746ac2 270w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-project-interpreter.57282306555a.png&amp;amp;w=541&amp;amp;sig=6d33c5adf0380e8c5b01ae9430436983580b4b49 541w, https://files.realpython.com/media/pycharm-project-interpreter.57282306555a.png 1083w&quot; sizes=&quot;75vw&quot; alt=&quot;Project interpreter in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1392 &lt;p&gt;Choose the &lt;code&gt;virtualenv&lt;/code&gt; from the drop-down list. If it&amp;rsquo;s not there, then click on the settings button to the right of the drop-down list and then choose &lt;em&gt;Add&amp;hellip;&lt;/em&gt;. The rest of the steps should be the same as when we were &lt;a href=&quot;#writing-code-in-pycharm&quot;&gt;creating a new project&lt;/a&gt;.&lt;/p&gt;
1393 &lt;h2 id=&quot;searching-and-navigating-in-pycharm&quot;&gt;Searching and Navigating in PyCharm&lt;/h2&gt;
1394 &lt;p&gt;In a big project where it&amp;rsquo;s difficult for a single person to remember where everything is located, it&amp;rsquo;s very important to be able to quickly navigate and find what you looking for. PyCharm has you covered here as well. Use the project you opened in the section above to practice these shortcuts: &lt;/p&gt;
1395 &lt;ul&gt;
1396 &lt;li&gt;&lt;strong&gt;Searching for a fragment in the current file:&lt;/strong&gt; Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-f&quot;&gt;F&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-f&quot;&gt;F&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux.&lt;/li&gt;
1397 &lt;li&gt;&lt;strong&gt;Searching for a fragment in the entire project:&lt;/strong&gt; Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-f&quot;&gt;F&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-f&quot;&gt;F&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux.&lt;/li&gt;
1398 &lt;li&gt;&lt;strong&gt;Searching for a class:&lt;/strong&gt; Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-o&quot;&gt;O&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-n&quot;&gt;N&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux.&lt;/li&gt;
1399 &lt;li&gt;&lt;strong&gt;Searching for a file:&lt;/strong&gt; Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-o&quot;&gt;O&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-n&quot;&gt;N&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux.&lt;/li&gt;
1400 &lt;li&gt;&lt;strong&gt;Searching all if you don&amp;rsquo;t know whether it&amp;rsquo;s a file, class, or a code fragment that you are looking for:&lt;/strong&gt; Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;/span&gt; twice.&lt;/li&gt;
1401 &lt;/ul&gt;
1402 &lt;p&gt;As for the navigation, the following shortcuts may save you a lot of time:&lt;/p&gt;
1403 &lt;ul&gt;
1404 &lt;li&gt;&lt;strong&gt;Going to the declaration of a variable:&lt;/strong&gt; Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux, and click on the variable.&lt;/li&gt;
1405 &lt;li&gt;&lt;strong&gt;Finding usages of a class, a method, or any symbol:&lt;/strong&gt; Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-f7&quot;&gt;F7&lt;/kbd&gt;&lt;/span&gt;.&lt;/li&gt;
1406 &lt;li&gt;&lt;strong&gt;Seeing your recent changes:&lt;/strong&gt; Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-c&quot;&gt;C&lt;/kbd&gt;&lt;/span&gt; or go to &lt;em&gt;View → Recent Changes&lt;/em&gt; on the main menu.&lt;/li&gt;
1407 &lt;li&gt;&lt;strong&gt;Seeing your recent files:&lt;/strong&gt; Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-e&quot;&gt;E&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-e&quot;&gt;E&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux, or go to &lt;em&gt;View → Recent Files&lt;/em&gt; on the main menu.&lt;/li&gt;
1408 &lt;li&gt;&lt;strong&gt;Going backward and forward through your history of navigation after you jumped around:&lt;/strong&gt; Press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-bracket-left&quot;&gt;[&lt;/kbd&gt;&lt;/span&gt; / &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-bracket-right&quot;&gt;]&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-arrow-left&quot;&gt;Left&lt;/kbd&gt;&lt;/span&gt; / &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-arrow-right&quot;&gt;Right&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux.&lt;/li&gt;
1409 &lt;/ul&gt;
1410 &lt;p&gt;For more details, see the &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/tutorial-exploring-navigation-and-search.html&quot;&gt;official documentation&lt;/a&gt;. &lt;/p&gt;
1411 &lt;h2 id=&quot;using-version-control-in-pycharm&quot;&gt;Using Version Control in PyCharm&lt;/h2&gt;
1412 &lt;p&gt;Version control systems such as &lt;a href=&quot;https://git-scm.com/&quot;&gt;Git&lt;/a&gt; and &lt;a href=&quot;https://www.mercurial-scm.org/&quot;&gt;Mercurial&lt;/a&gt; are some of the most important tools in the modern software development world. So, it is essential for an IDE to support them. PyCharm does that very well by integrating with a lot of popular VC systems such as Git (and &lt;a href=&quot;https://github.com/&quot;&gt;Github&lt;/a&gt;), Mercurial, &lt;a href=&quot;https://www.perforce.com/solutions/version-control&quot;&gt;Perforce&lt;/a&gt; and, &lt;a href=&quot;https://subversion.apache.org/&quot;&gt;Subversion&lt;/a&gt;.&lt;/p&gt;
1413 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
1414 &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;a href=&quot;https://realpython.com/python-git-github-intro/&quot;&gt;Git&lt;/a&gt; is used for the following examples.&lt;/p&gt;
1415 &lt;/div&gt;
1416 &lt;h3 id=&quot;configuring-vcs&quot;&gt;Configuring VCS&lt;/h3&gt;
1417 &lt;p&gt;To enable VCS integration. Go to &lt;em&gt;VCS → VCS Operations Popup&amp;hellip;&lt;/em&gt; from the menu on the top or press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-v&quot;&gt;V&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-grave&quot;&gt;`&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux. Choose &lt;em&gt;Enable Version Control Integration&amp;hellip;&lt;/em&gt;. You&amp;rsquo;ll see the following window open:&lt;/p&gt;
1418 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-enable-vc-integration.b30ec94c1246.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-enable-vc-integration.b30ec94c1246.png&quot; width=&quot;715&quot; height=&quot;147&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-enable-vc-integration.b30ec94c1246.png&amp;amp;w=178&amp;amp;sig=7ef55e4ed6068c86d831adaefc1af11f4c083763 178w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-enable-vc-integration.b30ec94c1246.png&amp;amp;w=357&amp;amp;sig=c701d809b49e9837477c14e8dfe34dc4cfa66c33 357w, https://files.realpython.com/media/pycharm-enable-vc-integration.b30ec94c1246.png 715w&quot; sizes=&quot;75vw&quot; alt=&quot;Enable Version Control Integration in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1419 &lt;p&gt;Choose &lt;em&gt;Git&lt;/em&gt; from the drop down list, click &lt;em&gt;OK&lt;/em&gt;, and you have VCS enabled for your project. Note that if you opened an existing project that has version control enabled, then PyCharm will see that and automatically enable it.&lt;/p&gt;
1420 &lt;p&gt;Now, if you go to the &lt;em&gt;VCS Operations Popup&amp;hellip;&lt;/em&gt;, you&amp;rsquo;ll see a different popup with the options to do &lt;code&gt;git add&lt;/code&gt;, &lt;code&gt;git stash&lt;/code&gt;, &lt;code&gt;git branch&lt;/code&gt;, &lt;code&gt;git commit&lt;/code&gt;, &lt;code&gt;git push&lt;/code&gt; and more:&lt;/p&gt;
1421 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-vcs-operations.70dbafcb983a.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/pycharm-vcs-operations.70dbafcb983a.png&quot; width=&quot;392&quot; height=&quot;379&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-vcs-operations.70dbafcb983a.png&amp;amp;w=98&amp;amp;sig=f285b015c957936448441c4ec8b03cf8627cdffc 98w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-vcs-operations.70dbafcb983a.png&amp;amp;w=196&amp;amp;sig=a16c449a21dde2a2b0f2f7533c92e71574cd3d60 196w, https://files.realpython.com/media/pycharm-vcs-operations.70dbafcb983a.png 392w&quot; sizes=&quot;75vw&quot; alt=&quot;VCS operations in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1422 &lt;p&gt;If you can&amp;rsquo;t find what you need, you can most probably find it by going to &lt;em&gt;VCS&lt;/em&gt; from the top menu and choosing &lt;em&gt;Git&lt;/em&gt;, where you can even create and view pull requests.&lt;/p&gt;
1423 &lt;h3 id=&quot;committing-and-conflict-resolution&quot;&gt;Committing and Conflict Resolution&lt;/h3&gt;
1424 &lt;p&gt;These are two features of VCS integration in PyCharm that I personally use and enjoy a lot! Let&amp;rsquo;s say you have finished your work and want to commit it. Go to &lt;em&gt;VCS → VCS Operations Popup&amp;hellip; → Commit&amp;hellip;&lt;/em&gt; or press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-k&quot;&gt;K&lt;/kbd&gt;&lt;/span&gt; on Mac or &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-k&quot;&gt;K&lt;/kbd&gt;&lt;/span&gt; on Windows or Linux. You&amp;rsquo;ll see the following window open:&lt;/p&gt;
1425 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-commit-window.a4ceff16c2d3.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-commit-window.a4ceff16c2d3.png&quot; width=&quot;929&quot; height=&quot;682&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-commit-window.a4ceff16c2d3.png&amp;amp;w=232&amp;amp;sig=935dabf7a28cf757a5c87165e3da494540c3e4a6 232w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-commit-window.a4ceff16c2d3.png&amp;amp;w=464&amp;amp;sig=7a05fe8a5cbfb1c3524c24515f9a8d7fa3211591 464w, https://files.realpython.com/media/pycharm-commit-window.a4ceff16c2d3.png 929w&quot; sizes=&quot;75vw&quot; alt=&quot;Commit window in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1426 &lt;p&gt;In this window, you can do the following:&lt;/p&gt;
1427 &lt;ol&gt;
1428 &lt;li&gt;Choose which files to commit&lt;/li&gt;
1429 &lt;li&gt;Write your commit message&lt;/li&gt;
1430 &lt;li&gt;Do all kinds of checks and cleanup &lt;a href=&quot;https://www.jetbrains.com/help/idea/commit-changes-dialog.html#before_commit&quot;&gt;before commit&lt;/a&gt;&lt;/li&gt;
1431 &lt;li&gt;See the difference of changes&lt;/li&gt;
1432 &lt;li&gt;Commit and push at once by pressing the arrow to the right of the &lt;em&gt;Commit&lt;/em&gt; button on the right bottom and choosing &lt;em&gt;Commit and Push&amp;hellip;&lt;/em&gt;&lt;/li&gt;
1433 &lt;/ol&gt;
1434 &lt;p&gt;It can feel magical and fast, especially if you&amp;rsquo;re used to doing everything manually on the command line.&lt;/p&gt;
1435 &lt;p&gt;When you work in a team, &lt;strong&gt;merge conflicts&lt;/strong&gt; do happen. When somebody commits changes to a file that you&amp;rsquo;re working on, but their changes overlap with yours because both of you changed the same lines, then VCS will not be able to figure out if it should choose your changes or those of your teammate. So you&amp;rsquo;ll get these unfortunate arrows and symbols:&lt;/p&gt;
1436 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-conflicts.74b23b9ec798.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-conflicts.74b23b9ec798.png&quot; width=&quot;996&quot; height=&quot;691&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-conflicts.74b23b9ec798.png&amp;amp;w=249&amp;amp;sig=d02221be0ce12dbc9a8ea7514e047bb608b16c08 249w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-conflicts.74b23b9ec798.png&amp;amp;w=498&amp;amp;sig=1286c7aa0f62795e01c6a2f0607096b8c0d67b20 498w, https://files.realpython.com/media/pycharm-conflicts.74b23b9ec798.png 996w&quot; sizes=&quot;75vw&quot; alt=&quot;Conflicts in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1437 &lt;p&gt;This looks strange, and it&amp;rsquo;s difficult to figure out which changes should be deleted and which ones should stay. PyCharm to the rescue! It has a much nicer and cleaner way of resolving conflicts. Go to &lt;em&gt;VCS&lt;/em&gt; in the top menu, choose &lt;em&gt;Git&lt;/em&gt; and then &lt;em&gt;Resolve conflicts&amp;hellip;&lt;/em&gt;. Choose the file whose conflicts you want to resolve and click on &lt;em&gt;Merge&lt;/em&gt;. You will see the following window open:&lt;/p&gt;
1438 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-conflict-resolving-window.eea8f79a12b2.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-conflict-resolving-window.eea8f79a12b2.png&quot; width=&quot;1174&quot; height=&quot;709&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-conflict-resolving-window.eea8f79a12b2.png&amp;amp;w=293&amp;amp;sig=ef195e8acbb5ec9fa55fca46a43486995c2efca7 293w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-conflict-resolving-window.eea8f79a12b2.png&amp;amp;w=587&amp;amp;sig=067731ba579736c92c747eb128b3fb02b0d68417 587w, https://files.realpython.com/media/pycharm-conflict-resolving-window.eea8f79a12b2.png 1174w&quot; sizes=&quot;75vw&quot; alt=&quot;Conflict resolving windown in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1439 &lt;p&gt;On the left column, you will see your changes. On the right one, the changes made by your teammate. Finally, in the middle column, you will see the result. The conflicting lines are highlighted, and you can see a little &lt;em&gt;X&lt;/em&gt; and &lt;em&gt;&amp;gt;&amp;gt;&lt;/em&gt;/&lt;em&gt;&amp;lt;&amp;lt;&lt;/em&gt; right beside those lines. Press the arrows to accept the changes and the &lt;em&gt;X&lt;/em&gt; to decline. After you resolve all those conflicts, click the &lt;em&gt;Apply&lt;/em&gt; button: &lt;/p&gt;
1440 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-resolving-conflicts.d3128ce78c45.gif&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-resolving-conflicts.d3128ce78c45.gif&quot; width=&quot;1200&quot; height=&quot;720&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-resolving-conflicts.d3128ce78c45.gif&amp;amp;w=300&amp;amp;sig=099dcca659431f9d2a1315b1fea5d7cbe246425c 300w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-resolving-conflicts.d3128ce78c45.gif&amp;amp;w=600&amp;amp;sig=6b98751300d8750c93d80cf7b65e96fb57d81714 600w, https://files.realpython.com/media/pycharm-resolving-conflicts.d3128ce78c45.gif 1200w&quot; sizes=&quot;75vw&quot; alt=&quot;Resolving Conflicts in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1441 &lt;p&gt;In the GIF above, for the first conflicting line, the author declined his own changes and accepted those of his teammates. Conversely, the author accepted his own changes and declined his teammates&amp;rsquo; for the second conflicting line.&lt;/p&gt;
1442 &lt;p&gt;There&amp;rsquo;s a lot more that you can do with the VCS integration in PyCharm. For more details, see &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/version-control-integration.html&quot;&gt;this documentation&lt;/a&gt;.&lt;/p&gt;
1443 &lt;h2 id=&quot;using-plugins-and-external-tools-in-pycharm&quot;&gt;Using Plugins and External Tools in PyCharm&lt;/h2&gt;
1444 &lt;p&gt;You can find almost everything you need for development in PyCharm. If you can&amp;rsquo;t, there is most probably a &lt;a href=&quot;https://plugins.jetbrains.com/&quot;&gt;plugin&lt;/a&gt; that adds that functionality you need to PyCharm. For example, they can:&lt;/p&gt;
1445 &lt;ul&gt;
1446 &lt;li&gt;Add support for various languages and frameworks &lt;/li&gt;
1447 &lt;li&gt;Boost your productivity with shortcut hints, file watchers, and so on &lt;/li&gt;
1448 &lt;li&gt;Help you learn a new programming language with coding exercises&lt;/li&gt;
1449 &lt;/ul&gt;
1450 &lt;p&gt;For instance, &lt;a href=&quot;https://plugins.jetbrains.com/plugin/164-ideavim&quot;&gt;IdeaVim&lt;/a&gt; adds Vim emulation to PyCharm. If you like Vim, this can be a pretty good combination. &lt;/p&gt;
1451 &lt;p&gt;&lt;a href=&quot;https://plugins.jetbrains.com/plugin/8006-material-theme-ui&quot;&gt;Material Theme UI&lt;/a&gt; changes the appearance of PyCharm to a Material Design look and feel: &lt;/p&gt;
1452 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-material-theme.178175815adc.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/pycharm-material-theme.178175815adc.png&quot; width=&quot;1110&quot; height=&quot;743&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-material-theme.178175815adc.png&amp;amp;w=277&amp;amp;sig=60ec4c8b5f6a89af345a230518e21ee8a33d174b 277w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-material-theme.178175815adc.png&amp;amp;w=555&amp;amp;sig=fdac8603145ed77eb443abcbbe8ebdb9811bdff4 555w, https://files.realpython.com/media/pycharm-material-theme.178175815adc.png 1110w&quot; sizes=&quot;75vw&quot; alt=&quot;Material Theme in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1453 &lt;p&gt;&lt;a href=&quot;https://plugins.jetbrains.com/plugin/9442-vue-js&quot;&gt;Vue.js&lt;/a&gt; adds support for &lt;a href=&quot;https://vuejs.org/&quot;&gt;Vue.js&lt;/a&gt; projects. &lt;a href=&quot;https://plugins.jetbrains.com/plugin/7793-markdown&quot;&gt;Markdown&lt;/a&gt; provides the capability to edit Markdown files within the IDE and see the rendered HTML in a live preview. You can find and install all of the available plugins by going to the &lt;em&gt;Preferences → Plugins&lt;/em&gt; on Mac or &lt;em&gt;Settings → Plugins&lt;/em&gt; on Windows or Linux, under the &lt;em&gt;Marketplace&lt;/em&gt; tab:&lt;/p&gt;
1454 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-plugin-marketplace.7d1cecfdc8b3.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-plugin-marketplace.7d1cecfdc8b3.png&quot; width=&quot;1047&quot; height=&quot;687&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-plugin-marketplace.7d1cecfdc8b3.png&amp;amp;w=261&amp;amp;sig=8d4a9ba35b5eb27b5604f86108b79f28e40f3cc9 261w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-plugin-marketplace.7d1cecfdc8b3.png&amp;amp;w=523&amp;amp;sig=ec5e20ae96bf9ee37a1011bcc2203e7d1599b4a4 523w, https://files.realpython.com/media/pycharm-plugin-marketplace.7d1cecfdc8b3.png 1047w&quot; sizes=&quot;75vw&quot; alt=&quot;Plugin Marketplace in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1455 &lt;p&gt;If you can&amp;rsquo;t find what you need, you can even &lt;a href=&quot;http://www.jetbrains.org/intellij/sdk/docs/basics.html&quot;&gt;develop your own plugin&lt;/a&gt;.&lt;/p&gt;
1456 &lt;p&gt;If you can&amp;rsquo;t find the right plugin and don&amp;rsquo;t want to develop your own because there&amp;rsquo;s already a package in PyPI, then you can add it to PyCharm as an external tool. Take &lt;a href=&quot;http://flake8.pycqa.org/en/latest/&quot;&gt;&lt;code&gt;Flake8&lt;/code&gt;&lt;/a&gt;, the code analyzer, as an example. &lt;/p&gt;
1457 &lt;p&gt;First, install &lt;code&gt;flake8&lt;/code&gt; in your virtualenv with &lt;code&gt;pip install flake8&lt;/code&gt; in the Terminal app of your choice. You can also use the one integrated into PyCharm:&lt;/p&gt;
1458 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-terminal.bb20cae6697e.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/pycharm-terminal.bb20cae6697e.png&quot; width=&quot;972&quot; height=&quot;646&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-terminal.bb20cae6697e.png&amp;amp;w=243&amp;amp;sig=860217f31e60a4bb574e169ee05b6788cacaa388 243w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-terminal.bb20cae6697e.png&amp;amp;w=486&amp;amp;sig=26a30f328e42cc19e7e652c44767093480dbf352 486w, https://files.realpython.com/media/pycharm-terminal.bb20cae6697e.png 972w&quot; sizes=&quot;75vw&quot; alt=&quot;Terminal in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1459 &lt;p&gt;Then, go to &lt;em&gt;Preferences → Tools&lt;/em&gt; on Mac or &lt;em&gt;Settings → Tools&lt;/em&gt; on Windows/Linux, and then choose &lt;em&gt;External Tools&lt;/em&gt;. Then click on the little &lt;em&gt;+&lt;/em&gt; button at the bottom (1). In the new popup window, insert the details as shown below and click &lt;em&gt;OK&lt;/em&gt; for both windows:&lt;/p&gt;
1460 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-flake8-tool.3963506224b4.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/pycharm-flake8-tool.3963506224b4.png&quot; width=&quot;1082&quot; height=&quot;720&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-flake8-tool.3963506224b4.png&amp;amp;w=270&amp;amp;sig=152f2ccf0a75a950b6a5cd6b5087507b66288595 270w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-flake8-tool.3963506224b4.png&amp;amp;w=541&amp;amp;sig=ee7221ee226076dfeaedfd5d2756263e351d8d14 541w, https://files.realpython.com/media/pycharm-flake8-tool.3963506224b4.png 1082w&quot; sizes=&quot;75vw&quot; alt=&quot;Flake8 tool in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1461 &lt;p&gt;Here, &lt;em&gt;Program&lt;/em&gt; (2) refers to the Flake8 executable that can be found in the folder &lt;em&gt;/bin&lt;/em&gt; of your virtual environment. &lt;em&gt;Arguments&lt;/em&gt; (3) refers to which file you want to analyze with the help of Flake8. &lt;em&gt;Working directory&lt;/em&gt; is the directory of your project.&lt;/p&gt;
1462 &lt;p&gt;You could hardcode the absolute paths for everything here, but that would mean that you couldn&amp;rsquo;t use this external tool in other projects. You would be able to use it only inside one project for one file. &lt;/p&gt;
1463 &lt;p&gt;So you need to use something called &lt;em&gt;Macros&lt;/em&gt;. Macros are basically variables in the format of &lt;code&gt;$name$&lt;/code&gt; that change according to your context. For example, &lt;code&gt;$FileName$&lt;/code&gt; is &lt;code&gt;first.py&lt;/code&gt; when you&amp;rsquo;re editing &lt;code&gt;first.py&lt;/code&gt;, and it is &lt;code&gt;second.py&lt;/code&gt; when you&amp;rsquo;re editing &lt;code&gt;second.py&lt;/code&gt;. You can see their list and insert any of them by clicking on the &lt;em&gt;Insert Macro&amp;hellip;&lt;/em&gt; buttons. Because you used macros here, the values will change according to the project you&amp;rsquo;re currently working on, and Flake8 will continue to do its job properly.   &lt;/p&gt;
1464 &lt;p&gt;In order to use it, create a file &lt;code&gt;example.py&lt;/code&gt; and put the following code in it:&lt;/p&gt;
1465 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CONSTANT_VAR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
1466 &lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
1467 &lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;
1468 &lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;
1469 &lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1470 &lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;
1471 &lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
1472 &lt;/pre&gt;&lt;/div&gt;
1473 
1474 &lt;p&gt;It deliberately breaks some of the Flake8 rules. Right-click the background of this file. Choose &lt;em&gt;External Tools&lt;/em&gt; and then &lt;em&gt;Flake8&lt;/em&gt;. Voilà! The output of the Flake8 analysis will appear at the bottom: &lt;/p&gt;
1475 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-flake8-output.5b78e911e6d3.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/pycharm-flake8-output.5b78e911e6d3.png&quot; width=&quot;997&quot; height=&quot;634&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-flake8-output.5b78e911e6d3.png&amp;amp;w=249&amp;amp;sig=8fecbaaf9d4e2daa2bbe443be4b6dee2634f2a46 249w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-flake8-output.5b78e911e6d3.png&amp;amp;w=498&amp;amp;sig=4e41c6dbac28fbe23c18716f49c3cadf63767500 498w, https://files.realpython.com/media/pycharm-flake8-output.5b78e911e6d3.png 997w&quot; sizes=&quot;75vw&quot; alt=&quot;Flake8 Output in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1476 &lt;p&gt;In order to make it even better, you can add a shortcut for it. Go to &lt;em&gt;Preferences&lt;/em&gt; on Mac or to &lt;em&gt;Settings&lt;/em&gt; on Windows or Linux. Then, go to &lt;em&gt;Keymap → External Tools → External Tools&lt;/em&gt;. Double-click &lt;em&gt;Flake8&lt;/em&gt; and choose &lt;em&gt;Add Keyboard Shortcut&lt;/em&gt;. You&amp;rsquo;ll see this window:&lt;/p&gt;
1477 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pycharm-add-shortcut.8c66b2bd12c0.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/pycharm-add-shortcut.8c66b2bd12c0.png&quot; width=&quot;1084&quot; height=&quot;724&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-add-shortcut.8c66b2bd12c0.png&amp;amp;w=271&amp;amp;sig=e95cc32634af125588e6881ec6992dace79ec667 271w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pycharm-add-shortcut.8c66b2bd12c0.png&amp;amp;w=542&amp;amp;sig=836cbeec5256df8e8048aa6a0c3e7d89b2bac444 542w, https://files.realpython.com/media/pycharm-add-shortcut.8c66b2bd12c0.png 1084w&quot; sizes=&quot;75vw&quot; alt=&quot;Add shortcut in PyCharm&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1478 &lt;p&gt;In the image above, the shortcut is &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-a&quot;&gt;A&lt;/kbd&gt;&lt;/span&gt; for this tool. Add your preferred shortcut in the textbox and click &lt;em&gt;OK&lt;/em&gt; for both windows. Now you can now use that shortcut to analyze the file you&amp;rsquo;re currently working on with Flake8.&lt;/p&gt;
1479 &lt;h2 id=&quot;pycharm-professional-features&quot;&gt;PyCharm Professional Features&lt;/h2&gt;
1480 &lt;p&gt;PyCharm Professional is a paid version of PyCharm with more out-of-the-box features and integrations. In this section, you&amp;rsquo;ll mainly be presented with overviews of its main features and links to the official documentation, where each feature is discussed in detail. Remember that none of the following features is available in the Community edition. &lt;/p&gt;
1481 &lt;h3 id=&quot;django-support&quot;&gt;Django Support&lt;/h3&gt;
1482 &lt;p&gt;PyCharm has extensive support for &lt;a href=&quot;https://www.djangoproject.com/&quot;&gt;Django&lt;/a&gt;, one of the most popular and beloved &lt;a href=&quot;https://realpython.com/learning-paths/become-python-web-developer/&quot;&gt;Python web frameworks&lt;/a&gt;. To make sure that it&amp;rsquo;s enabled, do the following:&lt;/p&gt;
1483 &lt;ol&gt;
1484 &lt;li&gt;Open &lt;em&gt;Preferences&lt;/em&gt; on Mac or &lt;em&gt;Settings&lt;/em&gt; on Windows or Linux.&lt;/li&gt;
1485 &lt;li&gt;Choose &lt;em&gt;Languages and Frameworks&lt;/em&gt;.&lt;/li&gt;
1486 &lt;li&gt;Choose &lt;em&gt;Django&lt;/em&gt;.&lt;/li&gt;
1487 &lt;li&gt;Check the checkbox &lt;em&gt;Enable Django support&lt;/em&gt;.&lt;/li&gt;
1488 &lt;li&gt;Apply changes.&lt;/li&gt;
1489 &lt;/ol&gt;
1490 &lt;p&gt;Now that you&amp;rsquo;ve enabled Django support, your Django development journey will be a lot easier in PyCharm:&lt;/p&gt;
1491 &lt;ul&gt;
1492 &lt;li&gt;When creating a project, you&amp;rsquo;ll have a dedicated Django project type. This means that, when you choose this type, you&amp;rsquo;ll have all the necessary files and settings. This is the equivalent of using &lt;code&gt;django-admin startproject mysite&lt;/code&gt;.&lt;/li&gt;
1493 &lt;li&gt;You can run &lt;code&gt;manage.py&lt;/code&gt; commands directly inside PyCharm. &lt;/li&gt;
1494 &lt;li&gt;Django templates are supported, including:&lt;ul&gt;
1495 &lt;li&gt;Syntax and error highlighting&lt;/li&gt;
1496 &lt;li&gt;Code completion&lt;/li&gt;
1497 &lt;li&gt;Navigation&lt;/li&gt;
1498 &lt;li&gt;Completion for block names&lt;/li&gt;
1499 &lt;li&gt;Completion for custom tags and filters&lt;/li&gt;
1500 &lt;li&gt;Quick documentation for tags and filters&lt;/li&gt;
1501 &lt;li&gt;Capability to debug them&lt;/li&gt;
1502 &lt;/ul&gt;
1503 &lt;/li&gt;
1504 &lt;li&gt;Code completion in all other Django parts such as views, URLs and models, and code insight support for Django ORM.&lt;/li&gt;
1505 &lt;li&gt;Model dependency diagrams for Django models.&lt;/li&gt;
1506 &lt;/ul&gt;
1507 &lt;p&gt;For more details on Django support, see the &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/django-support7.html&quot;&gt;official documentation&lt;/a&gt;.&lt;/p&gt;
1508 &lt;h3 id=&quot;database-support&quot;&gt;Database Support&lt;/h3&gt;
1509 &lt;p&gt;Modern database development is a complex task with many supporting systems and workflows. That&amp;rsquo;s why JetBrains, the company behind PyCharm, developed a standalone IDE called &lt;a href=&quot;https://www.jetbrains.com/datagrip/&quot;&gt;DataGrip&lt;/a&gt; for that. It&amp;rsquo;s a separate product from PyCharm with a separate license. &lt;/p&gt;
1510 &lt;p&gt;Luckily, PyCharm supports all the features that are available in DataGrip through a plugin called &lt;em&gt;Database tools and SQL&lt;/em&gt;, which is enabled by default. With the help of it, you can query, create and manage databases whether they&amp;rsquo;re working locally, on a server, or in the cloud. The plugin supports MySQL, PostgreSQL, Microsoft SQL Server, SQLite, MariaDB, Oracle, Apache Cassandra, and others. For more information on what you can do with this plugin, check out &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/relational-databases.html&quot;&gt;the comprehensive documentation on the database support&lt;/a&gt;.&lt;/p&gt;
1511 &lt;h3 id=&quot;thread-concurrency-visualization&quot;&gt;Thread Concurrency Visualization&lt;/h3&gt;
1512 &lt;p&gt;&lt;a href=&quot;https://channels.readthedocs.io/en/latest/&quot;&gt;&lt;code&gt;Django Channels&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/async-io-python/&quot;&gt;&lt;code&gt;asyncio&lt;/code&gt;&lt;/a&gt;, and the recent frameworks like &lt;a href=&quot;https://www.starlette.io/&quot;&gt;&lt;code&gt;Starlette&lt;/code&gt;&lt;/a&gt; are examples of a growing trend in asynchronous Python programming. While it&amp;rsquo;s true that asynchronous programs do bring a lot of benefits to the table, it&amp;rsquo;s also notoriously hard to write and debug them. In such cases, &lt;em&gt;Thread Concurrency Visualization&lt;/em&gt; can be just what the doctor ordered because it helps you take full control over your multi-threaded applications and optimize them.&lt;/p&gt;
1513 &lt;p&gt;Check out &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/thread-concurrency-visualization.html&quot;&gt;the comprehensive documentation of this feature&lt;/a&gt; for more details.&lt;/p&gt;
1514 &lt;h3 id=&quot;profiler&quot;&gt;Profiler&lt;/h3&gt;
1515 &lt;p&gt;Speaking of optimization, profiling is another technique that you can use to optimize your code. With its help, you can see which parts of your code are taking most of the execution time. A profiler runs in the following order of priority: &lt;/p&gt;
1516 &lt;ol&gt;
1517 &lt;li&gt;&lt;a href=&quot;https://vmprof.readthedocs.io/en/latest/&quot;&gt;&lt;code&gt;vmprof&lt;/code&gt;&lt;/a&gt; &lt;/li&gt;
1518 &lt;li&gt;&lt;a href=&quot;https://github.com/sumerc/yappi&quot;&gt;&lt;code&gt;yappi&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
1519 &lt;li&gt;&lt;a href=&quot;https://docs.python.org/3/library/profile.html&quot;&gt;&lt;code&gt;cProfile&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
1520 &lt;/ol&gt;
1521 &lt;p&gt;If you don&amp;rsquo;t have &lt;code&gt;vmprof&lt;/code&gt; or &lt;code&gt;yappi&lt;/code&gt; installed, then it&amp;rsquo;ll fall back to the standard &lt;code&gt;cProfile&lt;/code&gt;. It&amp;rsquo;s &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/profiler.html&quot;&gt;well-documented&lt;/a&gt;, so I won&amp;rsquo;t rehash it here. &lt;/p&gt;
1522 &lt;h3 id=&quot;scientific-mode&quot;&gt;Scientific Mode&lt;/h3&gt;
1523 &lt;p&gt;Python is not only a language for general and web programming. It also emerged as the best tool for data science and machine learning over these last years thanks to libraries and tools like &lt;a href=&quot;http://www.numpy.org/&quot;&gt;NumPy&lt;/a&gt;, &lt;a href=&quot;https://www.scipy.org/&quot;&gt;SciPy&lt;/a&gt;, &lt;a href=&quot;https://scikit-learn.org/&quot;&gt;scikit-learn&lt;/a&gt;, &lt;a href=&quot;https://matplotlib.org/&quot;&gt;Matplotlib&lt;/a&gt;, &lt;a href=&quot;https://jupyter.org/&quot;&gt;Jupyter&lt;/a&gt;, and more. With such powerful libraries available, you need a powerful IDE to support all the functions such as graphing and analyzing those libraries have. PyCharm provides everything you need as &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/matplotlib-support.html&quot;&gt;thoroughly documented here&lt;/a&gt;.  &lt;/p&gt;
1524 &lt;h3 id=&quot;remote-development&quot;&gt;Remote Development&lt;/h3&gt;
1525 &lt;p&gt;One common cause of bugs in many applications is that development and production environments differ. Although, in most cases, it&amp;rsquo;s not possible to provide an exact copy of the production environment for development, pursuing it is a worthy goal.&lt;/p&gt;
1526 &lt;p&gt;With PyCharm, you can debug your application using an interpreter that is located on the other computer, such as a Linux VM. As a result, you can have the same interpreter as your production environment to fix and avoid many bugs resulting from the difference between development and production environments. Make sure to check out the &lt;a href=&quot;https://www.jetbrains.com/help/pycharm/remote-debugging-with-product.html&quot;&gt;official documentation&lt;/a&gt; to learn more.&lt;/p&gt;
1527 &lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
1528 &lt;p&gt;PyCharm is one of best, if not the best, full-featured, dedicated, and versatile IDEs for Python development. It offers a ton of benefits, saving you a lot of time by helping you with routine tasks. Now you know how to be productive with it!&lt;/p&gt;
1529 &lt;p&gt;In this article, you learned about a lot, including:&lt;/p&gt;
1530 &lt;ul&gt;
1531 &lt;li&gt;Installing PyCharm&lt;/li&gt;
1532 &lt;li&gt;Writing code in PyCharm&lt;/li&gt;
1533 &lt;li&gt;Running your code in PyCharm&lt;/li&gt;
1534 &lt;li&gt;Debugging and testing your code in PyCharm&lt;/li&gt;
1535 &lt;li&gt;Editing an existing project in PyCharm&lt;/li&gt;
1536 &lt;li&gt;Searching and navigating in PyCharm&lt;/li&gt;
1537 &lt;li&gt;Using Version Control in PyCharm&lt;/li&gt;
1538 &lt;li&gt;Using Plugins and External Tools in PyCharm&lt;/li&gt;
1539 &lt;li&gt;Using PyCharm Professional features, such as Django support and Scientific mode&lt;/li&gt;
1540 &lt;/ul&gt;
1541 &lt;p&gt;If there&amp;rsquo;s anything you&amp;rsquo;d like to ask or share, please reach out in the comments below. There&amp;rsquo;s also a lot more information at the &lt;a href=&quot;https://www.jetbrains.com/pycharm/documentation/&quot;&gt;PyCharm website&lt;/a&gt; for you to explore.&lt;/p&gt;
1542 &lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Clone Repo:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/alcazar-web-framework/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-alcazar-web-framework&quot; data-focus=&quot;false&quot;&gt;Click here to clone the repo you&#39;ll use&lt;/a&gt; to explore the project-focused features of PyCharm in this tutorial.&lt;/p&gt;&lt;/div&gt;
1543         &lt;hr /&gt;
1544         &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;
1545       </content>
1546     </entry>
1547   
1548     <entry>
1549       <title>How to Use Python Lambda Functions</title>
1550       <id>https://realpython.com/courses/python-lambda-functions/</id>
1551       <link href="https://realpython.com/courses/python-lambda-functions/"/>
1552       <updated>2019-08-27T14:00:00+00:00</updated>
1553       <summary>In this step-by-step course, you&#39;ll learn about Python lambda functions. You&#39;ll see how they compare with regular functions and how you can use them in accordance with best practices.</summary>
1554       <content type="html">
1555         &lt;p&gt;Python and other languages like Java, C#, and even C++ have had lambda functions added to their syntax, whereas languages like LISP or the ML family of languages, Haskell, OCaml, and F#, use lambdas as a core concept. Python lambdas are little, anonymous functions, subject to a more restrictive but more concise syntax than regular Python functions.&lt;/p&gt;
1556 &lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll know:&lt;/strong&gt;&lt;/p&gt;
1557 &lt;ul&gt;
1558 &lt;li&gt;How Python lambdas came to be &lt;/li&gt;
1559 &lt;li&gt;How lambdas compare with regular function objects&lt;/li&gt;
1560 &lt;li&gt;How to write lambda functions&lt;/li&gt;
1561 &lt;li&gt;Which functions in the Python standard library leverage lambdas&lt;/li&gt;
1562 &lt;li&gt;When to use or avoid Python lambda functions&lt;/li&gt;
1563 &lt;/ul&gt;
1564 &lt;p&gt;This course is mainly for intermediate to experienced Python programmers, but it is accessible to any curious minds with interest in programming. All the examples included in this tutorial have been tested with Python 3.7.&lt;/p&gt;
1565         &lt;hr /&gt;
1566         &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;
1567       </content>
1568     </entry>
1569   
1570     <entry>
1571       <title>A Guide to Excel Spreadsheets in Python With openpyxl</title>
1572       <id>https://realpython.com/openpyxl-excel-spreadsheets-python/</id>
1573       <link href="https://realpython.com/openpyxl-excel-spreadsheets-python/"/>
1574       <updated>2019-08-26T14:00:00+00:00</updated>
1575       <summary>In this step-by-step tutorial, you&#39;ll learn how to handle spreadsheets in Python using the openpyxl package. You&#39;ll learn how to manipulate Excel spreadsheets, extract information from spreadsheets, create simple or more complex spreadsheets, including adding styles, charts, and so on.</summary>
1576       <content type="html">
1577         &lt;p&gt;Excel spreadsheets are one of those things you might have to deal with at some point. Either it&amp;rsquo;s because your boss loves them or because marketing needs them, you might have to learn how to work with spreadsheets, and that&amp;rsquo;s when knowing &lt;code&gt;openpyxl&lt;/code&gt; comes in handy!&lt;/p&gt;
1578 &lt;p&gt;Spreadsheets are a very intuitive and user-friendly way to manipulate large datasets without any prior technical background. That&amp;rsquo;s why they&amp;rsquo;re still so commonly used today.&lt;/p&gt;
1579 &lt;p&gt;&lt;strong&gt;In this article, you&amp;rsquo;ll learn how to use openpyxl to:&lt;/strong&gt;&lt;/p&gt;
1580 &lt;ul&gt;
1581 &lt;li&gt;Manipulate Excel spreadsheets with confidence&lt;/li&gt;
1582 &lt;li&gt;Extract information from spreadsheets&lt;/li&gt;
1583 &lt;li&gt;Create simple or more complex spreadsheets, including adding styles, charts, and so on&lt;/li&gt;
1584 &lt;/ul&gt;
1585 &lt;p&gt;This article is written for intermediate developers who have a pretty good knowledge of Python data structures, such as &lt;a href=&quot;https://realpython.com/python-dicts/&quot;&gt;dicts&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/python-lists-tuples/&quot;&gt;lists&lt;/a&gt;, but also feel comfortable around &lt;a href=&quot;https://realpython.com/python3-object-oriented-programming/&quot;&gt;OOP&lt;/a&gt; and more intermediate level topics.&lt;/p&gt;
1586 &lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Download Dataset:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/openpyxl-sample-dataset/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-openpyxl-sample-dataset&quot; data-focus=&quot;false&quot;&gt;Click here to download the dataset for the openpyxl exercise you&#39;ll be following in this tutorial.&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
1587 
1588 &lt;h2 id=&quot;before-you-begin&quot;&gt;Before You Begin&lt;/h2&gt;
1589 &lt;p&gt;If you ever get asked to extract some data from a database or log file into an Excel spreadsheet, or if you often have to convert an Excel spreadsheet into some more usable programmatic form, then this tutorial is perfect for you. Let&amp;rsquo;s jump into the &lt;code&gt;openpyxl&lt;/code&gt; caravan!&lt;/p&gt;
1590 &lt;h3 id=&quot;practical-use-cases&quot;&gt;Practical Use Cases&lt;/h3&gt;
1591 &lt;p&gt;First things first, when would you need to use a package like &lt;code&gt;openpyxl&lt;/code&gt; in a real-world scenario? You&amp;rsquo;ll see a few examples below, but really, there are hundreds of possible scenarios where this knowledge could come in handy.&lt;/p&gt;
1592 &lt;h4 id=&quot;importing-new-products-into-a-database&quot;&gt;Importing New Products Into a Database&lt;/h4&gt;
1593 &lt;p&gt;You are responsible for tech in an online store company, and your boss doesn&amp;rsquo;t want to pay for a cool and expensive CMS system.&lt;/p&gt;
1594 &lt;p&gt;Every time they want to add new products to the online store, they come to you with an Excel spreadsheet with a few hundred rows and, for each of them, you have the product name, description, price, and so forth.&lt;/p&gt;
1595 &lt;p&gt;Now, to import the data, you&amp;rsquo;ll have to iterate over each spreadsheet row and add each product to the online store.&lt;/p&gt;
1596 &lt;h4 id=&quot;exporting-database-data-into-a-spreadsheet&quot;&gt;Exporting Database Data Into a Spreadsheet&lt;/h4&gt;
1597 &lt;p&gt;Say you have a Database table where you record all your users&amp;rsquo; information, including name, phone number, email address, and so forth.&lt;/p&gt;
1598 &lt;p&gt;Now, the Marketing team wants to contact all users to give them some discounted offer or promotion. However, they don&amp;rsquo;t have access to the Database, or they don&amp;rsquo;t know how to use SQL to extract that information easily.&lt;/p&gt;
1599 &lt;p&gt;What can you do to help? Well, you can make a quick script using &lt;code&gt;openpyxl&lt;/code&gt; that iterates over every single User record and puts all the essential information into an Excel spreadsheet.&lt;/p&gt;
1600 &lt;p&gt;That&amp;rsquo;s gonna earn you an extra slice of cake at your company&amp;rsquo;s next birthday party!&lt;/p&gt;
1601 &lt;h4 id=&quot;appending-information-to-an-existing-spreadsheet&quot;&gt;Appending Information to an Existing Spreadsheet&lt;/h4&gt;
1602 &lt;p&gt;You may also have to open a spreadsheet, read the information in it and, according to some business logic, append more data to it.&lt;/p&gt;
1603 &lt;p&gt;For example, using the online store scenario again, say you get an Excel spreadsheet with a list of users and you need to append to each row the total amount they&amp;rsquo;ve spent in your store.&lt;/p&gt;
1604 &lt;p&gt;This data is in the Database and, in order to do this, you have to read the spreadsheet, iterate through each row, fetch the total amount spent from the Database and then write back to the spreadsheet.&lt;/p&gt;
1605 &lt;p&gt;Not a problem for &lt;code&gt;openpyxl&lt;/code&gt;!&lt;/p&gt;
1606 &lt;h3 id=&quot;learning-some-basic-excel-terminology&quot;&gt;Learning Some Basic Excel Terminology&lt;/h3&gt;
1607 &lt;p&gt;Here&amp;rsquo;s a quick list of basic terms you&amp;rsquo;ll see when you&amp;rsquo;re working with Excel spreadsheets:&lt;/p&gt;
1608 &lt;div class=&quot;table-responsive&quot;&gt;
1609 &lt;table class=&quot;table table-hover&quot;&gt;
1610 &lt;thead&gt;
1611 &lt;tr&gt;
1612 &lt;th&gt;Term&lt;/th&gt;
1613 &lt;th&gt;Explanation&lt;/th&gt;
1614 &lt;/tr&gt;
1615 &lt;/thead&gt;
1616 &lt;tbody&gt;
1617 &lt;tr&gt;
1618 &lt;td&gt;Spreadsheet or Workbook&lt;/td&gt;
1619 &lt;td&gt;A &lt;strong&gt;Spreadsheet&lt;/strong&gt; is the main file you are creating or working with.&lt;/td&gt;
1620 &lt;/tr&gt;
1621 &lt;tr&gt;
1622 &lt;td&gt;Worksheet or Sheet&lt;/td&gt;
1623 &lt;td&gt;A &lt;strong&gt;Sheet&lt;/strong&gt; is used to split different kinds of content within the same spreadsheet. A &lt;strong&gt;Spreadsheet&lt;/strong&gt; can have one or more &lt;strong&gt;Sheets&lt;/strong&gt;.&lt;/td&gt;
1624 &lt;/tr&gt;
1625 &lt;tr&gt;
1626 &lt;td&gt;Column&lt;/td&gt;
1627 &lt;td&gt;A &lt;strong&gt;Column&lt;/strong&gt; is a vertical line, and it&amp;rsquo;s represented by an uppercase letter: &lt;em&gt;A&lt;/em&gt;.&lt;/td&gt;
1628 &lt;/tr&gt;
1629 &lt;tr&gt;
1630 &lt;td&gt;Row&lt;/td&gt;
1631 &lt;td&gt;A &lt;strong&gt;Row&lt;/strong&gt; is a horizontal line, and it&amp;rsquo;s represented by a number: &lt;em&gt;1&lt;/em&gt;.&lt;/td&gt;
1632 &lt;/tr&gt;
1633 &lt;tr&gt;
1634 &lt;td&gt;Cell&lt;/td&gt;
1635 &lt;td&gt;A &lt;strong&gt;Cell&lt;/strong&gt; is a combination of &lt;strong&gt;Column&lt;/strong&gt; and &lt;strong&gt;Row&lt;/strong&gt;, represented by both an uppercase letter and a number: &lt;em&gt;A1&lt;/em&gt;.&lt;/td&gt;
1636 &lt;/tr&gt;
1637 &lt;/tbody&gt;
1638 &lt;/table&gt;
1639 &lt;/div&gt;
1640 &lt;h3 id=&quot;getting-started-with-openpyxl&quot;&gt;Getting Started With openpyxl&lt;/h3&gt;
1641 &lt;p&gt;Now that you&amp;rsquo;re aware of the benefits of a tool like &lt;code&gt;openpyxl&lt;/code&gt;, let&amp;rsquo;s get down to it and start by installing the package. For this tutorial, you should use Python 3.7 and openpyxl 2.6.2. To install the package, you can do the following:&lt;/p&gt;
1642 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; pip install openpyxl
1643 &lt;/pre&gt;&lt;/div&gt;
1644 
1645 &lt;p&gt;After you install the package, you should be able to create a super simple spreadsheet with the following code:&lt;/p&gt;
1646 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;
1647 
1648 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
1649 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
1650 
1651 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;
1652 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;B1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;world!&amp;quot;&lt;/span&gt;
1653 
1654 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;hello_world.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1655 &lt;/pre&gt;&lt;/div&gt;
1656 
1657 &lt;p&gt;The code above should create a file called &lt;code&gt;hello_world.xlsx&lt;/code&gt; in the folder you are using to run the code. If you open that file with Excel you should see something like this:&lt;/p&gt;
1658 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_16.54.45.e646867e4dbb.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_16.54.45.e646867e4dbb.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_16.54.45.e646867e4dbb.png&amp;amp;w=540&amp;amp;sig=4c3acdcf35f528b6ed0cf6e299c2575781934414 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_16.54.45.e646867e4dbb.png&amp;amp;w=1080&amp;amp;sig=328d4ff12cec767d684f5b7666380d9f23a2a548 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_16.54.45.e646867e4dbb.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;A Simple Hello World Spreadsheet&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
1659 &lt;p&gt;&lt;em&gt;Woohoo&lt;/em&gt;, your first spreadsheet created!&lt;/p&gt;
1660 &lt;h2 id=&quot;reading-excel-spreadsheets-with-openpyxl&quot;&gt;Reading Excel Spreadsheets With openpyxl&lt;/h2&gt;
1661 &lt;p&gt;Let&amp;rsquo;s start with the most essential thing one can do with a spreadsheet: read it.&lt;/p&gt;
1662 &lt;p&gt;You&amp;rsquo;ll go from a straightforward approach to reading a spreadsheet to more complex examples where you read the data and convert it into more useful Python structures.&lt;/p&gt;
1663 &lt;h3 id=&quot;dataset-for-this-tutorial&quot;&gt;Dataset for This Tutorial&lt;/h3&gt;
1664 &lt;p&gt;Before you dive deep into some code examples, you should &lt;strong&gt;download this sample dataset&lt;/strong&gt; and store it somewhere as &lt;code&gt;sample.xlsx&lt;/code&gt;:&lt;/p&gt;
1665 &lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Download Dataset:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/openpyxl-sample-dataset/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-openpyxl-sample-dataset&quot; data-focus=&quot;false&quot;&gt;Click here to download the dataset for the openpyxl exercise you&#39;ll be following in this tutorial.&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
1666 
1667 &lt;p&gt;This is one of the datasets you&amp;rsquo;ll be using throughout this tutorial, and it&amp;rsquo;s a spreadsheet with a sample of real data from Amazon&amp;rsquo;s online product reviews. This dataset is only a tiny fraction of what Amazon &lt;a href=&quot;https://registry.opendata.aws/amazon-reviews/&quot;&gt;provides&lt;/a&gt;, but for testing purposes, it&amp;rsquo;s more than enough.&lt;/p&gt;
1668 &lt;h3 id=&quot;a-simple-approach-to-reading-an-excel-spreadsheet&quot;&gt;A Simple Approach to Reading an Excel Spreadsheet&lt;/h3&gt;
1669 &lt;p&gt;Finally, let&amp;rsquo;s start reading some spreadsheets! To begin with, open our sample spreadsheet:&lt;/p&gt;
1670 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;
1671 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1672 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheetnames&lt;/span&gt;
1673 &lt;span class=&quot;go&quot;&gt;[&amp;#39;Sheet 1&amp;#39;]&lt;/span&gt;
1674 
1675 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
1676 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;
1677 &lt;span class=&quot;go&quot;&gt;&amp;lt;Worksheet &amp;quot;Sheet 1&amp;quot;&amp;gt;&lt;/span&gt;
1678 
1679 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;
1680 &lt;span class=&quot;go&quot;&gt;&amp;#39;Sheet 1&amp;#39;&lt;/span&gt;
1681 &lt;/pre&gt;&lt;/div&gt;
1682 
1683 &lt;p&gt;In the code above, you first open the spreadsheet &lt;code&gt;sample.xlsx&lt;/code&gt; using &lt;code&gt;load_workbook()&lt;/code&gt;, and then you can use &lt;code&gt;workbook.sheetnames&lt;/code&gt; to see all the sheets you have available to work with. After that,  &lt;code&gt;workbook.active&lt;/code&gt; selects the first available sheet and, in this case, you can see that it selects &lt;strong&gt;Sheet 1&lt;/strong&gt; automatically. Using these methods is the default way of opening a spreadsheet, and you&amp;rsquo;ll see it many times during this tutorial.&lt;/p&gt;
1684 &lt;p&gt;Now, after opening a spreadsheet, you can easily retrieve data from it like this:&lt;/p&gt;
1685 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
1686 &lt;span class=&quot;go&quot;&gt;&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A1&amp;gt;&lt;/span&gt;
1687 
1688 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
1689 &lt;span class=&quot;go&quot;&gt;&amp;#39;marketplace&amp;#39;&lt;/span&gt;
1690 
1691 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;F10&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
1692 &lt;span class=&quot;go&quot;&gt;&amp;quot;G-Shock Men&amp;#39;s Grey Sport Watch&amp;quot;&lt;/span&gt;
1693 &lt;/pre&gt;&lt;/div&gt;
1694 
1695 &lt;p&gt;To return the actual value of a cell, you need to do &lt;code&gt;.value&lt;/code&gt;. Otherwise, you&amp;rsquo;ll get the main &lt;code&gt;Cell&lt;/code&gt; object. You can also use the method &lt;code&gt;.cell()&lt;/code&gt; to retrieve a cell using index notation. Remember to add &lt;code&gt;.value&lt;/code&gt; to get the actual value and not a &lt;code&gt;Cell&lt;/code&gt; object:&lt;/p&gt;
1696 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1697 &lt;span class=&quot;go&quot;&gt;&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.F10&amp;gt;&lt;/span&gt;
1698 
1699 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
1700 &lt;span class=&quot;go&quot;&gt;&amp;quot;G-Shock Men&amp;#39;s Grey Sport Watch&amp;quot;&lt;/span&gt;
1701 &lt;/pre&gt;&lt;/div&gt;
1702 
1703 &lt;p&gt;You can see that the results returned are the same, no matter which way you decide to go with. However, in this tutorial, you&amp;rsquo;ll be mostly using the first approach: &lt;code&gt;[&quot;A1&quot;]&lt;/code&gt;.&lt;/p&gt;
1704 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
1705 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Even though in Python you&amp;rsquo;re used to a zero-indexed notation, with spreadsheets you&amp;rsquo;ll always use a one-indexed notation where the first row or column always has index &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
1706 &lt;/div&gt;
1707 &lt;p&gt;The above shows you the quickest way to open a spreadsheet. However, you can pass additional parameters to change the way a spreadsheet is loaded.&lt;/p&gt;
1708 &lt;h4 id=&quot;additional-reading-options&quot;&gt;Additional Reading Options&lt;/h4&gt;
1709 &lt;p&gt;There are a few arguments you can pass to &lt;code&gt;load_workbook()&lt;/code&gt; that change the way a spreadsheet is loaded. The most important ones are the following two Booleans:&lt;/p&gt;
1710 &lt;ol&gt;
1711 &lt;li&gt;&lt;strong&gt;read_only&lt;/strong&gt; loads a spreadsheet in read-only mode allowing you to open very large Excel files.&lt;/li&gt;
1712 &lt;li&gt;&lt;strong&gt;data_only&lt;/strong&gt; ignores loading formulas and instead loads only the resulting values.&lt;/li&gt;
1713 &lt;/ol&gt;
1714 &lt;h3 id=&quot;importing-data-from-a-spreadsheet&quot;&gt;Importing Data From a Spreadsheet&lt;/h3&gt;
1715 &lt;p&gt;Now that you&amp;rsquo;ve learned the basics about loading a spreadsheet, it&amp;rsquo;s about time you get to the fun part: &lt;strong&gt;the iteration and actual usage of the values within the spreadsheet&lt;/strong&gt;.&lt;/p&gt;
1716 &lt;p&gt;This section is where you&amp;rsquo;ll learn all the different ways you can iterate through the data, but also how to convert that data into something usable and, more importantly, how to do it in a Pythonic way.&lt;/p&gt;
1717 &lt;h4 id=&quot;iterating-through-the-data&quot;&gt;Iterating Through the Data&lt;/h4&gt;
1718 &lt;p&gt;There are a few different ways you can iterate through the data depending on your needs.&lt;/p&gt;
1719 &lt;p&gt;You can slice the data with a combination of columns and rows:&lt;/p&gt;
1720 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A1:C2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
1721 &lt;span class=&quot;go&quot;&gt;((&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A1&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B1&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.C1&amp;gt;),&lt;/span&gt;
1722 &lt;span class=&quot;go&quot;&gt; (&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A2&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B2&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.C2&amp;gt;))&lt;/span&gt;
1723 &lt;/pre&gt;&lt;/div&gt;
1724 
1725 &lt;p&gt;You can get ranges of rows or columns:&lt;/p&gt;
1726 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Get all cells from column A&lt;/span&gt;
1727 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
1728 &lt;span class=&quot;go&quot;&gt;(&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A1&amp;gt;,&lt;/span&gt;
1729 &lt;span class=&quot;go&quot;&gt; &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A2&amp;gt;,&lt;/span&gt;
1730 &lt;span class=&quot;go&quot;&gt; ...&lt;/span&gt;
1731 &lt;span class=&quot;go&quot;&gt; &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A99&amp;gt;,&lt;/span&gt;
1732 &lt;span class=&quot;go&quot;&gt; &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A100&amp;gt;)&lt;/span&gt;
1733 
1734 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Get all cells for a range of columns&lt;/span&gt;
1735 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A:B&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
1736 &lt;span class=&quot;go&quot;&gt;((&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A1&amp;gt;,&lt;/span&gt;
1737 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A2&amp;gt;,&lt;/span&gt;
1738 &lt;span class=&quot;go&quot;&gt;  ...&lt;/span&gt;
1739 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A99&amp;gt;,&lt;/span&gt;
1740 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A100&amp;gt;),&lt;/span&gt;
1741 &lt;span class=&quot;go&quot;&gt; (&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B1&amp;gt;,&lt;/span&gt;
1742 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B2&amp;gt;,&lt;/span&gt;
1743 &lt;span class=&quot;go&quot;&gt;  ...&lt;/span&gt;
1744 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B99&amp;gt;,&lt;/span&gt;
1745 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B100&amp;gt;))&lt;/span&gt;
1746 
1747 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Get all cells from row 5&lt;/span&gt;
1748 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
1749 &lt;span class=&quot;go&quot;&gt;(&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A5&amp;gt;,&lt;/span&gt;
1750 &lt;span class=&quot;go&quot;&gt; &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B5&amp;gt;,&lt;/span&gt;
1751 &lt;span class=&quot;go&quot;&gt; ...&lt;/span&gt;
1752 &lt;span class=&quot;go&quot;&gt; &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.N5&amp;gt;,&lt;/span&gt;
1753 &lt;span class=&quot;go&quot;&gt; &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.O5&amp;gt;)&lt;/span&gt;
1754 
1755 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Get all cells for a range of rows&lt;/span&gt;
1756 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
1757 &lt;span class=&quot;go&quot;&gt;((&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A5&amp;gt;,&lt;/span&gt;
1758 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B5&amp;gt;,&lt;/span&gt;
1759 &lt;span class=&quot;go&quot;&gt;  ...&lt;/span&gt;
1760 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.N5&amp;gt;,&lt;/span&gt;
1761 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.O5&amp;gt;),&lt;/span&gt;
1762 &lt;span class=&quot;go&quot;&gt; (&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A6&amp;gt;,&lt;/span&gt;
1763 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B6&amp;gt;,&lt;/span&gt;
1764 &lt;span class=&quot;go&quot;&gt;  ...&lt;/span&gt;
1765 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.N6&amp;gt;,&lt;/span&gt;
1766 &lt;span class=&quot;go&quot;&gt;  &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.O6&amp;gt;))&lt;/span&gt;
1767 &lt;/pre&gt;&lt;/div&gt;
1768 
1769 &lt;p&gt;You&amp;rsquo;ll notice that all of the above examples return a &lt;code&gt;tuple&lt;/code&gt;. If you want to refresh your memory on how to handle &lt;code&gt;tuples&lt;/code&gt; in Python, check out the article on &lt;a href=&quot;https://realpython.com/python-lists-tuples/#python-tuples&quot;&gt;Lists and Tuples in Python&lt;/a&gt;.&lt;/p&gt;
1770 &lt;p&gt;There are also multiple ways of using normal Python &lt;a href=&quot;https://realpython.com/introduction-to-python-generators/&quot;&gt;generators&lt;/a&gt; to go through the data. The main methods you can use to achieve this are:&lt;/p&gt;
1771 &lt;ul&gt;
1772 &lt;li&gt;&lt;code&gt;.iter_rows()&lt;/code&gt;&lt;/li&gt;
1773 &lt;li&gt;&lt;code&gt;.iter_cols()&lt;/code&gt;&lt;/li&gt;
1774 &lt;/ul&gt;
1775 &lt;p&gt;Both methods can receive the following arguments:&lt;/p&gt;
1776 &lt;ul&gt;
1777 &lt;li&gt;&lt;code&gt;min_row&lt;/code&gt;&lt;/li&gt;
1778 &lt;li&gt;&lt;code&gt;max_row&lt;/code&gt;&lt;/li&gt;
1779 &lt;li&gt;&lt;code&gt;min_col&lt;/code&gt;&lt;/li&gt;
1780 &lt;li&gt;&lt;code&gt;max_col&lt;/code&gt;&lt;/li&gt;
1781 &lt;/ul&gt;
1782 &lt;p&gt;These arguments are used to set boundaries for the iteration:&lt;/p&gt;
1783 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_row&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;
1784 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                           &lt;span class=&quot;n&quot;&gt;max_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1785 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                           &lt;span class=&quot;n&quot;&gt;min_col&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;
1786 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                           &lt;span class=&quot;n&quot;&gt;max_col&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;
1787 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1788 &lt;span class=&quot;go&quot;&gt;(&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A1&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B1&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.C1&amp;gt;)&lt;/span&gt;
1789 &lt;span class=&quot;go&quot;&gt;(&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A2&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B2&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.C2&amp;gt;)&lt;/span&gt;
1790 
1791 
1792 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_row&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;
1793 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                              &lt;span class=&quot;n&quot;&gt;max_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1794 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                              &lt;span class=&quot;n&quot;&gt;min_col&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;
1795 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                              &lt;span class=&quot;n&quot;&gt;max_col&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;
1796 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1797 &lt;span class=&quot;go&quot;&gt;(&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A1&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A2&amp;gt;)&lt;/span&gt;
1798 &lt;span class=&quot;go&quot;&gt;(&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B1&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B2&amp;gt;)&lt;/span&gt;
1799 &lt;span class=&quot;go&quot;&gt;(&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.C1&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.C2&amp;gt;)&lt;/span&gt;
1800 &lt;/pre&gt;&lt;/div&gt;
1801 
1802 &lt;p&gt;You&amp;rsquo;ll notice that in the first example, when iterating through the rows using &lt;code&gt;.iter_rows()&lt;/code&gt;, you get one &lt;code&gt;tuple&lt;/code&gt; element per row selected. While when using &lt;code&gt;.iter_cols()&lt;/code&gt; and iterating through columns, you&amp;rsquo;ll get one &lt;code&gt;tuple&lt;/code&gt; per column instead.&lt;/p&gt;
1803 &lt;p&gt;One additional argument you can pass to both methods is the Boolean &lt;code&gt;values_only&lt;/code&gt;. When it&amp;rsquo;s set to &lt;code&gt;True&lt;/code&gt;, the values of the cell are returned, instead of the &lt;code&gt;Cell&lt;/code&gt; object:&lt;/p&gt;
1804 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_row&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;
1805 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                             &lt;span class=&quot;n&quot;&gt;max_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1806 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                             &lt;span class=&quot;n&quot;&gt;min_col&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;
1807 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                             &lt;span class=&quot;n&quot;&gt;max_col&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;
1808 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                             &lt;span class=&quot;n&quot;&gt;values_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1809 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1810 &lt;span class=&quot;go&quot;&gt;(&amp;#39;marketplace&amp;#39;, &amp;#39;customer_id&amp;#39;, &amp;#39;review_id&amp;#39;)&lt;/span&gt;
1811 &lt;span class=&quot;go&quot;&gt;(&amp;#39;US&amp;#39;, 3653882, &amp;#39;R3O9SGZBVQBV76&amp;#39;)&lt;/span&gt;
1812 &lt;/pre&gt;&lt;/div&gt;
1813 
1814 &lt;p&gt;If you want to iterate through the whole dataset, then you can also use the attributes &lt;code&gt;.rows&lt;/code&gt; or &lt;code&gt;.columns&lt;/code&gt; directly, which are shortcuts to using &lt;code&gt;.iter_rows()&lt;/code&gt; and &lt;code&gt;.iter_cols()&lt;/code&gt; without any arguments:&lt;/p&gt;
1815 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1816 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1817 &lt;span class=&quot;go&quot;&gt;(&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.A1&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.B1&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.C1&amp;gt;&lt;/span&gt;
1818 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
1819 &lt;span class=&quot;go&quot;&gt;&amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.M100&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.N100&amp;gt;, &amp;lt;Cell &amp;#39;Sheet 1&amp;#39;.O100&amp;gt;)&lt;/span&gt;
1820 &lt;/pre&gt;&lt;/div&gt;
1821 
1822 &lt;p&gt;These shortcuts are very useful when you&amp;rsquo;re iterating through the whole dataset.&lt;/p&gt;
1823 &lt;h4 id=&quot;manipulate-data-using-pythons-default-data-structures&quot;&gt;Manipulate Data Using Python&amp;rsquo;s Default Data Structures&lt;/h4&gt;
1824 &lt;p&gt;Now that you know the basics of iterating through the data in a workbook, let&amp;rsquo;s look at smart ways of converting that data into Python structures.&lt;/p&gt;
1825 &lt;p&gt;As you saw earlier, the result from all iterations comes in the form of &lt;code&gt;tuples&lt;/code&gt;. However, since a &lt;code&gt;tuple&lt;/code&gt; is nothing more than an immutable &lt;code&gt;list&lt;/code&gt;, you can easily access its data and transform it into other structures.&lt;/p&gt;
1826 &lt;p&gt;For example, say you want to extract product information from the &lt;code&gt;sample.xlsx&lt;/code&gt; spreadsheet and into a dictionary where each key is a product ID.&lt;/p&gt;
1827 &lt;p&gt;A straightforward way to do this is to iterate over all the rows, pick the columns you know are related to product information, and then store that in a dictionary. Let&amp;rsquo;s code this out!&lt;/p&gt;
1828 &lt;p&gt;First of all, have a look at the headers and see what information you care most about:&lt;/p&gt;
1829 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_row&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;
1830 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                             &lt;span class=&quot;n&quot;&gt;max_row&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;
1831 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                             &lt;span class=&quot;n&quot;&gt;values_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1832 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1833 &lt;span class=&quot;go&quot;&gt;(&amp;#39;marketplace&amp;#39;, &amp;#39;customer_id&amp;#39;, &amp;#39;review_id&amp;#39;, &amp;#39;product_id&amp;#39;, ...)&lt;/span&gt;
1834 &lt;/pre&gt;&lt;/div&gt;
1835 
1836 &lt;p&gt;This code returns a list of all the column names you have in the spreadsheet. To start, grab the columns with names:&lt;/p&gt;
1837 &lt;ul&gt;
1838 &lt;li&gt;&lt;code&gt;product_id&lt;/code&gt;&lt;/li&gt;
1839 &lt;li&gt;&lt;code&gt;product_parent&lt;/code&gt;&lt;/li&gt;
1840 &lt;li&gt;&lt;code&gt;product_title&lt;/code&gt;&lt;/li&gt;
1841 &lt;li&gt;&lt;code&gt;product_category&lt;/code&gt;&lt;/li&gt;
1842 &lt;/ul&gt;
1843 &lt;p&gt;Lucky for you, the columns you need are all next to each other so you can use the &lt;code&gt;min_column&lt;/code&gt; and &lt;code&gt;max_column&lt;/code&gt; to easily get the data you want:&lt;/p&gt;
1844 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1845 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                             &lt;span class=&quot;n&quot;&gt;min_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1846 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                             &lt;span class=&quot;n&quot;&gt;max_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1847 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                             &lt;span class=&quot;n&quot;&gt;values_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1848 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1849 &lt;span class=&quot;go&quot;&gt;(&amp;#39;B00FALQ1ZC&amp;#39;, 937001370, &amp;#39;Invicta Women\&amp;#39;s 15150 &amp;quot;Angel&amp;quot; 18k Yellow...)&lt;/span&gt;
1850 &lt;span class=&quot;go&quot;&gt;(&amp;#39;B00D3RGO20&amp;#39;, 484010722, &amp;quot;Kenneth Cole New York Women&amp;#39;s KC4944...)&lt;/span&gt;
1851 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
1852 &lt;/pre&gt;&lt;/div&gt;
1853 
1854 &lt;p&gt;Nice! Now that you know how to get all the important product information you need, let&amp;rsquo;s put that data into a dictionary:&lt;/p&gt;
1855 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;json&lt;/span&gt;
1856 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;
1857 
1858 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1859 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
1860 
1861 &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
1862 
1863 &lt;span class=&quot;c1&quot;&gt;# Using the values_only because you want to return the cells&amp;#39; values&lt;/span&gt;
1864 &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1865                            &lt;span class=&quot;n&quot;&gt;min_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1866                            &lt;span class=&quot;n&quot;&gt;max_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1867                            &lt;span class=&quot;n&quot;&gt;values_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1868     &lt;span class=&quot;n&quot;&gt;product_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
1869     &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
1870         &lt;span class=&quot;s2&quot;&gt;&amp;quot;parent&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
1871         &lt;span class=&quot;s2&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&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;
1872         &lt;span class=&quot;s2&quot;&gt;&amp;quot;category&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
1873     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
1874     &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;
1875 
1876 &lt;span class=&quot;c1&quot;&gt;# Using json here to be able to format the output for displaying later&lt;/span&gt;
1877 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dumps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
1878 &lt;/pre&gt;&lt;/div&gt;
1879 
1880 &lt;p&gt;The code above returns a JSON similar to this:&lt;/p&gt;
1881 &lt;div class=&quot;highlight json&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
1882   &lt;span class=&quot;nt&quot;&gt;&amp;quot;B00FALQ1ZC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
1883     &lt;span class=&quot;nt&quot;&gt;&amp;quot;parent&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;937001370&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1884     &lt;span class=&quot;nt&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Invicta Women&amp;#39;s 15150 ...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1885     &lt;span class=&quot;nt&quot;&gt;&amp;quot;category&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Watches&amp;quot;&lt;/span&gt;
1886   &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
1887   &lt;span class=&quot;nt&quot;&gt;&amp;quot;B00D3RGO20&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
1888     &lt;span class=&quot;nt&quot;&gt;&amp;quot;parent&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;484010722&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1889     &lt;span class=&quot;nt&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Kenneth Cole New York ...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
1890     &lt;span class=&quot;nt&quot;&gt;&amp;quot;category&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Watches&amp;quot;&lt;/span&gt;
1891   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
1892 &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
1893 &lt;/pre&gt;&lt;/div&gt;
1894 
1895 &lt;p&gt;Here you can see that the output is trimmed to 2 products only, but if you run the script as it is, then you should get 98 products.&lt;/p&gt;
1896 &lt;h4 id=&quot;convert-data-into-python-classes&quot;&gt;Convert Data Into Python Classes&lt;/h4&gt;
1897 &lt;p&gt;To finalize the reading section of this tutorial, let&amp;rsquo;s dive into Python classes and see how you could improve on the example above and better structure the data.&lt;/p&gt;
1898 &lt;p&gt;For this, you&amp;rsquo;ll be using the new Python &lt;a href=&quot;https://realpython.com/python-data-classes/&quot;&gt;Data Classes&lt;/a&gt; that are available from Python 3.7. If you&amp;rsquo;re using an older version of Python, then you can use the default &lt;a href=&quot;https://realpython.com/python3-object-oriented-programming/#classes-in-python&quot;&gt;Classes&lt;/a&gt; instead.&lt;/p&gt;
1899 &lt;p&gt;So, first things first, let&amp;rsquo;s look at the data you have and decide what you want to store and how you want to store it.&lt;/p&gt;
1900 &lt;p&gt;As you saw right at the start, this data comes from Amazon, and it&amp;rsquo;s a list of product reviews. You can check the &lt;a href=&quot;https://s3.amazonaws.com/amazon-reviews-pds/tsv/index.txt&quot;&gt;list of all the columns and their meaning&lt;/a&gt; on Amazon.&lt;/p&gt;
1901 &lt;p&gt;There are two significant elements you can extract from the data available:&lt;/p&gt;
1902 &lt;ol&gt;
1903 &lt;li&gt;Products&lt;/li&gt;
1904 &lt;li&gt;Reviews&lt;/li&gt;
1905 &lt;/ol&gt;
1906 &lt;p&gt;A &lt;strong&gt;Product&lt;/strong&gt; has:&lt;/p&gt;
1907 &lt;ul&gt;
1908 &lt;li&gt;ID&lt;/li&gt;
1909 &lt;li&gt;Title&lt;/li&gt;
1910 &lt;li&gt;Parent&lt;/li&gt;
1911 &lt;li&gt;Category&lt;/li&gt;
1912 &lt;/ul&gt;
1913 &lt;p&gt;The &lt;strong&gt;Review&lt;/strong&gt; has a few more fields:&lt;/p&gt;
1914 &lt;ul&gt;
1915 &lt;li&gt;ID&lt;/li&gt;
1916 &lt;li&gt;Customer ID&lt;/li&gt;
1917 &lt;li&gt;Stars&lt;/li&gt;
1918 &lt;li&gt;Headline&lt;/li&gt;
1919 &lt;li&gt;Body&lt;/li&gt;
1920 &lt;li&gt;Date&lt;/li&gt;
1921 &lt;/ul&gt;
1922 &lt;p&gt;You can ignore a few of the review fields to make things a bit simpler.&lt;/p&gt;
1923 &lt;p&gt;So, a straightforward implementation of these two classes could be written in a separate file &lt;code&gt;classes.py&lt;/code&gt;:&lt;/p&gt;
1924 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt;
1925 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;dataclasses&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataclass&lt;/span&gt;
1926 
1927 &lt;span class=&quot;nd&quot;&gt;@dataclass&lt;/span&gt;
1928 &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1929     &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
1930     &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
1931     &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
1932     &lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
1933 
1934 &lt;span class=&quot;nd&quot;&gt;@dataclass&lt;/span&gt;
1935 &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Review&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
1936     &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
1937     &lt;span class=&quot;n&quot;&gt;customer_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
1938     &lt;span class=&quot;n&quot;&gt;stars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;
1939     &lt;span class=&quot;n&quot;&gt;headline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
1940     &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
1941     &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;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;
1942 &lt;/pre&gt;&lt;/div&gt;
1943 
1944 &lt;p&gt;After defining your data classes, you need to convert the data from the spreadsheet into these new structures.&lt;/p&gt;
1945 &lt;p&gt;Before doing the conversion, it&amp;rsquo;s worth looking at our header again and creating a mapping between columns and the fields you need:&lt;/p&gt;
1946 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_row&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;
1947 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                             &lt;span class=&quot;n&quot;&gt;max_row&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;
1948 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                             &lt;span class=&quot;n&quot;&gt;values_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1949 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1950 &lt;span class=&quot;go&quot;&gt;(&amp;#39;marketplace&amp;#39;, &amp;#39;customer_id&amp;#39;, &amp;#39;review_id&amp;#39;, &amp;#39;product_id&amp;#39;, ...)&lt;/span&gt;
1951 
1952 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Or an alternative&lt;/span&gt;
1953 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
1954 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1955 &lt;span class=&quot;go&quot;&gt;marketplace&lt;/span&gt;
1956 &lt;span class=&quot;go&quot;&gt;customer_id&lt;/span&gt;
1957 &lt;span class=&quot;go&quot;&gt;review_id&lt;/span&gt;
1958 &lt;span class=&quot;go&quot;&gt;product_id&lt;/span&gt;
1959 &lt;span class=&quot;go&quot;&gt;product_parent&lt;/span&gt;
1960 &lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
1961 &lt;/pre&gt;&lt;/div&gt;
1962 
1963 &lt;p&gt;Let&amp;rsquo;s create a file &lt;code&gt;mapping.py&lt;/code&gt; where you have a list of all the field names and their column location (zero-indexed) on the spreadsheet:&lt;/p&gt;
1964 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Product fields&lt;/span&gt;
1965 &lt;span class=&quot;n&quot;&gt;PRODUCT_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
1966 &lt;span class=&quot;n&quot;&gt;PRODUCT_PARENT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
1967 &lt;span class=&quot;n&quot;&gt;PRODUCT_TITLE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
1968 &lt;span class=&quot;n&quot;&gt;PRODUCT_CATEGORY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;
1969 
1970 &lt;span class=&quot;c1&quot;&gt;# Review fields&lt;/span&gt;
1971 &lt;span class=&quot;n&quot;&gt;REVIEW_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
1972 &lt;span class=&quot;n&quot;&gt;REVIEW_CUSTOMER&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
1973 &lt;span class=&quot;n&quot;&gt;REVIEW_STARS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;
1974 &lt;span class=&quot;n&quot;&gt;REVIEW_HEADLINE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;
1975 &lt;span class=&quot;n&quot;&gt;REVIEW_BODY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;
1976 &lt;span class=&quot;n&quot;&gt;REVIEW_DATE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;
1977 &lt;/pre&gt;&lt;/div&gt;
1978 
1979 &lt;p&gt;You don&amp;rsquo;t necessarily have to do the mapping above. It&amp;rsquo;s more for readability when parsing the row data, so you don&amp;rsquo;t end up with a lot of magic numbers lying around.&lt;/p&gt;
1980 &lt;p&gt;Finally, let&amp;rsquo;s look at the code needed to parse the spreadsheet data into a list of product and review objects:&lt;/p&gt;
1981 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;
1982 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;
1983 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;classes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Review&lt;/span&gt;
1984 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mapping&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PRODUCT_ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PRODUCT_PARENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PRODUCT_TITLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; \
1985     &lt;span class=&quot;n&quot;&gt;PRODUCT_CATEGORY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;REVIEW_DATE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;REVIEW_ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;REVIEW_CUSTOMER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; \
1986     &lt;span class=&quot;n&quot;&gt;REVIEW_STARS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;REVIEW_HEADLINE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;REVIEW_BODY&lt;/span&gt;
1987 
1988 &lt;span class=&quot;c1&quot;&gt;# Using the read_only method since you&amp;#39;re not gonna be editing the spreadsheet&lt;/span&gt;
1989 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
1990 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
1991 
1992 &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
1993 &lt;span class=&quot;n&quot;&gt;reviews&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
1994 
1995 &lt;span class=&quot;c1&quot;&gt;# Using the values_only because you just want to return the cell value&lt;/span&gt;
1996 &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
1997     &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PRODUCT_ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
1998                       &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PRODUCT_PARENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
1999                       &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PRODUCT_TITLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2000                       &lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PRODUCT_CATEGORY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
2001     &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2002 
2003     &lt;span class=&quot;c1&quot;&gt;# You need to parse the date from the spreadsheet into a datetime format&lt;/span&gt;
2004     &lt;span class=&quot;n&quot;&gt;spread_date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;REVIEW_DATE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2005     &lt;span class=&quot;n&quot;&gt;parsed_date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strptime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spread_date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;%Y-%m-&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2006 
2007     &lt;span class=&quot;n&quot;&gt;review&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Review&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;REVIEW_ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2008                     &lt;span class=&quot;n&quot;&gt;customer_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;REVIEW_CUSTOMER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2009                     &lt;span class=&quot;n&quot;&gt;stars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;REVIEW_STARS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2010                     &lt;span class=&quot;n&quot;&gt;headline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;REVIEW_HEADLINE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2011                     &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;REVIEW_BODY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2012                     &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;parsed_date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2013     &lt;span class=&quot;n&quot;&gt;reviews&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;review&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2014 
2015 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
2016 &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reviews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
2017 &lt;/pre&gt;&lt;/div&gt;
2018 
2019 &lt;p&gt;After you run the code above, you should get some output like this:&lt;/p&gt;
2020 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;B00FALQ1ZC&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;937001370&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2021 &lt;span class=&quot;n&quot;&gt;Review&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;R3O9SGZBVQBV76&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;customer_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3653882&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2022 &lt;/pre&gt;&lt;/div&gt;
2023 
2024 &lt;p&gt;That&amp;rsquo;s it! Now you should have the data in a very simple and digestible class format, and you can start thinking of storing this in a &lt;a href=&quot;https://realpython.com/tutorials/databases/&quot;&gt;Database&lt;/a&gt; or any other type of data storage you like.&lt;/p&gt;
2025 &lt;p&gt;Using this kind of OOP strategy to parse spreadsheets makes handling the data much simpler later on.&lt;/p&gt;
2026 &lt;h3 id=&quot;appending-new-data&quot;&gt;Appending New Data&lt;/h3&gt;
2027 &lt;p&gt;Before you start creating very complex spreadsheets, have a quick look at an example of how to append data to an existing spreadsheet.&lt;/p&gt;
2028 &lt;p&gt;Go back to the first example spreadsheet you created (&lt;code&gt;hello_world.xlsx&lt;/code&gt;) and try opening it and appending some data to it, like this:&lt;/p&gt;
2029 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;
2030 
2031 &lt;span class=&quot;c1&quot;&gt;# Start by opening the spreadsheet and selecting the main sheet&lt;/span&gt;
2032 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;hello_world.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2033 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2034 
2035 &lt;span class=&quot;c1&quot;&gt;# Write what you want into a specific cell&lt;/span&gt;
2036 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;C1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;writing ;)&amp;quot;&lt;/span&gt;
2037 
2038 &lt;span class=&quot;c1&quot;&gt;# Save the spreadsheet&lt;/span&gt;
2039 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;hello_world_append.xlsx&amp;quot;&lt;/span&gt;
2040 &lt;/pre&gt;&lt;/div&gt;
2041 
2042 &lt;p&gt;&lt;em&gt;Et voilà&lt;/em&gt;, if you open the new &lt;code&gt;hello_world_append.xlsx&lt;/code&gt; spreadsheet, you&amp;rsquo;ll see the following change:&lt;/p&gt;
2043 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_17.44.22.e4f18e5abc42.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_17.44.22.e4f18e5abc42.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_17.44.22.e4f18e5abc42.png&amp;amp;w=540&amp;amp;sig=098886279b90048004feb6dcdbe1c66ac3e231ce 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_17.44.22.e4f18e5abc42.png&amp;amp;w=1080&amp;amp;sig=8619e04c109779499f96dcd8aee01c4cf1ed52eb 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_17.44.22.e4f18e5abc42.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Appending Data to a Spreadsheet&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2044 &lt;p&gt;Notice the additional &lt;em&gt;writing ;)&lt;/em&gt; on cell &lt;code&gt;C1&lt;/code&gt;.&lt;/p&gt;
2045 &lt;h2 id=&quot;writing-excel-spreadsheets-with-openpyxl&quot;&gt;Writing Excel Spreadsheets With openpyxl&lt;/h2&gt;
2046 &lt;p&gt;There are a lot of different things you can write to a spreadsheet, from simple text or number values to complex formulas, charts, or even images.&lt;/p&gt;
2047 &lt;p&gt;Let&amp;rsquo;s start creating some spreadsheets!&lt;/p&gt;
2048 &lt;h3 id=&quot;creating-a-simple-spreadsheet&quot;&gt;Creating a Simple Spreadsheet&lt;/h3&gt;
2049 &lt;p&gt;Previously, you saw a very quick example of how to write &amp;ldquo;Hello world!&amp;rdquo; into a spreadsheet, so you can start with that:&lt;/p&gt;
2050 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;
2051 &lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
2052 &lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;hello_world.xlsx&amp;quot;&lt;/span&gt;
2053 &lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;
2054 &lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2055 &lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2056 &lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;
2057 &lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;
2058 &lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;B1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;world!&amp;quot;&lt;/span&gt;
2059 &lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;
2060 &lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2061 &lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
2062 
2063 &lt;p&gt;The highlighted lines in the code above are the most important ones for writing. In the code, you can see that:&lt;/p&gt;
2064 &lt;ul&gt;
2065 &lt;li&gt;&lt;strong&gt;Line 5&lt;/strong&gt; shows you how to create a new empty workbook.&lt;/li&gt;
2066 &lt;li&gt;&lt;strong&gt;Lines 8 and 9&lt;/strong&gt; show you how to add data to specific cells.&lt;/li&gt;
2067 &lt;li&gt;&lt;strong&gt;Line 11&lt;/strong&gt; shows you how to save the spreadsheet when you&amp;rsquo;re done.&lt;/li&gt;
2068 &lt;/ul&gt;
2069 &lt;p&gt;Even though these lines above can be straightforward, it&amp;rsquo;s still good to know them well for when things get a bit more complicated.&lt;/p&gt;
2070 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
2071 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You&amp;rsquo;ll be using the &lt;code&gt;hello_world.xlsx&lt;/code&gt; spreadsheet for some of the upcoming examples, so keep it handy.&lt;/p&gt;
2072 &lt;/div&gt;
2073 &lt;p&gt;One thing you can do to help with coming code examples is add the following method to your Python file or console:&lt;/p&gt;
2074 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
2075 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
2076 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2077 &lt;/pre&gt;&lt;/div&gt;
2078 
2079 &lt;p&gt;It makes it easier to print all of your spreadsheet values by just calling &lt;code&gt;print_rows()&lt;/code&gt;.&lt;/p&gt;
2080 &lt;h3 id=&quot;basic-spreadsheet-operations&quot;&gt;Basic Spreadsheet Operations&lt;/h3&gt;
2081 &lt;p&gt;Before you get into the more advanced topics, it&amp;rsquo;s good for you to know how to manage the most simple elements of a spreadsheet.&lt;/p&gt;
2082 &lt;h4 id=&quot;adding-and-updating-cell-values&quot;&gt;Adding and Updating Cell Values&lt;/h4&gt;
2083 &lt;p&gt;You already learned how to add values to a spreadsheet like this:&lt;/p&gt;
2084 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;value&amp;quot;&lt;/span&gt;
2085 &lt;/pre&gt;&lt;/div&gt;
2086 
2087 &lt;p&gt;There&amp;rsquo;s another way you can do this, by first selecting a cell and then changing its value:&lt;/p&gt;
2088 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2089 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;
2090 &lt;span class=&quot;go&quot;&gt;&amp;lt;Cell &amp;#39;Sheet&amp;#39;.A1&amp;gt;&lt;/span&gt;
2091 
2092 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
2093 &lt;span class=&quot;go&quot;&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;
2094 
2095 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;hey&amp;quot;&lt;/span&gt;
2096 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
2097 &lt;span class=&quot;go&quot;&gt;&amp;#39;hey&amp;#39;&lt;/span&gt;
2098 &lt;/pre&gt;&lt;/div&gt;
2099 
2100 &lt;p&gt;The new value is only stored into the spreadsheet once you call &lt;code&gt;workbook.save()&lt;/code&gt;.&lt;/p&gt;
2101 &lt;p&gt;The &lt;code&gt;openpyxl&lt;/code&gt; creates a cell when adding a value, if that cell didn&amp;rsquo;t exist before:&lt;/p&gt;
2102 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Before, our spreadsheet has only 1 row&lt;/span&gt;
2103 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2104 &lt;span class=&quot;go&quot;&gt;(&amp;#39;hello&amp;#39;, &amp;#39;world!&amp;#39;)&lt;/span&gt;
2105 
2106 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Try adding a value to row 10&lt;/span&gt;
2107 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;B10&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;
2108 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2109 &lt;span class=&quot;go&quot;&gt;(&amp;#39;hello&amp;#39;, &amp;#39;world!&amp;#39;)&lt;/span&gt;
2110 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2111 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2112 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2113 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2114 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2115 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2116 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2117 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2118 &lt;span class=&quot;go&quot;&gt;(None, &amp;#39;test&amp;#39;)&lt;/span&gt;
2119 &lt;/pre&gt;&lt;/div&gt;
2120 
2121 &lt;p&gt;As you can see, when trying to add a value to cell &lt;code&gt;B10&lt;/code&gt;, you end up with a tuple with 10 rows, just so you can have that &lt;em&gt;test&lt;/em&gt; value.&lt;/p&gt;
2122 &lt;h4 id=&quot;managing-rows-and-columns&quot;&gt;Managing Rows and Columns&lt;/h4&gt;
2123 &lt;p&gt;One of the most common things you have to do when manipulating spreadsheets is adding or removing rows and columns. The &lt;code&gt;openpyxl&lt;/code&gt; package allows you to do that in a very straightforward way by using the methods:&lt;/p&gt;
2124 &lt;ul&gt;
2125 &lt;li&gt;&lt;code&gt;.insert_rows()&lt;/code&gt;&lt;/li&gt;
2126 &lt;li&gt;&lt;code&gt;.delete_rows()&lt;/code&gt;&lt;/li&gt;
2127 &lt;li&gt;&lt;code&gt;.insert_cols()&lt;/code&gt;&lt;/li&gt;
2128 &lt;li&gt;&lt;code&gt;.delete_cols()&lt;/code&gt;&lt;/li&gt;
2129 &lt;/ul&gt;
2130 &lt;p&gt;Every single one of those methods can receive two arguments:&lt;/p&gt;
2131 &lt;ol&gt;
2132 &lt;li&gt;&lt;code&gt;idx&lt;/code&gt;&lt;/li&gt;
2133 &lt;li&gt;&lt;code&gt;amount&lt;/code&gt;&lt;/li&gt;
2134 &lt;/ol&gt;
2135 &lt;p&gt;Using our basic &lt;code&gt;hello_world.xlsx&lt;/code&gt; example again, let&amp;rsquo;s see how these methods work:&lt;/p&gt;
2136 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2137 &lt;span class=&quot;go&quot;&gt;(&amp;#39;hello&amp;#39;, &amp;#39;world!&amp;#39;)&lt;/span&gt;
2138 
2139 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Insert a column before the existing column 1 (&amp;quot;A&amp;quot;)&lt;/span&gt;
2140 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&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;
2141 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2142 &lt;span class=&quot;go&quot;&gt;(None, &amp;#39;hello&amp;#39;, &amp;#39;world!&amp;#39;)&lt;/span&gt;
2143 
2144 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Insert 5 columns between column 2 (&amp;quot;B&amp;quot;) and 3 (&amp;quot;C&amp;quot;)&lt;/span&gt;
2145 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2146 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2147 &lt;span class=&quot;go&quot;&gt;(None, &amp;#39;hello&amp;#39;, None, None, None, None, None, &amp;#39;world!&amp;#39;)&lt;/span&gt;
2148 
2149 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Delete the created columns&lt;/span&gt;
2150 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delete_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2151 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delete_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&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;
2152 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2153 &lt;span class=&quot;go&quot;&gt;(&amp;#39;hello&amp;#39;, &amp;#39;world!&amp;#39;)&lt;/span&gt;
2154 
2155 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Insert a new row in the beginning&lt;/span&gt;
2156 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&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;
2157 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2158 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2159 &lt;span class=&quot;go&quot;&gt;(&amp;#39;hello&amp;#39;, &amp;#39;world!&amp;#39;)&lt;/span&gt;
2160 
2161 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Insert 3 new rows in the beginning&lt;/span&gt;
2162 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&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;
2163 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2164 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2165 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2166 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2167 &lt;span class=&quot;go&quot;&gt;(None, None)&lt;/span&gt;
2168 &lt;span class=&quot;go&quot;&gt;(&amp;#39;hello&amp;#39;, &amp;#39;world!&amp;#39;)&lt;/span&gt;
2169 
2170 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Delete the first 4 rows&lt;/span&gt;
2171 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delete_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2172 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2173 &lt;span class=&quot;go&quot;&gt;(&amp;#39;hello&amp;#39;, &amp;#39;world!&amp;#39;)&lt;/span&gt;
2174 &lt;/pre&gt;&lt;/div&gt;
2175 
2176 &lt;p&gt;The only thing you need to remember is that when inserting new data (rows or columns), the insertion happens &lt;strong&gt;before&lt;/strong&gt; the &lt;code&gt;idx&lt;/code&gt; parameter.&lt;/p&gt;
2177 &lt;p&gt;So, if you do &lt;code&gt;insert_rows(1)&lt;/code&gt;, it inserts a new row &lt;strong&gt;before&lt;/strong&gt; the existing first row.&lt;/p&gt;
2178 &lt;p&gt;It&amp;rsquo;s the same for columns: when you call &lt;code&gt;insert_cols(2)&lt;/code&gt;, it inserts a new column right &lt;strong&gt;before&lt;/strong&gt; the already existing second column (&lt;code&gt;B&lt;/code&gt;).&lt;/p&gt;
2179 &lt;p&gt;However, when deleting rows or columns, &lt;code&gt;.delete_...&lt;/code&gt; deletes data &lt;strong&gt;starting from&lt;/strong&gt; the index passed as an argument.&lt;/p&gt;
2180 &lt;p&gt;For example, when doing &lt;code&gt;delete_rows(2)&lt;/code&gt; it deletes row &lt;code&gt;2&lt;/code&gt;, and when doing &lt;code&gt;delete_cols(3)&lt;/code&gt; it deletes the third column (&lt;code&gt;C&lt;/code&gt;).&lt;/p&gt;
2181 &lt;h4 id=&quot;managing-sheets&quot;&gt;Managing Sheets&lt;/h4&gt;
2182 &lt;p&gt;Sheet management is also one of those things you might need to know, even though it might be something that you don&amp;rsquo;t use that often.&lt;/p&gt;
2183 &lt;p&gt;If you look back at the code examples from this tutorial, you&amp;rsquo;ll notice the following recurring piece of code:&lt;/p&gt;
2184 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2185 &lt;/pre&gt;&lt;/div&gt;
2186 
2187 &lt;p&gt;This is the way to select the default sheet from a spreadsheet. However, if you&amp;rsquo;re opening a spreadsheet with multiple sheets, then you can always select a specific one like this:&lt;/p&gt;
2188 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Let&amp;#39;s say you have two sheets: &amp;quot;Products&amp;quot; and &amp;quot;Company Sales&amp;quot;&lt;/span&gt;
2189 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheetnames&lt;/span&gt;
2190 &lt;span class=&quot;go&quot;&gt;[&amp;#39;Products&amp;#39;, &amp;#39;Company Sales&amp;#39;]&lt;/span&gt;
2191 
2192 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# You can select a sheet using its title&lt;/span&gt;
2193 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products_sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Products&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2194 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sales_sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Company Sales&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2195 &lt;/pre&gt;&lt;/div&gt;
2196 
2197 &lt;p&gt;You can also change a sheet title very easily:&lt;/p&gt;
2198 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheetnames&lt;/span&gt;
2199 &lt;span class=&quot;go&quot;&gt;[&amp;#39;Products&amp;#39;, &amp;#39;Company Sales&amp;#39;]&lt;/span&gt;
2200 
2201 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products_sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Products&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2202 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products_sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;New Products&amp;quot;&lt;/span&gt;
2203 
2204 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheetnames&lt;/span&gt;
2205 &lt;span class=&quot;go&quot;&gt;[&amp;#39;New Products&amp;#39;, &amp;#39;Company Sales&amp;#39;]&lt;/span&gt;
2206 &lt;/pre&gt;&lt;/div&gt;
2207 
2208 &lt;p&gt;If you want to create or delete sheets, then you can also do that with &lt;code&gt;.create_sheet()&lt;/code&gt; and &lt;code&gt;.remove()&lt;/code&gt;:&lt;/p&gt;
2209 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheetnames&lt;/span&gt;
2210 &lt;span class=&quot;go&quot;&gt;[&amp;#39;Products&amp;#39;, &amp;#39;Company Sales&amp;#39;]&lt;/span&gt;
2211 
2212 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operations_sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Operations&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2213 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheetnames&lt;/span&gt;
2214 &lt;span class=&quot;go&quot;&gt;[&amp;#39;Products&amp;#39;, &amp;#39;Company Sales&amp;#39;, &amp;#39;Operations&amp;#39;]&lt;/span&gt;
2215 
2216 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# You can also define the position to create the sheet at&lt;/span&gt;
2217 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hr_sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;HR&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2218 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheetnames&lt;/span&gt;
2219 &lt;span class=&quot;go&quot;&gt;[&amp;#39;HR&amp;#39;, &amp;#39;Products&amp;#39;, &amp;#39;Company Sales&amp;#39;, &amp;#39;Operations&amp;#39;]&lt;/span&gt;
2220 
2221 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# To remove them, just pass the sheet as an argument to the .remove()&lt;/span&gt;
2222 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operations_sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2223 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheetnames&lt;/span&gt;
2224 &lt;span class=&quot;go&quot;&gt;[&amp;#39;HR&amp;#39;, &amp;#39;Products&amp;#39;, &amp;#39;Company Sales&amp;#39;]&lt;/span&gt;
2225 
2226 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hr_sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2227 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheetnames&lt;/span&gt;
2228 &lt;span class=&quot;go&quot;&gt;[&amp;#39;Products&amp;#39;, &amp;#39;Company Sales&amp;#39;]&lt;/span&gt;
2229 &lt;/pre&gt;&lt;/div&gt;
2230 
2231 &lt;p&gt;One other thing you can do is make duplicates of a sheet using &lt;code&gt;copy_worksheet()&lt;/code&gt;:&lt;/p&gt;
2232 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheetnames&lt;/span&gt;
2233 &lt;span class=&quot;go&quot;&gt;[&amp;#39;Products&amp;#39;, &amp;#39;Company Sales&amp;#39;]&lt;/span&gt;
2234 
2235 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products_sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Products&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2236 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;copy_worksheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products_sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2237 &lt;span class=&quot;go&quot;&gt;&amp;lt;Worksheet &amp;quot;Products Copy&amp;quot;&amp;gt;&lt;/span&gt;
2238 
2239 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheetnames&lt;/span&gt;
2240 &lt;span class=&quot;go&quot;&gt;[&amp;#39;Products&amp;#39;, &amp;#39;Company Sales&amp;#39;, &amp;#39;Products Copy&amp;#39;]&lt;/span&gt;
2241 &lt;/pre&gt;&lt;/div&gt;
2242 
2243 &lt;p&gt;If you open your spreadsheet after saving the above code, you&amp;rsquo;ll notice that the sheet &lt;em&gt;Products Copy&lt;/em&gt; is a duplicate of the sheet &lt;em&gt;Products&lt;/em&gt;.&lt;/p&gt;
2244 &lt;h4 id=&quot;freezing-rows-and-columns&quot;&gt;Freezing Rows and Columns&lt;/h4&gt;
2245 &lt;p&gt;Something that you might want to do when working with big spreadsheets is to freeze a few rows or columns, so they remain visible when you scroll right or down.&lt;/p&gt;
2246 &lt;p&gt;Freezing data allows you to keep an eye on important rows or columns, regardless of where you scroll in the spreadsheet.&lt;/p&gt;
2247 &lt;p&gt;Again, &lt;code&gt;openpyxl&lt;/code&gt; also has a way to accomplish this by using the worksheet &lt;code&gt;freeze_panes&lt;/code&gt; attribute. For this example, go back to our &lt;code&gt;sample.xlsx&lt;/code&gt; spreadsheet and try doing the following:&lt;/p&gt;
2248 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2249 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2250 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freeze_panes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;C2&amp;quot;&lt;/span&gt;
2251 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_frozen.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2252 &lt;/pre&gt;&lt;/div&gt;
2253 
2254 &lt;p&gt;If you open the &lt;code&gt;sample_frozen.xlsx&lt;/code&gt; spreadsheet in your favorite spreadsheet editor, you&amp;rsquo;ll notice that row &lt;code&gt;1&lt;/code&gt; and columns &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; are frozen and are always visible no matter where you navigate within the spreadsheet.&lt;/p&gt;
2255 &lt;p&gt;This feature is handy, for example, to keep headers within sight, so you always know what each column represents.&lt;/p&gt;
2256 &lt;p&gt;Here&amp;rsquo;s how it looks in the editor:&lt;/p&gt;
2257 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.12.20.55694a0781f8.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.12.20.55694a0781f8.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.12.20.55694a0781f8.png&amp;amp;w=540&amp;amp;sig=5826de23e5df2e08d625844698fc3a29b32ee7b2 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.12.20.55694a0781f8.png&amp;amp;w=1080&amp;amp;sig=c3abe2321f00372d975bbbf033f3ebe3687eb09f 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_18.12.20.55694a0781f8.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Frozen Rows and Columns&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2258 &lt;p&gt;Notice how you&amp;rsquo;re at the end of the spreadsheet, and yet, you can see both row &lt;code&gt;1&lt;/code&gt; and columns &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;
2259 &lt;h4 id=&quot;adding-filters&quot;&gt;Adding Filters&lt;/h4&gt;
2260 &lt;p&gt;You can use &lt;code&gt;openpyxl&lt;/code&gt; to add filters and sorts to your spreadsheet. However, when you open the spreadsheet, the data won&amp;rsquo;t be rearranged according to these sorts and filters.&lt;/p&gt;
2261 &lt;p&gt;At first, this might seem like a pretty useless feature, but when you&amp;rsquo;re programmatically creating a spreadsheet that is going to be sent and used by somebody else, it&amp;rsquo;s still nice to at least create the filters and allow people to use it afterward.&lt;/p&gt;
2262 &lt;p&gt;The code below is an example of how you would add some filters to our existing &lt;code&gt;sample.xlsx&lt;/code&gt; spreadsheet:&lt;/p&gt;
2263 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Check the used spreadsheet space using the attribute &amp;quot;dimensions&amp;quot;&lt;/span&gt;
2264 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dimensions&lt;/span&gt;
2265 &lt;span class=&quot;go&quot;&gt;&amp;#39;A1:O100&amp;#39;&lt;/span&gt;
2266 
2267 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auto_filter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;A1:O100&amp;quot;&lt;/span&gt;
2268 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_with_filters.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2269 &lt;/pre&gt;&lt;/div&gt;
2270 
2271 &lt;p&gt;You should now see the filters created when opening the spreadsheet in your editor:&lt;/p&gt;
2272 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.20.35.5fdbfe805194.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.20.35.5fdbfe805194.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.20.35.5fdbfe805194.png&amp;amp;w=540&amp;amp;sig=c1d7ad4f2dfc03fc8730e3babf9000ac74170c7d 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.20.35.5fdbfe805194.png&amp;amp;w=1080&amp;amp;sig=27e888a967ddc112f1e824be671a15e2c111fe6c 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_18.20.35.5fdbfe805194.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Filters&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2273 &lt;p&gt;You don&amp;rsquo;t have to use &lt;code&gt;sheet.dimensions&lt;/code&gt; if you know precisely which part of the spreadsheet you want to apply filters to.&lt;/p&gt;
2274 &lt;h3 id=&quot;adding-formulas&quot;&gt;Adding Formulas&lt;/h3&gt;
2275 &lt;p&gt;&lt;strong&gt;Formulas&lt;/strong&gt; (or &lt;strong&gt;formulae&lt;/strong&gt;) are one of the most powerful features of spreadsheets.&lt;/p&gt;
2276 &lt;p&gt;They gives you the power to apply specific mathematical equations to a range of cells. Using formulas with &lt;code&gt;openpyxl&lt;/code&gt; is as simple as editing the value of a cell.&lt;/p&gt;
2277 &lt;p&gt;You can see the list of formulas supported by &lt;code&gt;openpyxl&lt;/code&gt;:&lt;/p&gt;
2278 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;openpyxl.utils&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FORMULAE&lt;/span&gt;
2279 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FORMULAE&lt;/span&gt;
2280 &lt;span class=&quot;go&quot;&gt;frozenset({&amp;#39;ABS&amp;#39;,&lt;/span&gt;
2281 &lt;span class=&quot;go&quot;&gt;           &amp;#39;ACCRINT&amp;#39;,&lt;/span&gt;
2282 &lt;span class=&quot;go&quot;&gt;           &amp;#39;ACCRINTM&amp;#39;,&lt;/span&gt;
2283 &lt;span class=&quot;go&quot;&gt;           &amp;#39;ACOS&amp;#39;,&lt;/span&gt;
2284 &lt;span class=&quot;go&quot;&gt;           &amp;#39;ACOSH&amp;#39;,&lt;/span&gt;
2285 &lt;span class=&quot;go&quot;&gt;           &amp;#39;AMORDEGRC&amp;#39;,&lt;/span&gt;
2286 &lt;span class=&quot;go&quot;&gt;           &amp;#39;AMORLINC&amp;#39;,&lt;/span&gt;
2287 &lt;span class=&quot;go&quot;&gt;           &amp;#39;AND&amp;#39;,&lt;/span&gt;
2288 &lt;span class=&quot;go&quot;&gt;           ...&lt;/span&gt;
2289 &lt;span class=&quot;go&quot;&gt;           &amp;#39;YEARFRAC&amp;#39;,&lt;/span&gt;
2290 &lt;span class=&quot;go&quot;&gt;           &amp;#39;YIELD&amp;#39;,&lt;/span&gt;
2291 &lt;span class=&quot;go&quot;&gt;           &amp;#39;YIELDDISC&amp;#39;,&lt;/span&gt;
2292 &lt;span class=&quot;go&quot;&gt;           &amp;#39;YIELDMAT&amp;#39;,&lt;/span&gt;
2293 &lt;span class=&quot;go&quot;&gt;           &amp;#39;ZTEST&amp;#39;})&lt;/span&gt;
2294 &lt;/pre&gt;&lt;/div&gt;
2295 
2296 &lt;p&gt;Let&amp;rsquo;s add some formulas to our &lt;code&gt;sample.xlsx&lt;/code&gt; spreadsheet.&lt;/p&gt;
2297 &lt;p&gt;Starting with something easy, let&amp;rsquo;s check the average star rating for the 99 reviews within the spreadsheet:&lt;/p&gt;
2298 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Star rating is column &amp;quot;H&amp;quot;&lt;/span&gt;
2299 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;P2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;=AVERAGE(H2:H100)&amp;quot;&lt;/span&gt;
2300 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_formulas.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2301 &lt;/pre&gt;&lt;/div&gt;
2302 
2303 &lt;p&gt;If you open the spreadsheet now and go to cell &lt;code&gt;P2&lt;/code&gt;, you should see that its value is: &lt;em&gt;4.18181818181818&lt;/em&gt;. Have a look in the editor:&lt;/p&gt;
2304 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.33.09.7c2633f706cc.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.33.09.7c2633f706cc.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.33.09.7c2633f706cc.png&amp;amp;w=540&amp;amp;sig=5d7a9eb97acf524d5d2b9b93ae0e9214bbcf95c8 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.33.09.7c2633f706cc.png&amp;amp;w=1080&amp;amp;sig=8af67321cb101fb2f30fd0ca2bdcc62de35c9334 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_18.33.09.7c2633f706cc.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Average Formula&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2305 &lt;p&gt;You can use the same methodology to add any formulas to your spreadsheet. For example, let&amp;rsquo;s count the number of reviews that had helpful votes:&lt;/p&gt;
2306 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# The helpful votes are counted on column &amp;quot;I&amp;quot;&lt;/span&gt;
2307 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;P3&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;=COUNTIF(I2:I100, &amp;quot;&amp;gt;0&amp;quot;)&amp;#39;&lt;/span&gt;
2308 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_formulas.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2309 &lt;/pre&gt;&lt;/div&gt;
2310 
2311 &lt;p&gt;You should get the number &lt;code&gt;21&lt;/code&gt; on your &lt;code&gt;P3&lt;/code&gt; spreadsheet cell like so:&lt;/p&gt;
2312 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.35.24.e26e97b0c9c0.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.35.24.e26e97b0c9c0.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.35.24.e26e97b0c9c0.png&amp;amp;w=540&amp;amp;sig=0ec4c4c12a792a1a393e0273855282bfa0594d53 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.35.24.e26e97b0c9c0.png&amp;amp;w=1080&amp;amp;sig=67b399b8cb79ddbe7285da0325fe8f6b9edf3ecc 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_18.35.24.e26e97b0c9c0.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Average and CountIf Formula&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2313 &lt;p&gt;You&amp;rsquo;ll have to make sure that the strings within a formula are always in double quotes, so you either have to use single quotes around the formula like in the example above or you&amp;rsquo;ll have to escape the double quotes inside the formula: &lt;code&gt;&quot;=COUNTIF(I2:I100, \&quot;&amp;gt;0\&quot;)&quot;&lt;/code&gt;.&lt;/p&gt;
2314 &lt;p&gt;There are a ton of other formulas you can add to your spreadsheet using the same procedure you tried above. Give it a go yourself!&lt;/p&gt;
2315 &lt;h3 id=&quot;adding-styles&quot;&gt;Adding Styles&lt;/h3&gt;
2316 &lt;p&gt;Even though styling a spreadsheet might not be something you would do every day, it&amp;rsquo;s still good to know how to do it.&lt;/p&gt;
2317 &lt;p&gt;Using &lt;code&gt;openpyxl&lt;/code&gt;, you can apply multiple styling options to your spreadsheet, including fonts, borders, colors, and so on. Have a look at the &lt;code&gt;openpyxl&lt;/code&gt; &lt;a href=&quot;https://openpyxl.readthedocs.io/en/stable/styles.html&quot;&gt;documentation&lt;/a&gt; to learn more.&lt;/p&gt;
2318 &lt;p&gt;You can also choose to either apply a style directly to a cell or create a template and reuse it to apply styles to multiple cells.&lt;/p&gt;
2319 &lt;p&gt;Let&amp;rsquo;s start by having a look at simple cell styling, using our &lt;code&gt;sample.xlsx&lt;/code&gt; again as the base spreadsheet:&lt;/p&gt;
2320 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Import necessary style classes&lt;/span&gt;
2321 &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;nn&quot;&gt;openpyxl.styles&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Font&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Alignment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Border&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Side&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt;
2322 
2323 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Create a few styles&lt;/span&gt;
2324 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bold_font&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Font&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bold&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2325 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;big_red_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Font&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&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;
2326 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;center_aligned_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Alignment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;horizontal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;center&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2327 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;double_border_side&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Side&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;border_style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;double&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2328 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;square_border&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Border&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;double_border_side&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2329 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                       &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;double_border_side&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2330 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                       &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;double_border_side&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2331 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                       &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;double_border_side&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2332 
2333 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Style some cells!&lt;/span&gt;
2334 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;font&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bold_font&lt;/span&gt;
2335 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A3&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;font&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;big_red_text&lt;/span&gt;
2336 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A4&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alignment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center_aligned_text&lt;/span&gt;
2337 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A5&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;border&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;square_border&lt;/span&gt;
2338 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_styles.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2339 &lt;/pre&gt;&lt;/div&gt;
2340 
2341 &lt;p&gt;If you open your spreadsheet now, you should see quite a few different styles on the first 5 cells of column &lt;code&gt;A&lt;/code&gt;:&lt;/p&gt;
2342 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.43.15.e3aeb3fb06e3.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.43.15.e3aeb3fb06e3.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.43.15.e3aeb3fb06e3.png&amp;amp;w=540&amp;amp;sig=ecc21878006697a6135ae515442642a95ab2bfb6 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.43.15.e3aeb3fb06e3.png&amp;amp;w=1080&amp;amp;sig=6f0ef4a148f1ca5a588e0cb2c02b0c9aad4246f2 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_18.43.15.e3aeb3fb06e3.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Simple Cell Styles&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2343 &lt;p&gt;There you go. You got:&lt;/p&gt;
2344 &lt;ul&gt;
2345 &lt;li&gt;&lt;strong&gt;A2&lt;/strong&gt; with the text in bold&lt;/li&gt;
2346 &lt;li&gt;&lt;strong&gt;A3&lt;/strong&gt; with the text in red and bigger font size&lt;/li&gt;
2347 &lt;li&gt;&lt;strong&gt;A4&lt;/strong&gt; with the text centered&lt;/li&gt;
2348 &lt;li&gt;&lt;strong&gt;A5&lt;/strong&gt; with a square border around the text&lt;/li&gt;
2349 &lt;/ul&gt;
2350 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
2351 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For the colors, you can also use HEX codes instead by doing  &lt;code&gt;Font(color=&quot;C70E0F&quot;)&lt;/code&gt;.&lt;/p&gt;
2352 &lt;/div&gt;
2353 &lt;p&gt;You can also combine styles by simply adding them to the cell at the same time:&lt;/p&gt;
2354 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Reusing the same styles from the example above&lt;/span&gt;
2355 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A6&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alignment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center_aligned_text&lt;/span&gt;
2356 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A6&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;font&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;big_red_text&lt;/span&gt;
2357 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A6&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;border&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;square_border&lt;/span&gt;
2358 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_styles.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2359 &lt;/pre&gt;&lt;/div&gt;
2360 
2361 &lt;p&gt;Have a look at cell &lt;code&gt;A6&lt;/code&gt; here:&lt;/p&gt;
2362 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.46.04.314517930065.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.46.04.314517930065.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.46.04.314517930065.png&amp;amp;w=540&amp;amp;sig=290bbf523eb24ac8c9741daf86701ca57cad4b96 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.46.04.314517930065.png&amp;amp;w=1080&amp;amp;sig=9decedef154c2138e26b287f2186213142650f6e 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_18.46.04.314517930065.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Coupled Cell Styles&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2363 &lt;p&gt;When you want to apply multiple styles to one or several cells, you can use a &lt;code&gt;NamedStyle&lt;/code&gt; class instead, which is like a style template that you can use over and over again. Have a look at the example below:&lt;/p&gt;
2364 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;openpyxl.styles&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NamedStyle&lt;/span&gt;
2365 
2366 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Let&amp;#39;s create a style template for the header row&lt;/span&gt;
2367 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NamedStyle&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;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;header&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2368 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;font&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Font&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bold&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2369 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;border&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Border&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Side&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;border_style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;thin&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
2370 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alignment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Alignment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;horizontal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;center&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vertical&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;center&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2371 
2372 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Now let&amp;#39;s apply this to all first row (header) cells&lt;/span&gt;
2373 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header_row&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2374 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header_row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
2375 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;style&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;
2376 
2377 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_styles.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2378 &lt;/pre&gt;&lt;/div&gt;
2379 
2380 &lt;p&gt;If you open the spreadsheet now, you should see that its first row is bold, the text is aligned to the center, and there&amp;rsquo;s a small bottom border! Have a look below:&lt;/p&gt;
2381 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.48.33.4bc57d1b24d5.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.48.33.4bc57d1b24d5.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.48.33.4bc57d1b24d5.png&amp;amp;w=540&amp;amp;sig=199107a0c9ea60fbf1dfcc078a7680b43faeef3a 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.48.33.4bc57d1b24d5.png&amp;amp;w=1080&amp;amp;sig=af3e5225e36a24dea088e8c175da02050bb5dda9 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_18.48.33.4bc57d1b24d5.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Named Styles&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2382 &lt;p&gt;As you saw above, there are many options when it comes to styling, and it depends on the use case, so feel free to check &lt;code&gt;openpyxl&lt;/code&gt; &lt;a href=&quot;https://openpyxl.readthedocs.io/en/stable/styles.html&quot;&gt;documentation&lt;/a&gt; and see what other things you can do.&lt;/p&gt;
2383 &lt;h3 id=&quot;conditional-formatting&quot;&gt;Conditional Formatting&lt;/h3&gt;
2384 &lt;p&gt;This feature is one of my personal favorites when it comes to adding styles to a spreadsheet.&lt;/p&gt;
2385 &lt;p&gt;It&amp;rsquo;s a much more powerful approach to styling because it dynamically applies styles according to how the data in the spreadsheet changes.&lt;/p&gt;
2386 &lt;p&gt;In a nutshell, &lt;strong&gt;conditional formatting&lt;/strong&gt; allows you to specify a list of styles to apply to a cell (or cell range) according to specific conditions.&lt;/p&gt;
2387 &lt;p&gt;For example, a widespread use case is to have a balance sheet where all the negative totals are in red, and the positive ones are in green. This formatting makes it much more efficient to spot good vs bad periods.&lt;/p&gt;
2388 &lt;p&gt;Without further ado, let&amp;rsquo;s pick our favorite spreadsheet&amp;mdash;&lt;code&gt;sample.xlsx&lt;/code&gt;&amp;mdash;and add some conditional formatting.&lt;/p&gt;
2389 &lt;p&gt;You can start by adding a simple one that adds a red background to all reviews with less than 3 stars:&lt;/p&gt;
2390 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;openpyxl.styles&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PatternFill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt;
2391 &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;nn&quot;&gt;openpyxl.styles.differential&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DifferentialStyle&lt;/span&gt;
2392 &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;nn&quot;&gt;openpyxl.formatting.rule&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Rule&lt;/span&gt;
2393 
2394 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;red_background&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PatternFill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bgColor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2395 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;diff_style&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DifferentialStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;red_background&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2396 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Rule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;expression&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dxf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;diff_style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2397 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;formula&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;$H1&amp;lt;3&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2398 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conditional_formatting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A1:O100&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2399 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_conditional_formatting.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2400 &lt;/pre&gt;&lt;/div&gt;
2401 
2402 &lt;p&gt;Now you&amp;rsquo;ll see all the reviews with a star rating below 3 marked with a red background:&lt;/p&gt;
2403 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.55.41.17f234a186c6.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_18.55.41.17f234a186c6.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.55.41.17f234a186c6.png&amp;amp;w=540&amp;amp;sig=f3c141c2fe708c031c32c083cb038a736fd8da87 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_18.55.41.17f234a186c6.png&amp;amp;w=1080&amp;amp;sig=9ded3045cee09d34cd6f5dada7a4eea669ac4808 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_18.55.41.17f234a186c6.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Simple Conditional Formatting&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2404 &lt;p&gt;Code-wise, the only things that are new here are the objects &lt;code&gt;DifferentialStyle&lt;/code&gt; and &lt;code&gt;Rule&lt;/code&gt;:&lt;/p&gt;
2405 &lt;ul&gt;
2406 &lt;li&gt;&lt;strong&gt;&lt;code&gt;DifferentialStyle&lt;/code&gt;&lt;/strong&gt; is quite similar to &lt;code&gt;NamedStyle&lt;/code&gt;, which you already saw above, and it&amp;rsquo;s used to aggregate multiple styles such as fonts, borders, alignment, and so forth.&lt;/li&gt;
2407 &lt;li&gt;&lt;strong&gt;&lt;code&gt;Rule&lt;/code&gt;&lt;/strong&gt; is responsible for selecting the cells and applying the styles if the cells match the rule&amp;rsquo;s logic.&lt;/li&gt;
2408 &lt;/ul&gt;
2409 &lt;p&gt;Using a &lt;code&gt;Rule&lt;/code&gt; object, you can create numerous conditional formatting scenarios.&lt;/p&gt;
2410 &lt;p&gt;However, for simplicity sake, the &lt;code&gt;openpyxl&lt;/code&gt; package offers 3 built-in formats that make it easier to create a few common conditional formatting patterns. These built-ins are:&lt;/p&gt;
2411 &lt;ul&gt;
2412 &lt;li&gt;&lt;code&gt;ColorScale&lt;/code&gt;&lt;/li&gt;
2413 &lt;li&gt;&lt;code&gt;IconSet&lt;/code&gt;&lt;/li&gt;
2414 &lt;li&gt;&lt;code&gt;DataBar&lt;/code&gt;&lt;/li&gt;
2415 &lt;/ul&gt;
2416 &lt;p&gt;The &lt;strong&gt;ColorScale&lt;/strong&gt; gives you the ability to create color gradients:&lt;/p&gt;
2417 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;openpyxl.formatting.rule&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ColorScaleRule&lt;/span&gt;
2418 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color_scale_rule&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ColorScaleRule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;min&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2419 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                  &lt;span class=&quot;n&quot;&gt;start_color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2420 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                  &lt;span class=&quot;n&quot;&gt;end_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;max&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2421 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                  &lt;span class=&quot;n&quot;&gt;end_color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GREEN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2422 
2423 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Again, let&amp;#39;s add this gradient to the star ratings, column &amp;quot;H&amp;quot;&lt;/span&gt;
2424 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conditional_formatting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;H2:H100&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;color_scale_rule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2425 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_conditional_formatting_color_scale.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2426 &lt;/pre&gt;&lt;/div&gt;
2427 
2428 &lt;p&gt;Now you should see a color gradient on column &lt;code&gt;H&lt;/code&gt;, from red to green, according to the star rating:&lt;/p&gt;
2429 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_19.00.57.26756963c1e9.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_19.00.57.26756963c1e9.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_19.00.57.26756963c1e9.png&amp;amp;w=540&amp;amp;sig=782964d150a8adc1de811fab78b0accde6357f85 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_19.00.57.26756963c1e9.png&amp;amp;w=1080&amp;amp;sig=4c7c87c194ec0a8eb3a9e73fdabf3ead991e96ea 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_19.00.57.26756963c1e9.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Color Scale Conditional Formatting&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2430 &lt;p&gt;You can also add a third color and make two gradients instead:&lt;/p&gt;
2431 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;openpyxl.formatting.rule&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ColorScaleRule&lt;/span&gt;
2432 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color_scale_rule&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ColorScaleRule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;num&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2433 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                  &lt;span class=&quot;n&quot;&gt;start_value&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;
2434 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                  &lt;span class=&quot;n&quot;&gt;start_color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2435 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                  &lt;span class=&quot;n&quot;&gt;mid_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;num&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2436 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                  &lt;span class=&quot;n&quot;&gt;mid_value&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;
2437 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                  &lt;span class=&quot;n&quot;&gt;mid_color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;YELLOW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2438 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                  &lt;span class=&quot;n&quot;&gt;end_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;num&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2439 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                  &lt;span class=&quot;n&quot;&gt;end_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2440 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                                  &lt;span class=&quot;n&quot;&gt;end_color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GREEN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2441 
2442 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Again, let&amp;#39;s add this gradient to the star ratings, column &amp;quot;H&amp;quot;&lt;/span&gt;
2443 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conditional_formatting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;H2:H100&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;color_scale_rule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2444 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_conditional_formatting_color_scale_3.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2445 &lt;/pre&gt;&lt;/div&gt;
2446 
2447 &lt;p&gt;This time, you&amp;rsquo;ll notice that star ratings between 1 and 3 have a gradient from red to yellow, and star ratings between 3 and 5 have a gradient from yellow to green:&lt;/p&gt;
2448 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_19.03.30.0de9a2ff9866.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_19.03.30.0de9a2ff9866.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_19.03.30.0de9a2ff9866.png&amp;amp;w=540&amp;amp;sig=17daddc356c8ff5c78497b200fe57ab69f80617d 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_19.03.30.0de9a2ff9866.png&amp;amp;w=1080&amp;amp;sig=6dcb18f4aa3f8ae0a395ca1e3581f8d4c59805ad 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_19.03.30.0de9a2ff9866.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With 2 Color Scales Conditional Formatting&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2449 &lt;p&gt;The &lt;strong&gt;IconSet&lt;/strong&gt; allows you to add an icon to the cell according to its value:&lt;/p&gt;
2450 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;openpyxl.formatting.rule&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IconSetRule&lt;/span&gt;
2451 
2452 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;icon_set_rule&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IconSetRule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;5Arrows&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;num&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
2453 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conditional_formatting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;H2:H100&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;icon_set_rule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2454 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_conditional_formatting_icon_set.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2455 &lt;/pre&gt;&lt;/div&gt;
2456 
2457 &lt;p&gt;You&amp;rsquo;ll see a colored arrow next to the star rating. This arrow is red and points down when the value of the cell is 1 and, as the rating gets better, the arrow starts pointing up and becomes green:&lt;/p&gt;
2458 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_19.07.29.23e75ff46771.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_19.07.29.23e75ff46771.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_19.07.29.23e75ff46771.png&amp;amp;w=540&amp;amp;sig=388fc68ff53fa2e2d3d5678acfd41f10fa8eccde 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_19.07.29.23e75ff46771.png&amp;amp;w=1080&amp;amp;sig=e33f483f9758189782bb619a6714c948130375aa 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_19.07.29.23e75ff46771.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Icon Set Conditional Formatting&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2459 &lt;p&gt;The &lt;code&gt;openpyxl&lt;/code&gt; package has a &lt;a href=&quot;https://openpyxl.readthedocs.io/en/stable/formatting.html#iconset&quot;&gt;full list&lt;/a&gt; of other icons you can use, besides the arrow.&lt;/p&gt;
2460 &lt;p&gt;Finally, the &lt;strong&gt;DataBar&lt;/strong&gt; allows you to create progress bars:&lt;/p&gt;
2461 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;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;nn&quot;&gt;openpyxl.formatting.rule&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataBarRule&lt;/span&gt;
2462 
2463 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data_bar_rule&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataBarRule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;num&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2464 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                            &lt;span class=&quot;n&quot;&gt;start_value&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;
2465 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                            &lt;span class=&quot;n&quot;&gt;end_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;num&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2466 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                            &lt;span class=&quot;n&quot;&gt;end_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;5&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2467 &lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                            &lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GREEN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2468 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conditional_formatting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;H2:H100&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_bar_rule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2469 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample_conditional_formatting_data_bar.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2470 &lt;/pre&gt;&lt;/div&gt;
2471 
2472 &lt;p&gt;You&amp;rsquo;ll now see a green progress bar that gets fuller the closer the star rating is to the number 5:&lt;/p&gt;
2473 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_19.09.10.ebbe032c088d.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_19.09.10.ebbe032c088d.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_19.09.10.ebbe032c088d.png&amp;amp;w=540&amp;amp;sig=a7b8e3515fde3ff6b662ff1780cbc290da9ce2ad 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_19.09.10.ebbe032c088d.png&amp;amp;w=1080&amp;amp;sig=1e3d2befc147a43c5b98061cf5888abf22ca4c4a 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_19.09.10.ebbe032c088d.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Data Bar Conditional Formatting&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2474 &lt;p&gt;As you can see, there are a lot of cool things you can do with conditional formatting.&lt;/p&gt;
2475 &lt;p&gt;Here, you saw only a few examples of what you can achieve with it, but check the &lt;code&gt;openpyxl&lt;/code&gt; &lt;a href=&quot;https://openpyxl.readthedocs.io/en/stable/formatting.html&quot;&gt;documentation&lt;/a&gt; to see a bunch of other options.&lt;/p&gt;
2476 &lt;h3 id=&quot;adding-images&quot;&gt;Adding Images&lt;/h3&gt;
2477 &lt;p&gt;Even though images are not something that you&amp;rsquo;ll often see in a spreadsheet, it&amp;rsquo;s quite cool to be able to add them. Maybe you can use it for branding purposes or to make spreadsheets more personal.&lt;/p&gt;
2478 &lt;p&gt;To be able to load images to a spreadsheet using &lt;code&gt;openpyxl&lt;/code&gt;, you&amp;rsquo;ll have to install &lt;code&gt;Pillow&lt;/code&gt;:&lt;/p&gt;
2479 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; pip install Pillow
2480 &lt;/pre&gt;&lt;/div&gt;
2481 
2482 &lt;p&gt;Apart from that, you&amp;rsquo;ll also need an image. For this example, you can grab the &lt;em&gt;Real Python&lt;/em&gt; logo below and convert it from &lt;code&gt;.webp&lt;/code&gt; to &lt;code&gt;.png&lt;/code&gt; using an online converter such as &lt;a href=&quot;https://cloudconvert.com/webp-to-png&quot;&gt;cloudconvert.com&lt;/a&gt;, save the final file as &lt;code&gt;logo.png&lt;/code&gt;, and copy it to the root folder where you&amp;rsquo;re running your examples:&lt;/p&gt;
2483 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/real-python-logo-round.4d95338e8944.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-25&quot; src=&quot;https://files.realpython.com/media/real-python-logo-round.4d95338e8944.png&quot; width=&quot;1500&quot; height=&quot;1500&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/real-python-logo-round.4d95338e8944.png&amp;amp;w=375&amp;amp;sig=e431a39c9d7f2d5963a81687571a41288c359142 375w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/real-python-logo-round.4d95338e8944.png&amp;amp;w=750&amp;amp;sig=a098752adfc378feee6bc69748af593ed078b8c0 750w, https://files.realpython.com/media/real-python-logo-round.4d95338e8944.png 1500w&quot; sizes=&quot;75vw&quot; alt=&quot;Real Python Logo&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2484 &lt;p&gt;Afterward, this is the code you need to import that image into the &lt;code&gt;hello_word.xlsx&lt;/code&gt; spreadsheet:&lt;/p&gt;
2485 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;
2486 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl.drawing.image&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;
2487 
2488 &lt;span class=&quot;c1&quot;&gt;# Let&amp;#39;s use the hello_world spreadsheet since it has less data&lt;/span&gt;
2489 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;hello_world.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2490 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2491 
2492 &lt;span class=&quot;n&quot;&gt;logo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;logo.png&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2493 
2494 &lt;span class=&quot;c1&quot;&gt;# A bit of resizing to not fill the whole spreadsheet with the logo&lt;/span&gt;
2495 &lt;span class=&quot;n&quot;&gt;logo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;150&lt;/span&gt;
2496 &lt;span class=&quot;n&quot;&gt;logo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;150&lt;/span&gt;
2497 
2498 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;A3&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2499 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;hello_world_logo.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2500 &lt;/pre&gt;&lt;/div&gt;
2501 
2502 &lt;p&gt;You have an image on your spreadsheet! Here it is:&lt;/p&gt;
2503 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_20.05.30.2a69f2a77f68.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_20.05.30.2a69f2a77f68.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_20.05.30.2a69f2a77f68.png&amp;amp;w=540&amp;amp;sig=574c2c425c011fa21e790f7cd4a41547f2449b01 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_20.05.30.2a69f2a77f68.png&amp;amp;w=1080&amp;amp;sig=e6b9c78c7daa929ae86f887d560c3f50f0851d5d 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_20.05.30.2a69f2a77f68.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Image&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2504 &lt;p&gt;The image&amp;rsquo;s left top corner is on the cell you chose, in this case, &lt;code&gt;A3&lt;/code&gt;.&lt;/p&gt;
2505 &lt;h3 id=&quot;adding-pretty-charts&quot;&gt;Adding Pretty Charts&lt;/h3&gt;
2506 &lt;p&gt;Another powerful thing you can do with spreadsheets is create an incredible variety of charts. &lt;/p&gt;
2507 &lt;p&gt;Charts are a great way to visualize and understand loads of data quickly. There are a lot of different chart types: bar chart, pie chart, line chart, and so on. &lt;code&gt;openpyxl&lt;/code&gt; has support for a lot of them.&lt;/p&gt;
2508 &lt;p&gt;Here, you&amp;rsquo;ll see only a couple of examples of charts because the theory behind it is the same for every single chart type:&lt;/p&gt;
2509 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
2510 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A few of the chart types that &lt;code&gt;openpyxl&lt;/code&gt; currently doesn&amp;rsquo;t have support for are Funnel, Gantt, Pareto, Treemap, Waterfall, Map, and Sunburst.&lt;/p&gt;
2511 &lt;/div&gt;
2512 &lt;p&gt;For any chart you want to build, you&amp;rsquo;ll need to define the chart type: &lt;code&gt;BarChart&lt;/code&gt;, &lt;code&gt;LineChart&lt;/code&gt;, and so forth, plus the data to be used for the chart, which is called &lt;code&gt;Reference&lt;/code&gt;.&lt;/p&gt;
2513 &lt;p&gt;Before you can build your chart, you need to define what data you want to see represented in it. Sometimes, you can use the dataset as is, but other times you need to massage the data a bit to get additional information.&lt;/p&gt;
2514 &lt;p&gt;Let&amp;rsquo;s start by building a new workbook with some sample data:&lt;/p&gt;
2515 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;
2516 &lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl.chart&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BarChart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reference&lt;/span&gt;
2517 &lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;
2518 &lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2519 &lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2520 &lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;
2521 &lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Let&amp;#39;s create some sample sales data&lt;/span&gt;
2522 &lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
2523 &lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Product&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Online&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Store&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2524 &lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;45&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2525 &lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2526 &lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2527 &lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2528 &lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2529 &lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&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;
2530 &lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&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;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2531 &lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2532 &lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;
2533 &lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
2534 &lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2535 &lt;/pre&gt;&lt;/div&gt;
2536 
2537 &lt;p&gt;Now you&amp;rsquo;re going to start by creating a &lt;strong&gt;bar chart&lt;/strong&gt; that displays the total number of sales per product:&lt;/p&gt;
2538 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;22 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BarChart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2539 &lt;span class=&quot;lineno&quot;&gt;23 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;worksheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2540 &lt;span class=&quot;lineno&quot;&gt;24 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;min_row&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;
2541 &lt;span class=&quot;lineno&quot;&gt;25 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;max_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2542 &lt;span class=&quot;lineno&quot;&gt;26 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;min_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2543 &lt;span class=&quot;lineno&quot;&gt;27 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;max_col&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;
2544 &lt;span class=&quot;lineno&quot;&gt;28 &lt;/span&gt;
2545 &lt;span class=&quot;lineno&quot;&gt;29 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titles_from_data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2546 &lt;span class=&quot;lineno&quot;&gt;30 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_chart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;E2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2547 &lt;span class=&quot;lineno&quot;&gt;31 &lt;/span&gt;
2548 &lt;span class=&quot;lineno&quot;&gt;32 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;chart.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2549 &lt;/pre&gt;&lt;/div&gt;
2550 
2551 &lt;p&gt;There you have it. Below, you can see a very straightforward bar chart  showing the difference between &lt;strong&gt;online&lt;/strong&gt; product sales online and &lt;strong&gt;in-store&lt;/strong&gt; product sales:&lt;/p&gt;
2552 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_20.59.43.7eac35127b97.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_20.59.43.7eac35127b97.png&quot; width=&quot;2160&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_20.59.43.7eac35127b97.png&amp;amp;w=540&amp;amp;sig=bcdfa015a56b903169702ddbeb1ec06c8d67bc87 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_20.59.43.7eac35127b97.png&amp;amp;w=1080&amp;amp;sig=904be9b2a172b3ae7436311c9d05f6a9ad8ae451 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_20.59.43.7eac35127b97.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Bar Chart&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2553 &lt;p&gt;Like with images, the top left corner of the chart is on the cell you added the chart to. In your case, it was on cell &lt;code&gt;E2&lt;/code&gt;.&lt;/p&gt;
2554 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
2555 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Depending on whether you&amp;rsquo;re using Microsoft Excel or an open-source alternative (LibreOffice or OpenOffice), the chart might look slightly different.&lt;/p&gt;
2556 &lt;/div&gt;
2557 &lt;p&gt;Try creating a &lt;strong&gt;line chart&lt;/strong&gt; instead, changing the data a bit:&lt;/p&gt;
2558 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;
2559 &lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;
2560 &lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl.chart&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LineChart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reference&lt;/span&gt;
2561 &lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;
2562 &lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2563 &lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2564 &lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;
2565 &lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Let&amp;#39;s create some sample sales data&lt;/span&gt;
2566 &lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
2567 &lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;January&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;February&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;March&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;April&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2568 &lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;    &lt;span class=&quot;s2&quot;&gt;&amp;quot;May&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;June&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;July&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;August&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;September&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2569 &lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;     &lt;span class=&quot;s2&quot;&gt;&amp;quot;October&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;November&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;December&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2570 &lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2571 &lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2572 &lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2573 &lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2574 &lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;
2575 &lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
2576 &lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2577 &lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;
2578 &lt;span class=&quot;lineno&quot;&gt;21 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2579 &lt;span class=&quot;lineno&quot;&gt;22 &lt;/span&gt;                           &lt;span class=&quot;n&quot;&gt;max_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2580 &lt;span class=&quot;lineno&quot;&gt;23 &lt;/span&gt;                           &lt;span class=&quot;n&quot;&gt;min_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2581 &lt;span class=&quot;lineno&quot;&gt;24 &lt;/span&gt;                           &lt;span class=&quot;n&quot;&gt;max_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
2582 &lt;span class=&quot;lineno&quot;&gt;25 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
2583 &lt;span class=&quot;lineno&quot;&gt;26 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randrange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2584 &lt;/pre&gt;&lt;/div&gt;
2585 
2586 &lt;p&gt;With the above code, you&amp;rsquo;ll be able to generate some random data regarding the sales of 3 different products across a whole year.&lt;/p&gt;
2587 &lt;p&gt;Once that&amp;rsquo;s done, you can very easily create a line chart with the following code:&lt;/p&gt;
2588 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;28 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LineChart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2589 &lt;span class=&quot;lineno&quot;&gt;29 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;worksheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2590 &lt;span class=&quot;lineno&quot;&gt;30 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;min_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2591 &lt;span class=&quot;lineno&quot;&gt;31 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;max_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2592 &lt;span class=&quot;lineno&quot;&gt;32 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;min_col&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;
2593 &lt;span class=&quot;lineno&quot;&gt;33 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;max_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2594 &lt;span class=&quot;lineno&quot;&gt;34 &lt;/span&gt;
2595 &lt;span class=&quot;lineno&quot;&gt;35 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from_rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titles_from_data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2596 &lt;span class=&quot;lineno&quot;&gt;36 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_chart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;C6&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2597 &lt;span class=&quot;lineno&quot;&gt;37 &lt;/span&gt;
2598 &lt;span class=&quot;lineno&quot;&gt;38 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;line_chart.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2599 &lt;/pre&gt;&lt;/div&gt;
2600 
2601 &lt;p&gt;Here&amp;rsquo;s the outcome of the above piece of code:&lt;/p&gt;
2602 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.06.42.e4e52ab1b433.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.06.42.e4e52ab1b433.png&quot; width=&quot;2160&quot; height=&quot;1414&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.06.42.e4e52ab1b433.png&amp;amp;w=540&amp;amp;sig=362319a9716ded57c9567de98c52a4dc805b5346 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.06.42.e4e52ab1b433.png&amp;amp;w=1080&amp;amp;sig=cbd7b37aa77318e4ed8d2401281817fb53a7144b 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_21.06.42.e4e52ab1b433.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Line Chart&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2603 &lt;p&gt;One thing to keep in mind here is the fact that you&amp;rsquo;re using &lt;code&gt;from_rows=True&lt;/code&gt; when adding the data. This argument makes the chart plot row by row instead of column by column.&lt;/p&gt;
2604 &lt;p&gt;In your sample data, you see that each product has a row with 12 values (1 column per month). That&amp;rsquo;s why you use &lt;code&gt;from_rows&lt;/code&gt;. If you don&amp;rsquo;t pass that argument, by default, the chart tries to plot by column, and you&amp;rsquo;ll get a month-by-month comparison of sales.&lt;/p&gt;
2605 &lt;p&gt;Another difference that has to do with the above argument change is the fact that our &lt;code&gt;Reference&lt;/code&gt; now starts from the first column, &lt;code&gt;min_col=1&lt;/code&gt;, instead of the second one. This change is needed because the chart now expects the first column to have the titles.&lt;/p&gt;
2606 &lt;p&gt;There are a couple of other things you can also change regarding the style of the chart. For example, you can add specific categories to the chart:&lt;/p&gt;
2607 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cats&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;worksheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2608                  &lt;span class=&quot;n&quot;&gt;min_row&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;
2609                  &lt;span class=&quot;n&quot;&gt;max_row&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;
2610                  &lt;span class=&quot;n&quot;&gt;min_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2611                  &lt;span class=&quot;n&quot;&gt;max_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2612 &lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_categories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2613 &lt;/pre&gt;&lt;/div&gt;
2614 
2615 &lt;p&gt;Add this piece of code before saving the workbook, and you should see the month names appearing instead of numbers:&lt;/p&gt;
2616 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.08.05.8867e2cced85.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.08.05.8867e2cced85.png&quot; width=&quot;2160&quot; height=&quot;1414&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.08.05.8867e2cced85.png&amp;amp;w=540&amp;amp;sig=6e48719b75e585dcb58fec3768def0630bb367ff 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.08.05.8867e2cced85.png&amp;amp;w=1080&amp;amp;sig=9fed1350289fe067d8f50c07516bfcc460f4a720 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_21.08.05.8867e2cced85.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Line Chart and Categories&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2617 &lt;p&gt;Code-wise, this is a minimal change. But in terms of the readability of the spreadsheet, this makes it much easier for someone to open the spreadsheet and understand the chart straight away.&lt;/p&gt;
2618 &lt;p&gt;Another thing you can do to improve the chart readability is to add an axis. You can do it using the attributes &lt;code&gt;x_axis&lt;/code&gt; and &lt;code&gt;y_axis&lt;/code&gt;:&lt;/p&gt;
2619 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x_axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Months&amp;quot;&lt;/span&gt;
2620 &lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Sales (per unit)&amp;quot;&lt;/span&gt;
2621 &lt;/pre&gt;&lt;/div&gt;
2622 
2623 &lt;p&gt;This will generate a spreadsheet like the below one:&lt;/p&gt;
2624 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.09.46.ce55f629b073.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.09.46.ce55f629b073.png&quot; width=&quot;2160&quot; height=&quot;1414&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.09.46.ce55f629b073.png&amp;amp;w=540&amp;amp;sig=ac73f73702b55a957c77d6da224cde46c2c9a802 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.09.46.ce55f629b073.png&amp;amp;w=1080&amp;amp;sig=408f6929a900e4a5ccb5cb1cca8647cf64d0d069 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_21.09.46.ce55f629b073.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Line Chart, Categories and Axis Titles&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2625 &lt;p&gt;As you can see, small changes like the above make reading your chart a much easier and quicker task.&lt;/p&gt;
2626 &lt;p&gt;There is also a way to style your chart by using Excel&amp;rsquo;s default &lt;code&gt;ChartStyle&lt;/code&gt; property. In this case, you have to choose a number between 1 and 48. Depending on your choice, the colors of your chart change as well:&lt;/p&gt;
2627 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# You can play with this by choosing any number between 1 and 48&lt;/span&gt;
2628 &lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;style&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;
2629 &lt;/pre&gt;&lt;/div&gt;
2630 
2631 &lt;p&gt;With the style selected above, all lines have some shade of orange:&lt;/p&gt;
2632 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.16.31.7df18bbe94cb.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.16.31.7df18bbe94cb.png&quot; width=&quot;2160&quot; height=&quot;1414&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.16.31.7df18bbe94cb.png&amp;amp;w=540&amp;amp;sig=4b0439c6c48d0b3f96f411e6198f6fd49d5c7026 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.16.31.7df18bbe94cb.png&amp;amp;w=1080&amp;amp;sig=4d0aad0a27321bb321dc9c88158f357155968121 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_21.16.31.7df18bbe94cb.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Line Chart, Categories, Axis Titles and Style&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2633 &lt;p&gt;There is no clear documentation on what each style number looks like, but &lt;a href=&quot;https://1drv.ms/x/s!Asf0Y5Y4GI3Mg6kZNRd1IA09NLWv9A&quot;&gt;this spreadsheet&lt;/a&gt; has a few examples of the styles available.&lt;/p&gt;
2634 &lt;div class=&quot;card mb-3&quot; id=&quot;collapse_card0fb191&quot;&gt;
2635 &lt;div class=&quot;card-header border-0&quot;&gt;&lt;p class=&quot;m-0&quot;&gt;&lt;button class=&quot;btn&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapse0fb191&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapse0fb191&quot;&gt;Complete Code Example&lt;/button&gt; &lt;button class=&quot;btn btn-link float-right&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapse0fb191&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapse0fb191&quot;&gt;Show/Hide&lt;/button&gt;&lt;/p&gt;&lt;/div&gt;
2636 &lt;div id=&quot;collapse0fb191&quot; class=&quot;collapse&quot; data-parent=&quot;#collapse_card0fb191&quot;&gt;&lt;div class=&quot;card-body&quot; markdown=&quot;1&quot;&gt;
2637 
2638 &lt;p&gt;Here&amp;rsquo;s the full code used to generate the line chart with categories, axis titles, and style:&lt;/p&gt;
2639 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;
2640 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;
2641 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl.chart&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LineChart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reference&lt;/span&gt;
2642 
2643 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2644 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2645 
2646 &lt;span class=&quot;c1&quot;&gt;# Let&amp;#39;s create some sample sales data&lt;/span&gt;
2647 &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
2648     &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;January&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;February&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;March&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;April&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2649     &lt;span class=&quot;s2&quot;&gt;&amp;quot;May&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;June&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;July&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;August&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;September&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2650      &lt;span class=&quot;s2&quot;&gt;&amp;quot;October&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;November&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;December&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2651     &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2652     &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2653     &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2654 &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2655 
2656 &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
2657     &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2658 
2659 &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2660                            &lt;span class=&quot;n&quot;&gt;max_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2661                            &lt;span class=&quot;n&quot;&gt;min_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2662                            &lt;span class=&quot;n&quot;&gt;max_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
2663     &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
2664         &lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randrange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2665 
2666 &lt;span class=&quot;c1&quot;&gt;# Create a LineChart and add the main data&lt;/span&gt;
2667 &lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LineChart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2668 &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;worksheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2669                            &lt;span class=&quot;n&quot;&gt;min_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2670                            &lt;span class=&quot;n&quot;&gt;max_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2671                            &lt;span class=&quot;n&quot;&gt;min_col&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;
2672                            &lt;span class=&quot;n&quot;&gt;max_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2673 &lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titles_from_data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from_rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2674 
2675 &lt;span class=&quot;c1&quot;&gt;# Add categories to the chart&lt;/span&gt;
2676 &lt;span class=&quot;n&quot;&gt;cats&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;worksheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2677                  &lt;span class=&quot;n&quot;&gt;min_row&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;
2678                  &lt;span class=&quot;n&quot;&gt;max_row&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;
2679                  &lt;span class=&quot;n&quot;&gt;min_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2680                  &lt;span class=&quot;n&quot;&gt;max_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2681 &lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_categories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2682 
2683 &lt;span class=&quot;c1&quot;&gt;# Rename the X and Y Axis&lt;/span&gt;
2684 &lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x_axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Months&amp;quot;&lt;/span&gt;
2685 &lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Sales (per unit)&amp;quot;&lt;/span&gt;
2686 
2687 &lt;span class=&quot;c1&quot;&gt;# Apply a specific Style&lt;/span&gt;
2688 &lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;style&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;
2689 
2690 &lt;span class=&quot;c1&quot;&gt;# Save!&lt;/span&gt;
2691 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_chart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;C6&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2692 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;line_chart.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2693 &lt;/pre&gt;&lt;/div&gt;
2694 
2695 &lt;/div&gt;&lt;/div&gt;
2696 
2697 &lt;/div&gt;
2698 &lt;p&gt;There are a lot more chart types and customization you can apply, so be sure to check out the &lt;a href=&quot;https://openpyxl.readthedocs.io/en/stable/charts/introduction.html&quot;&gt;package documentation&lt;/a&gt; on this if you need some specific formatting.&lt;/p&gt;
2699 &lt;h3 id=&quot;convert-python-classes-to-excel-spreadsheet&quot;&gt;Convert Python Classes to Excel Spreadsheet&lt;/h3&gt;
2700 &lt;p&gt;You already saw how to convert an Excel spreadsheet&amp;rsquo;s data into Python classes, but now let&amp;rsquo;s do the opposite.&lt;/p&gt;
2701 &lt;p&gt;Let&amp;rsquo;s imagine you have a database and are using some Object-Relational Mapping (ORM) to map DB objects into Python classes. Now, you want to export those same objects into a spreadsheet.&lt;/p&gt;
2702 &lt;p&gt;Let&amp;rsquo;s assume the following &lt;a href=&quot;https://realpython.com/python-data-classes/&quot;&gt;data classes&lt;/a&gt; to represent the data coming from your database regarding product sales:&lt;/p&gt;
2703 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;dataclasses&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataclass&lt;/span&gt;
2704 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;
2705 
2706 &lt;span class=&quot;nd&quot;&gt;@dataclass&lt;/span&gt;
2707 &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Sale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
2708     &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
2709     &lt;span class=&quot;n&quot;&gt;quantity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;
2710 
2711 &lt;span class=&quot;nd&quot;&gt;@dataclass&lt;/span&gt;
2712 &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
2713     &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
2714     &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
2715     &lt;span class=&quot;n&quot;&gt;sales&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2716 &lt;/pre&gt;&lt;/div&gt;
2717 
2718 &lt;p&gt;Now, let&amp;rsquo;s generate some random data, assuming the above classes are stored in a &lt;code&gt;db_classes.py&lt;/code&gt; file:&lt;/p&gt;
2719 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;
2720 &lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
2721 &lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Ignore these for now. You&amp;#39;ll use them in a sec ;)&lt;/span&gt;
2722 &lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;
2723 &lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl.chart&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LineChart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reference&lt;/span&gt;
2724 &lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;
2725 &lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;db_classes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Sale&lt;/span&gt;
2726 &lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;
2727 &lt;span class=&quot;lineno&quot;&gt; 9 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
2728 &lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;
2729 &lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Let&amp;#39;s create 5 products&lt;/span&gt;
2730 &lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
2731 &lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;sales&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
2732 &lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;
2733 &lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# Create 5 months of sales&lt;/span&gt;
2734 &lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
2735 &lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;sale&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Sale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quantity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randrange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
2736 &lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;sales&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2737 &lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;
2738 &lt;span class=&quot;lineno&quot;&gt;20 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
2739 &lt;span class=&quot;lineno&quot;&gt;21 &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;s2&quot;&gt;&amp;quot;Product &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2740 &lt;span class=&quot;lineno&quot;&gt;22 &lt;/span&gt;                      &lt;span class=&quot;n&quot;&gt;sales&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sales&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2741 &lt;span class=&quot;lineno&quot;&gt;23 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2742 &lt;/pre&gt;&lt;/div&gt;
2743 
2744 &lt;p&gt;By running this piece of code, you should get 5 products with 5 months of sales with a random quantity of sales for each month.&lt;/p&gt;
2745 &lt;p&gt;Now, to convert this into a spreadsheet, you need to iterate over the data and append it to the spreadsheet:&lt;/p&gt;
2746 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;25 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2747 &lt;span class=&quot;lineno&quot;&gt;26 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2748 &lt;span class=&quot;lineno&quot;&gt;27 &lt;/span&gt;
2749 &lt;span class=&quot;lineno&quot;&gt;28 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Append column names first&lt;/span&gt;
2750 &lt;span class=&quot;lineno&quot;&gt;29 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Product ID&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Product Name&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Month 1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2751 &lt;span class=&quot;lineno&quot;&gt;30 &lt;/span&gt;              &lt;span class=&quot;s2&quot;&gt;&amp;quot;Month 2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Month 3&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Month 4&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Month 5&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
2752 &lt;span class=&quot;lineno&quot;&gt;31 &lt;/span&gt;
2753 &lt;span class=&quot;lineno&quot;&gt;32 &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Append the data&lt;/span&gt;
2754 &lt;span class=&quot;lineno&quot;&gt;33 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
2755 &lt;span class=&quot;lineno&quot;&gt;34 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2756 &lt;span class=&quot;lineno&quot;&gt;35 &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sale&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sales&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
2757 &lt;span class=&quot;lineno&quot;&gt;36 &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sale&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quantity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2758 &lt;span class=&quot;lineno&quot;&gt;37 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2759 &lt;/pre&gt;&lt;/div&gt;
2760 
2761 &lt;p&gt;That&amp;rsquo;s it. That should allow you to create a spreadsheet with some data coming from your database.&lt;/p&gt;
2762 &lt;p&gt;However, why not use some of that cool knowledge you gained recently to add a chart as well to display that data more visually?&lt;/p&gt;
2763 &lt;p&gt;All right, then you could probably do something like this:&lt;/p&gt;
2764 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;38 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LineChart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2765 &lt;span class=&quot;lineno&quot;&gt;39 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;worksheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2766 &lt;span class=&quot;lineno&quot;&gt;40 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;min_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2767 &lt;span class=&quot;lineno&quot;&gt;41 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;max_row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2768 &lt;span class=&quot;lineno&quot;&gt;42 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;min_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2769 &lt;span class=&quot;lineno&quot;&gt;43 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;max_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2770 &lt;span class=&quot;lineno&quot;&gt;44 &lt;/span&gt;
2771 &lt;span class=&quot;lineno&quot;&gt;45 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titles_from_data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from_rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2772 &lt;span class=&quot;lineno&quot;&gt;46 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_chart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;B8&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2773 &lt;span class=&quot;lineno&quot;&gt;47 &lt;/span&gt;
2774 &lt;span class=&quot;lineno&quot;&gt;48 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cats&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;worksheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
2775 &lt;span class=&quot;lineno&quot;&gt;49 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;min_row&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;
2776 &lt;span class=&quot;lineno&quot;&gt;50 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;max_row&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;
2777 &lt;span class=&quot;lineno&quot;&gt;51 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;min_col&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;
2778 &lt;span class=&quot;lineno&quot;&gt;52 &lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;max_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2779 &lt;span class=&quot;lineno&quot;&gt;53 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_categories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2780 &lt;span class=&quot;lineno&quot;&gt;54 &lt;/span&gt;
2781 &lt;span class=&quot;lineno&quot;&gt;55 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x_axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Months&amp;quot;&lt;/span&gt;
2782 &lt;span class=&quot;lineno&quot;&gt;56 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Sales (per unit)&amp;quot;&lt;/span&gt;
2783 &lt;span class=&quot;lineno&quot;&gt;57 &lt;/span&gt;
2784 &lt;span class=&quot;lineno&quot;&gt;58 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;oop_sample.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2785 &lt;/pre&gt;&lt;/div&gt;
2786 
2787 &lt;p&gt;Now we&amp;rsquo;re talking! Here&amp;rsquo;s a spreadsheet generated from database objects and with a chart and everything:&lt;/p&gt;
2788 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.26.23.1f355e76586d.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.26.23.1f355e76586d.png&quot; width=&quot;2160&quot; height=&quot;1414&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.26.23.1f355e76586d.png&amp;amp;w=540&amp;amp;sig=135f4ee5413467c91f65bbb6e914724cdf1fd413 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.26.23.1f355e76586d.png&amp;amp;w=1080&amp;amp;sig=5b7dd165f92c237ddd049350ca6fc6a165e10512 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_21.26.23.1f355e76586d.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Conversion from Python Data Classes&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2789 &lt;p&gt;That&amp;rsquo;s a great way for you to wrap up your new knowledge of charts!&lt;/p&gt;
2790 &lt;h3 id=&quot;bonus-working-with-pandas&quot;&gt;Bonus: Working With Pandas&lt;/h3&gt;
2791 &lt;p&gt;Even though you can use &lt;a href=&quot;https://realpython.com/working-with-large-excel-files-in-pandas/&quot;&gt;Pandas to handle Excel files&lt;/a&gt;, there are few things that you either can&amp;rsquo;t accomplish with Pandas or that you&amp;rsquo;d be better off just using &lt;code&gt;openpyxl&lt;/code&gt; directly.&lt;/p&gt;
2792 &lt;p&gt;For example, some of the advantages of using &lt;code&gt;openpyxl&lt;/code&gt; are the ability to easily customize your spreadsheet with styles, conditional formatting, and such.&lt;/p&gt;
2793 &lt;p&gt;But guess what, you don&amp;rsquo;t have to worry about picking. In fact, &lt;code&gt;openpyxl&lt;/code&gt; has support for both converting data from a Pandas DataFrame into a workbook or the opposite, converting an &lt;code&gt;openpyxl&lt;/code&gt; workbook into a Pandas DataFrame.&lt;/p&gt;
2794 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
2795 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you&amp;rsquo;re new to Pandas, check our &lt;a href=&quot;https://realpython.com/courses/pandas-dataframes-101/&quot;&gt;course on Pandas DataFrames&lt;/a&gt; beforehand.&lt;/p&gt;
2796 &lt;/div&gt;
2797 &lt;p&gt;First things first, remember to install the &lt;code&gt;pandas&lt;/code&gt; package:&lt;/p&gt;
2798 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; pip install pandas
2799 &lt;/pre&gt;&lt;/div&gt;
2800 
2801 &lt;p&gt;Then, let&amp;rsquo;s create a sample DataFrame:&lt;/p&gt;
2802 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt; 1 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pd&lt;/span&gt;
2803 &lt;span class=&quot;lineno&quot;&gt; 2 &lt;/span&gt;
2804 &lt;span class=&quot;lineno&quot;&gt; 3 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
2805 &lt;span class=&quot;lineno&quot;&gt; 4 &lt;/span&gt;    &lt;span class=&quot;s2&quot;&gt;&amp;quot;Product Name&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Product 1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Product 2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
2806 &lt;span class=&quot;lineno&quot;&gt; 5 &lt;/span&gt;    &lt;span class=&quot;s2&quot;&gt;&amp;quot;Sales Month 1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&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;
2807 &lt;span class=&quot;lineno&quot;&gt; 6 &lt;/span&gt;    &lt;span class=&quot;s2&quot;&gt;&amp;quot;Sales Month 2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&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;
2808 &lt;span class=&quot;lineno&quot;&gt; 7 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
2809 &lt;span class=&quot;lineno&quot;&gt; 8 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2810 &lt;/pre&gt;&lt;/div&gt;
2811 
2812 &lt;p&gt;Now that you have some data, you can use &lt;code&gt;.dataframe_to_rows()&lt;/code&gt; to convert it from a DataFrame into a worksheet:&lt;/p&gt;
2813 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;lineno&quot;&gt;10 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;
2814 &lt;span class=&quot;lineno&quot;&gt;11 &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl.utils.dataframe&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataframe_to_rows&lt;/span&gt;
2815 &lt;span class=&quot;lineno&quot;&gt;12 &lt;/span&gt;
2816 &lt;span class=&quot;lineno&quot;&gt;13 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
2817 &lt;span class=&quot;lineno&quot;&gt;14 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2818 &lt;span class=&quot;lineno&quot;&gt;15 &lt;/span&gt;
2819 &lt;span class=&quot;lineno&quot;&gt;16 &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataframe_to_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
2820 &lt;span class=&quot;lineno&quot;&gt;17 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2821 &lt;span class=&quot;lineno&quot;&gt;18 &lt;/span&gt;
2822 &lt;span class=&quot;lineno&quot;&gt;19 &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;pandas.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2823 &lt;/pre&gt;&lt;/div&gt;
2824 
2825 &lt;p&gt;You should see a spreadsheet that looks like this:&lt;/p&gt;
2826 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.42.15.0a4208db25f0.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Screenshot_2019-06-24_21.42.15.0a4208db25f0.png&quot; width=&quot;2160&quot; height=&quot;1414&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.42.15.0a4208db25f0.png&amp;amp;w=540&amp;amp;sig=636303dd8f99512651c5868f4ef572b2afa75d3c 540w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screenshot_2019-06-24_21.42.15.0a4208db25f0.png&amp;amp;w=1080&amp;amp;sig=c2ddf015c46566fc545ad03187cc5780a61938f9 1080w, https://files.realpython.com/media/Screenshot_2019-06-24_21.42.15.0a4208db25f0.png 2160w&quot; sizes=&quot;75vw&quot; alt=&quot;Example Spreadsheet With Data from Pandas Data Frame&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
2827 &lt;p&gt;If you want to add the &lt;a href=&quot;https://realpython.com/python-data-cleaning-numpy-pandas/#changing-the-index-of-a-dataframe&quot;&gt;DataFrame&amp;rsquo;s index&lt;/a&gt;, you can change &lt;code&gt;index=True&lt;/code&gt;, and it adds each row&amp;rsquo;s index into your spreadsheet.&lt;/p&gt;
2828 &lt;p&gt;On the other hand, if you want to convert a spreadsheet into a DataFrame, you can also do it in a very straightforward way like so:&lt;/p&gt;
2829 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pd&lt;/span&gt;
2830 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;
2831 
2832 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2833 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2834 
2835 &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;
2836 &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2837 &lt;/pre&gt;&lt;/div&gt;
2838 
2839 &lt;p&gt;Alternatively, if you want to add the correct headers and use the review ID as the index, for example, then you can also do it like this instead:&lt;/p&gt;
2840 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pd&lt;/span&gt;
2841 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;openpyxl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;
2842 &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mapping&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;REVIEW_ID&lt;/span&gt;
2843 
2844 &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_workbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sample.xlsx&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2845 &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workbook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;
2846 
2847 &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sheet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;
2848 
2849 &lt;span class=&quot;c1&quot;&gt;# Set the first row as the columns for the DataFrame&lt;/span&gt;
2850 &lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2851 &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2852 
2853 &lt;span class=&quot;c1&quot;&gt;# Set the field &amp;quot;review_id&amp;quot; as the indexes for each row&lt;/span&gt;
2854 &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;REVIEW_ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2855 
2856 &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
2857 &lt;/pre&gt;&lt;/div&gt;
2858 
2859 &lt;p&gt;Using indexes and columns allows you to access data from your DataFrame easily:&lt;/p&gt;
2860 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;
2861 &lt;span class=&quot;go&quot;&gt;Index([&amp;#39;marketplace&amp;#39;, &amp;#39;customer_id&amp;#39;, &amp;#39;review_id&amp;#39;, &amp;#39;product_id&amp;#39;,&lt;/span&gt;
2862 &lt;span class=&quot;go&quot;&gt;       &amp;#39;product_parent&amp;#39;, &amp;#39;product_title&amp;#39;, &amp;#39;product_category&amp;#39;, &amp;#39;star_rating&amp;#39;,&lt;/span&gt;
2863 &lt;span class=&quot;go&quot;&gt;       &amp;#39;helpful_votes&amp;#39;, &amp;#39;total_votes&amp;#39;, &amp;#39;vine&amp;#39;, &amp;#39;verified_purchase&amp;#39;,&lt;/span&gt;
2864 &lt;span class=&quot;go&quot;&gt;       &amp;#39;review_headline&amp;#39;, &amp;#39;review_body&amp;#39;, &amp;#39;review_date&amp;#39;],&lt;/span&gt;
2865 &lt;span class=&quot;go&quot;&gt;      dtype=&amp;#39;object&amp;#39;)&lt;/span&gt;
2866 
2867 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Get first 10 reviews&amp;#39; star rating&lt;/span&gt;
2868 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;star_rating&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2869 &lt;span class=&quot;go&quot;&gt;R3O9SGZBVQBV76    5&lt;/span&gt;
2870 &lt;span class=&quot;go&quot;&gt;RKH8BNC3L5DLF     5&lt;/span&gt;
2871 &lt;span class=&quot;go&quot;&gt;R2HLE8WKZSU3NL    2&lt;/span&gt;
2872 &lt;span class=&quot;go&quot;&gt;R31U3UH5AZ42LL    5&lt;/span&gt;
2873 &lt;span class=&quot;go&quot;&gt;R2SV659OUJ945Y    4&lt;/span&gt;
2874 &lt;span class=&quot;go&quot;&gt;RA51CP8TR5A2L     5&lt;/span&gt;
2875 &lt;span class=&quot;go&quot;&gt;RB2Q7DLDN6TH6     5&lt;/span&gt;
2876 &lt;span class=&quot;go&quot;&gt;R2RHFJV0UYBK3Y    1&lt;/span&gt;
2877 &lt;span class=&quot;go&quot;&gt;R2Z6JOQ94LFHEP    5&lt;/span&gt;
2878 &lt;span class=&quot;go&quot;&gt;RX27XIIWY5JPB     4&lt;/span&gt;
2879 &lt;span class=&quot;go&quot;&gt;Name: star_rating, dtype: int64&lt;/span&gt;
2880 
2881 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Grab review with id &amp;quot;R2EQL1V1L6E0C9&amp;quot;, using the index&lt;/span&gt;
2882 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;R2EQL1V1L6E0C9&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
2883 &lt;span class=&quot;go&quot;&gt;marketplace               US&lt;/span&gt;
2884 &lt;span class=&quot;go&quot;&gt;customer_id         15305006&lt;/span&gt;
2885 &lt;span class=&quot;go&quot;&gt;review_id     R2EQL1V1L6E0C9&lt;/span&gt;
2886 &lt;span class=&quot;go&quot;&gt;product_id        B004LURNO6&lt;/span&gt;
2887 &lt;span class=&quot;go&quot;&gt;product_parent     892860326&lt;/span&gt;
2888 &lt;span class=&quot;go&quot;&gt;review_headline   Five Stars&lt;/span&gt;
2889 &lt;span class=&quot;go&quot;&gt;review_body          Love it&lt;/span&gt;
2890 &lt;span class=&quot;go&quot;&gt;review_date       2015-08-31&lt;/span&gt;
2891 &lt;span class=&quot;go&quot;&gt;Name: R2EQL1V1L6E0C9, dtype: object&lt;/span&gt;
2892 &lt;/pre&gt;&lt;/div&gt;
2893 
2894 &lt;p&gt;There you go, whether you want to use &lt;code&gt;openpyxl&lt;/code&gt; to prettify your Pandas dataset or use Pandas to do some hardcore algebra, you now know how to switch between both packages.&lt;/p&gt;
2895 &lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
2896 &lt;p&gt;&lt;em&gt;Phew&lt;/em&gt;, after that long read, you now know how to work with spreadsheets in Python! You can rely on &lt;code&gt;openpyxl&lt;/code&gt;, your trustworthy companion, to:&lt;/p&gt;
2897 &lt;ul&gt;
2898 &lt;li&gt;Extract valuable information from spreadsheets in a Pythonic manner&lt;/li&gt;
2899 &lt;li&gt;Create your own spreadsheets, no matter the complexity level&lt;/li&gt;
2900 &lt;li&gt;Add cool features such as conditional formatting or charts to your spreadsheets&lt;/li&gt;
2901 &lt;/ul&gt;
2902 &lt;p&gt;There are a few other things you can do with &lt;code&gt;openpyxl&lt;/code&gt; that might not have been covered in this tutorial, but you can always check the package&amp;rsquo;s official &lt;a href=&quot;https://openpyxl.readthedocs.io/en/stable/index.html&quot;&gt;documentation website&lt;/a&gt; to learn more about it. You can even venture into checking its &lt;a href=&quot;https://bitbucket.org/openpyxl/openpyxl/src/default/&quot;&gt;source code&lt;/a&gt; and improving the package further.&lt;/p&gt;
2903 &lt;p&gt;Feel free to leave any comments below if you have any questions, or if there&amp;rsquo;s any section you&amp;rsquo;d love to hear more about.&lt;/p&gt;
2904 &lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Download Dataset:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/openpyxl-sample-dataset/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-openpyxl-sample-dataset&quot; data-focus=&quot;false&quot;&gt;Click here to download the dataset for the openpyxl exercise you&#39;ll be following in this tutorial.&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
2905         &lt;hr /&gt;
2906         &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;
2907       </content>
2908     </entry>
2909   
2910     <entry>
2911       <title>Your Guide to the CPython Source Code</title>
2912       <id>https://realpython.com/cpython-source-code-guide/</id>
2913       <link href="https://realpython.com/cpython-source-code-guide/"/>
2914       <updated>2019-08-21T16:10:00+00:00</updated>
2915       <summary>In this detailed Python tutorial, you&#39;ll explore the CPython source code. By following this step-by-step walkthrough, you&#39;ll take a deep dive into how the CPython compiler works and how your Python code gets executed.</summary>
2916       <content type="html">
2917         &lt;p&gt;Are there certain parts of Python that just seem magic? Like how are dictionaries so much faster than looping over a list to find an item. How does a generator remember the state of the variables each time it yields a value and why do you never have to allocate memory like other languages? It turns out, CPython, the most popular Python runtime is written in human-readable C and Python code. This tutorial will walk you through the CPython source code. &lt;/p&gt;
2918 &lt;p&gt;You&amp;rsquo;ll cover all the concepts behind the internals of CPython, how they work and visual explanations as you go.&lt;/p&gt;
2919 &lt;p&gt;&lt;strong&gt;You&amp;rsquo;ll learn how to:&lt;/strong&gt;&lt;/p&gt;
2920 &lt;ul&gt;
2921 &lt;li&gt;Read and navigate the source code&lt;/li&gt;
2922 &lt;li&gt;Compile CPython from source code&lt;/li&gt;
2923 &lt;li&gt;Navigate and comprehend the inner workings of concepts like lists, dictionaries, and generators&lt;/li&gt;
2924 &lt;li&gt;Run the test suite&lt;/li&gt;
2925 &lt;li&gt;Modify or upgrade components of the CPython library to contribute them to future versions&lt;/li&gt;
2926 &lt;/ul&gt;
2927 &lt;p&gt;Yes, this is a very long article. If you just made yourself a fresh cup of tea, coffee or your favorite beverage, it&amp;rsquo;s going to be cold by the end of Part 1. &lt;/p&gt;
2928 &lt;p&gt;This tutorial is split into five parts. Take your time for each part and make sure you try out the demos and the interactive components. You can feel a sense of achievement that you grasp the core concepts of Python that can make you a better Python programmer.&lt;/p&gt;
2929 &lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-mastery-course&quot; data-focus=&quot;false&quot;&gt;5 Thoughts On Python Mastery&lt;/a&gt;, a free course for Python developers that shows you the roadmap and the mindset you&#39;ll need to take your Python skills to the next level.&lt;/p&gt;&lt;/div&gt;
2930 
2931 &lt;h2 h1=&quot;h1&quot; id=&quot;part-1-introduction-to-cpython&quot;&gt;Part 1: Introduction to CPython&lt;/h2&gt;
2932 &lt;p&gt;When you type &lt;code&gt;python&lt;/code&gt; at the console or install a Python distribution from &lt;a href=&quot;https://www.python.org&quot;&gt;python.org&lt;/a&gt;, you are running &lt;strong&gt;CPython&lt;/strong&gt;. CPython is one of the many Python runtimes, maintained and written by different teams of developers. Some other runtimes you may have heard are &lt;a href=&quot;https://pypy.org/&quot;&gt;PyPy&lt;/a&gt;, &lt;a href=&quot;https://cython.org/&quot;&gt;Cython&lt;/a&gt;, and &lt;a href=&quot;https://www.jython.org/&quot;&gt;Jython&lt;/a&gt;.&lt;/p&gt;
2933 &lt;p&gt;The unique thing about CPython is that it contains both a runtime and the shared language specification that all Python runtimes use. CPython is the &amp;ldquo;official,&amp;rdquo; or reference implementation of Python.&lt;/p&gt;
2934 &lt;p&gt;The Python language specification is the document that the description of the Python language. For example, it says that &lt;code&gt;assert&lt;/code&gt; is a reserved keyword, and that &lt;code&gt;[]&lt;/code&gt; is used for indexing, slicing, and creating empty lists.&lt;/p&gt;
2935 &lt;p&gt;Think about what you expect to be inside the Python distribution on your computer:&lt;/p&gt;
2936 &lt;ul&gt;
2937 &lt;li&gt;When you type &lt;code&gt;python&lt;/code&gt; without a file or module, it gives an interactive prompt.&lt;/li&gt;
2938 &lt;li&gt;You can import built-in modules from the standard library like &lt;code&gt;json&lt;/code&gt;.&lt;/li&gt;
2939 &lt;li&gt;You can install packages from the internet using &lt;code&gt;pip&lt;/code&gt;.&lt;/li&gt;
2940 &lt;li&gt;You can test your applications using the built-in &lt;code&gt;unittest&lt;/code&gt; library.&lt;/li&gt;
2941 &lt;/ul&gt;
2942 &lt;p&gt;These are all part of the CPython distribution. There&amp;rsquo;s a lot more than just a compiler.&lt;/p&gt;
2943 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
2944 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This article is written against version &lt;a href=&quot;https://github.com/python/cpython/tree/v3.8.0b4&quot;&gt;3.8.0b4&lt;/a&gt; of the CPython source code.&lt;/p&gt;
2945 &lt;/div&gt;
2946 &lt;h3 id=&quot;whats-in-the-source-code&quot;&gt;What&amp;rsquo;s in the Source Code?&lt;/h3&gt;
2947 &lt;p&gt;The CPython source distribution comes with a whole range of tools, libraries, and components. We&amp;rsquo;ll explore those in this article. First we are going to focus on the compiler.&lt;/p&gt;
2948 &lt;p&gt;To download a copy of the CPython source code, you can use &lt;code&gt;git&lt;/code&gt; to pull the latest version to a working copy locally:&lt;/p&gt;
2949 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;git clone https://github.com/python/cpython&lt;/span&gt;
2950 &lt;span class=&quot;go&quot;&gt;cd cpython&lt;/span&gt;
2951 &lt;span class=&quot;go&quot;&gt;git checkout v3.8.0b4&lt;/span&gt;
2952 &lt;/pre&gt;&lt;/div&gt;
2953 
2954 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
2955 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you don&amp;rsquo;t have Git available, you can download the source in a &lt;a href=&quot;https://github.com/python/cpython/archive/v3.8.0b4.zip&quot;&gt;ZIP&lt;/a&gt; file directly from the GitHub website.&lt;/p&gt;
2956 &lt;/div&gt;
2957 &lt;p&gt;Inside of the newly downloaded &lt;code&gt;cpython&lt;/code&gt; directory, you will find the following subdirectories:&lt;/p&gt;
2958 &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;cpython/
29592960 ├── Doc      ← Source for the documentation
2961 ├── Grammar  ← The computer-readable language definition
2962 ├── Include  ← The C header files
2963 ├── Lib      ← Standard library modules written in Python
2964 ├── Mac      ← macOS support files
2965 ├── Misc     ← Miscellaneous files
2966 ├── Modules  ← Standard Library Modules written in C
2967 ├── Objects  ← Core types and the object model
2968 ├── Parser   ← The Python parser source code
2969 ├── PC       ← Windows build support files
2970 ├── PCbuild  ← Windows build support files for older Windows versions
2971 ├── Programs ← Source code for the python executable and other binaries
2972 ├── Python   ← The CPython interpreter source code
2973 └── Tools    ← Standalone tools useful for building or extending Python
2974 &lt;/pre&gt;&lt;/div&gt;
2975 
2976 &lt;p&gt;Next, we&amp;rsquo;ll compile CPython from the source code. This step requires a C compiler, and some build tools, which depend on the operating system you&amp;rsquo;re using.&lt;/p&gt;
2977 &lt;h3 id=&quot;compiling-cpython-macos&quot;&gt;Compiling CPython (macOS)&lt;/h3&gt;
2978 &lt;p&gt;Compiling CPython on macOS is straightforward. You will first need the essential C compiler toolkit. The Command Line Development Tools is an app that you can update in macOS through the App Store. You need to perform the initial installation on the terminal.&lt;/p&gt;
2979 &lt;p&gt;To open up a terminal in macOS, go to the Launchpad, then &lt;em&gt;Other&lt;/em&gt; then choose the &lt;em&gt;Terminal&lt;/em&gt; app. You will want to save this app to your Dock, so right-click the Icon and select &lt;em&gt;Keep in Dock&lt;/em&gt;.&lt;/p&gt;
2980 &lt;p&gt;Now, within the terminal, install the C compiler and toolkit by running the following:&lt;/p&gt;
2981 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; xcode-select --install
2982 &lt;/pre&gt;&lt;/div&gt;
2983 
2984 &lt;p&gt;This command will pop up with a prompt to download and install a set of tools, including Git, Make, and the GNU C compiler.&lt;/p&gt;
2985 &lt;p&gt;You will also need a working copy of &lt;a href=&quot;https://www.openssl.org/&quot;&gt;OpenSSL&lt;/a&gt; to use for fetching packages from the PyPi.org website. If you later plan on using this build to install additional packages, SSL validation is required.&lt;/p&gt;
2986 &lt;p&gt;The simplest way to install OpenSSL on macOS is by using &lt;a href=&quot;https://brew.sh&quot;&gt;HomeBrew&lt;/a&gt;. If you already have HomeBrew installed, you can install the dependencies for CPython with the &lt;code&gt;brew install&lt;/code&gt; command:&lt;/p&gt;
2987 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; brew install openssl xz zlib
2988 &lt;/pre&gt;&lt;/div&gt;
2989 
2990 &lt;p&gt;Now that you have the dependencies, you can run the &lt;code&gt;configure&lt;/code&gt; script, enabling SSL support by discovering the location that HomeBrew installed to and enabling the debug hooks &lt;code&gt;--with-pydebug&lt;/code&gt;:&lt;/p&gt;
2991 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;CPPFLAGS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-I&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;brew --prefix zlib&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/include&amp;quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
2992  &lt;span class=&quot;nv&quot;&gt;LDFLAGS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-L&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;brew --prefix zlib&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/lib&amp;quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
2993  ./configure --with-openssl&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;brew --prefix openssl&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt; --with-pydebug
2994 &lt;/pre&gt;&lt;/div&gt;
2995 
2996 &lt;p&gt;This will generate a &lt;code&gt;Makefile&lt;/code&gt; in the root of the repository that you can use to automate the build process. The &lt;code&gt;./configure&lt;/code&gt; step only needs to be run once. You can build the CPython binary by running:&lt;/p&gt;
2997 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; make -j2 -s
2998 &lt;/pre&gt;&lt;/div&gt;
2999 
3000 &lt;p&gt;The &lt;code&gt;-j2&lt;/code&gt; flag allows &lt;code&gt;make&lt;/code&gt; to run 2 jobs simultaneously. If you have 4 cores, you can change this to 4. The &lt;code&gt;-s&lt;/code&gt; flag stops the &lt;code&gt;Makefile&lt;/code&gt; from printing every command it runs to the console. You can remove this, but the output is very verbose.&lt;/p&gt;
3001 &lt;p&gt;During the build, you may receive some errors, and in the summary, it will notify you that not all packages could be built. For example, &lt;code&gt;_dbm&lt;/code&gt;, &lt;code&gt;_sqlite3&lt;/code&gt;, &lt;code&gt;_uuid&lt;/code&gt;, &lt;code&gt;nis&lt;/code&gt;, &lt;code&gt;ossaudiodev&lt;/code&gt;, &lt;code&gt;spwd&lt;/code&gt;, and &lt;code&gt;_tkinter&lt;/code&gt; would fail to build with this set of instructions. That&amp;rsquo;s okay if you aren&amp;rsquo;t planning on developing against those packages. If you are, then check out the &lt;a href=&quot;https://devguide.python.org/&quot;&gt;dev guide&lt;/a&gt; website for more information.&lt;/p&gt;
3002 &lt;p&gt;The build will take a few minutes and generate a binary called &lt;code&gt;python.exe&lt;/code&gt;.  Every time you make changes to the source code, you will need to re-run &lt;code&gt;make&lt;/code&gt; with the same flags.
3003 The &lt;code&gt;python.exe&lt;/code&gt; binary is the debug binary of CPython. Execute &lt;code&gt;python.exe&lt;/code&gt; to see a working REPL:&lt;/p&gt;
3004 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ./python.exe
3005 &lt;span class=&quot;go&quot;&gt;Python 3.8.0b4 (tags/v3.8.0b4:d93605de72, Aug 30 2019, 10:00:03) &lt;/span&gt;
3006 &lt;span class=&quot;go&quot;&gt;[Clang 10.0.1 (clang-1001.0.46.4)] on darwin&lt;/span&gt;
3007 &lt;span class=&quot;go&quot;&gt;Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;/span&gt;
3008 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&lt;/span&gt;&amp;gt;&amp;gt; 
3009 &lt;/pre&gt;&lt;/div&gt;
3010 
3011 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
3012 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; 
3013 Yes, that&amp;rsquo;s right, the macOS build has a file extension for &lt;code&gt;.exe&lt;/code&gt;. This is &lt;em&gt;not&lt;/em&gt; because it&amp;rsquo;s a Windows binary. Because macOS has a case-insensitive filesystem and when working with the binary, the developers didn&amp;rsquo;t want people to accidentally refer to the directory &lt;code&gt;Python/&lt;/code&gt; so &lt;code&gt;.exe&lt;/code&gt; was appended to avoid ambiguity.
3014 If you later run &lt;code&gt;make install&lt;/code&gt; or &lt;code&gt;make altinstall&lt;/code&gt;, it will rename the file back to &lt;code&gt;python&lt;/code&gt;.&lt;/p&gt;
3015 &lt;/div&gt;
3016 &lt;h3 id=&quot;compiling-cpython-linux&quot;&gt;Compiling CPython (Linux)&lt;/h3&gt;
3017 &lt;p&gt;For Linux, the first step is to download and install &lt;code&gt;make&lt;/code&gt;, &lt;code&gt;gcc&lt;/code&gt;, &lt;code&gt;configure&lt;/code&gt;, and &lt;code&gt;pkgconfig&lt;/code&gt;. &lt;/p&gt;
3018 &lt;p&gt;For Fedora Core, RHEL, CentOS, or other yum-based systems: &lt;/p&gt;
3019 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo yum install yum-utils
3020 &lt;/pre&gt;&lt;/div&gt;
3021 
3022 &lt;p&gt;For Debian, Ubuntu, or other &lt;code&gt;apt&lt;/code&gt;-based systems:&lt;/p&gt;
3023 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo apt install build-essential
3024 &lt;/pre&gt;&lt;/div&gt;
3025 
3026 &lt;p&gt;Then install the required packages, for Fedora Core, RHEL, CentOS or other yum-based systems: &lt;/p&gt;
3027 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo yum-builddep python3
3028 &lt;/pre&gt;&lt;/div&gt;
3029 
3030 &lt;p&gt;For Debian, Ubuntu, or other &lt;code&gt;apt&lt;/code&gt;-based systems:&lt;/p&gt;
3031 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo apt install libssl-dev zlib1g-dev libncurses5-dev &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
3032   libncursesw5-dev libreadline-dev libsqlite3-dev libgdbm-dev &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
3033   libdb5.3-dev libbz2-dev libexpat1-dev liblzma-dev libffi-dev
3034 &lt;/pre&gt;&lt;/div&gt;
3035 
3036 &lt;p&gt;Now that you have the dependencies, you can run the &lt;code&gt;configure&lt;/code&gt; script, enabling the debug hooks &lt;code&gt;--with-pydebug&lt;/code&gt;:&lt;/p&gt;
3037 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ./configure --with-pydebug
3038 &lt;/pre&gt;&lt;/div&gt;
3039 
3040 &lt;p&gt;Review the output to ensure that OpenSSL support was marked as &lt;code&gt;YES&lt;/code&gt;. Otherwise, check with your distribution for instructions on installing the headers for OpenSSL.&lt;/p&gt;
3041 &lt;p&gt;Next, you can build the CPython binary by running the generated &lt;code&gt;Makefile&lt;/code&gt;:&lt;/p&gt;
3042 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; make -j2 -s
3043 &lt;/pre&gt;&lt;/div&gt;
3044 
3045 &lt;p&gt;During the build, you may receive some errors, and in the summary, it will notify you that not all packages could be built. That&amp;rsquo;s okay if you aren&amp;rsquo;t planning on developing against those packages. If you are, then check out the &lt;a href=&quot;https://devguide.python.org/&quot;&gt;dev guide&lt;/a&gt; website for more information.&lt;/p&gt;
3046 &lt;p&gt;The build will take a few minutes and generate a binary called &lt;code&gt;python&lt;/code&gt;. This is the debug binary of CPython. Execute &lt;code&gt;./python&lt;/code&gt; to see a working REPL:&lt;/p&gt;
3047 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ./python
3048 &lt;span class=&quot;go&quot;&gt;Python 3.8.0b4 (tags/v3.8.0b4:d93605de72, Aug 30 2019, 10:00:03) &lt;/span&gt;
3049 &lt;span class=&quot;go&quot;&gt;[Clang 10.0.1 (clang-1001.0.46.4)] on darwin&lt;/span&gt;
3050 &lt;span class=&quot;go&quot;&gt;Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;/span&gt;
3051 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&lt;/span&gt;&amp;gt;&amp;gt; 
3052 &lt;/pre&gt;&lt;/div&gt;
3053 
3054 &lt;h3 id=&quot;compiling-cpython-windows&quot;&gt;Compiling CPython (Windows)&lt;/h3&gt;
3055 &lt;p&gt;Inside the PC folder is a Visual Studio project file for building and exploring CPython. To use this, you need to have Visual Studio installed on your PC.&lt;/p&gt;
3056 &lt;p&gt;The newest version of Visual Studio, Visual Studio 2019, makes it easier to work with Python and the CPython source code, so it is recommended for use in this tutorial. If you already have Visual Studio 2017 installed, that would also work fine.&lt;/p&gt;
3057 &lt;p&gt;None of the paid features are required for compiling CPython or this tutorial. You can use the Community edition of Visual Studio, which is available for free from &lt;a href=&quot;https://visualstudio.microsoft.com/vs/&quot;&gt;Microsoft&amp;rsquo;s Visual Studio website&lt;/a&gt;.&lt;/p&gt;
3058 &lt;p&gt;Once you&amp;rsquo;ve downloaded the installer, you&amp;rsquo;ll be asked to select which components you want to install. The bare minimum for this tutorial is:&lt;/p&gt;
3059 &lt;ul&gt;
3060 &lt;li&gt;The &lt;strong&gt;Python Development&lt;/strong&gt; workload&lt;/li&gt;
3061 &lt;li&gt;The optional &lt;strong&gt;Python native development tools&lt;/strong&gt;&lt;/li&gt;
3062 &lt;li&gt;Python 3 64-bit (3.7.2) (can be deselected if you already have Python 3.7 installed)&lt;/li&gt;
3063 &lt;/ul&gt;
3064 &lt;p&gt;Any other optional features can be deselected if you want to be more conscientious with disk space:&lt;/p&gt;
3065 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screen_Shot_2019-08-22_at_2.47.23_pm.5e8682a89503.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/Screen_Shot_2019-08-22_at_2.47.23_pm.5e8682a89503.png&quot; width=&quot;2504&quot; height=&quot;1260&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screen_Shot_2019-08-22_at_2.47.23_pm.5e8682a89503.png&amp;amp;w=626&amp;amp;sig=86eb9f82580a69f533983087ba0fa4faf0d5bf96 626w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screen_Shot_2019-08-22_at_2.47.23_pm.5e8682a89503.png&amp;amp;w=1252&amp;amp;sig=fe2157486f81073eabe043b3c441af23dd67b78a 1252w, https://files.realpython.com/media/Screen_Shot_2019-08-22_at_2.47.23_pm.5e8682a89503.png 2504w&quot; sizes=&quot;75vw&quot; alt=&quot;Visual Studio Options Window&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3066 &lt;p&gt;The installer will then download and install all of the required components. The installation could take an hour, so you may want to read on and come back to this section.&lt;/p&gt;
3067 &lt;p&gt;Once the installer has completed, click the &lt;em&gt;Launch&lt;/em&gt; button to start Visual Studio. You will be prompted to sign in. If you have a Microsoft account you can log in, or skip that step.&lt;/p&gt;
3068 &lt;p&gt;Once Visual Studio starts, you will be prompted to Open a Project. A shortcut to getting started with the Git configuration and cloning CPython is to choose the &lt;em&gt;Clone or check out code&lt;/em&gt; option:&lt;/p&gt;
3069 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Capture3.e19765d74ec4.PNG&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/Capture3.e19765d74ec4.PNG&quot; width=&quot;2048&quot; height=&quot;1420&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Capture3.e19765d74ec4.PNG&amp;amp;w=512&amp;amp;sig=e475e2a09cd780894f108850f91736c53ac95f27 512w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Capture3.e19765d74ec4.PNG&amp;amp;w=1024&amp;amp;sig=47d66a316c2546c9787e5af4cb4a9a006dca936d 1024w, https://files.realpython.com/media/Capture3.e19765d74ec4.PNG 2048w&quot; sizes=&quot;75vw&quot; alt=&quot;Choosing a Project Type in Visual Studio&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3070 &lt;p&gt;For the project URL, type &lt;code&gt;https://github.com/python/cpython&lt;/code&gt; to clone:&lt;/p&gt;
3071 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Capture4.ea01418a971c.PNG&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/Capture4.ea01418a971c.PNG&quot; width=&quot;2048&quot; height=&quot;1420&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Capture4.ea01418a971c.PNG&amp;amp;w=512&amp;amp;sig=47ed81b234652446a4f0e77e2a3f70e0074ac222 512w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Capture4.ea01418a971c.PNG&amp;amp;w=1024&amp;amp;sig=de393823fe557847f295d040573bd061b2ccd557 1024w, https://files.realpython.com/media/Capture4.ea01418a971c.PNG 2048w&quot; sizes=&quot;75vw&quot; alt=&quot;Cloning projects in Visual Studio&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3072 &lt;p&gt;Visual Studio will then download a copy of CPython from GitHub using the version of Git bundled with Visual Studio. This step also saves you the hassle of having to install Git on Windows. The download may take 10 minutes.&lt;/p&gt;
3073 &lt;p&gt;Once the project has downloaded, you need to point it to the &lt;strong&gt;&lt;code&gt;pcbuild&lt;/code&gt;&lt;/strong&gt; Solution file, by clicking on &lt;em&gt;Solutions and Projects&lt;/em&gt; and selecting &lt;code&gt;pcbuild.sln&lt;/code&gt;:&lt;/p&gt;
3074 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Capture6.3d06a62b8e87.PNG&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border w-50&quot; src=&quot;https://files.realpython.com/media/Capture6.3d06a62b8e87.PNG&quot; width=&quot;863&quot; height=&quot;565&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Capture6.3d06a62b8e87.PNG&amp;amp;w=215&amp;amp;sig=0d4c23758a58848ea65b74514aca9e15a72748fa 215w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Capture6.3d06a62b8e87.PNG&amp;amp;w=431&amp;amp;sig=05f0ebe121ef54abf51bcdb55fba695d28656868 431w, https://files.realpython.com/media/Capture6.3d06a62b8e87.PNG 863w&quot; sizes=&quot;75vw&quot; alt=&quot;Selecting a solution&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3075 &lt;p&gt;When the solution is loaded, it will prompt you to retarget the project&amp;rsquo;s inside the solution to the version of the C/C++ compiler you have installed. Visual Studio will also target the version of the Windows SDK you have installed.&lt;/p&gt;
3076 &lt;p&gt;Ensure that you change the Windows SDK version to the newest installed version and the platform toolset to the latest version. If you missed this window, you can right-click on the Solution in the &lt;em&gt;Solutions and Projects&lt;/em&gt; window and click &lt;em&gt;Retarget Solution&lt;/em&gt;.&lt;/p&gt;
3077 &lt;p&gt;Once this is complete, you need to download some source files to be able to build the whole CPython package. Inside the &lt;code&gt;PCBuild&lt;/code&gt; folder there is a &lt;code&gt;.bat&lt;/code&gt; file that automates this for you. &lt;a href=&quot;https://www.youtube.com/watch?v=bgSSJQolR0E&quot;&gt;Open up a command-line prompt inside&lt;/a&gt; the downloaded &lt;code&gt;PCBuild&lt;/code&gt; and run &lt;code&gt;get_externals.bat&lt;/code&gt;:&lt;/p&gt;
3078 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt; &amp;gt; get_externals.bat&lt;/span&gt;
3079 &lt;span class=&quot;go&quot;&gt;Using py -3.7 (found 3.7 with py.exe)&lt;/span&gt;
3080 &lt;span class=&quot;go&quot;&gt;Fetching external libraries...&lt;/span&gt;
3081 &lt;span class=&quot;go&quot;&gt;Fetching bzip2-1.0.6...&lt;/span&gt;
3082 &lt;span class=&quot;go&quot;&gt;Fetching sqlite-3.21.0.0...&lt;/span&gt;
3083 &lt;span class=&quot;go&quot;&gt;Fetching xz-5.2.2...&lt;/span&gt;
3084 &lt;span class=&quot;go&quot;&gt;Fetching zlib-1.2.11...&lt;/span&gt;
3085 &lt;span class=&quot;go&quot;&gt;Fetching external binaries...&lt;/span&gt;
3086 &lt;span class=&quot;go&quot;&gt;Fetching openssl-bin-1.1.0j...&lt;/span&gt;
3087 &lt;span class=&quot;go&quot;&gt;Fetching tcltk-8.6.9.0...&lt;/span&gt;
3088 &lt;span class=&quot;go&quot;&gt;Finished.&lt;/span&gt;
3089 &lt;/pre&gt;&lt;/div&gt;
3090 
3091 &lt;p&gt;Next, back within Visual Studio, build CPython by pressing &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-shift&quot;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-b&quot;&gt;B&lt;/kbd&gt;&lt;/span&gt;, or choosing &lt;em&gt;Build Solution&lt;/em&gt; from the top menu. If you receive any errors about the Windows SDK being missing, make sure you set the right targeting settings in the &lt;em&gt;Retarget Solution&lt;/em&gt; window. You should also see &lt;em&gt;Windows Kits&lt;/em&gt; inside your Start Menu, and &lt;em&gt;Windows Software Development Kit&lt;/em&gt; inside of that menu.&lt;/p&gt;
3092 &lt;p&gt;The build stage could take 10 minutes or more for the first time. Once the build is completed, you may see a few warnings that you can ignore and eventual completion.&lt;/p&gt;
3093 &lt;p&gt;To start the debug version of CPython, press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-f5&quot;&gt;F5&lt;/kbd&gt;&lt;/span&gt; and CPython will start in Debug mode straight into the REPL:&lt;/p&gt;
3094 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Capture8.967a3606daf0.PNG&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Capture8.967a3606daf0.PNG&quot; width=&quot;3360&quot; height=&quot;2100&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Capture8.967a3606daf0.PNG&amp;amp;w=840&amp;amp;sig=1822fde8ffe6946fc91e47dd8975aa23add8b23a 840w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Capture8.967a3606daf0.PNG&amp;amp;w=1680&amp;amp;sig=a093e68320ad548384c585840002e4294ab4bf94 1680w, https://files.realpython.com/media/Capture8.967a3606daf0.PNG 3360w&quot; sizes=&quot;75vw&quot; alt=&quot;CPython debugging Windows&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3095 &lt;p&gt;Once this is completed, you can run the Release build by changing the build configuration from &lt;em&gt;Debug&lt;/em&gt; to &lt;em&gt;Release&lt;/em&gt; on the top menu bar and rerunning Build Solution again.
3096 You now have both Debug and Release versions of the CPython binary within &lt;code&gt;PCBuild\win32\&lt;/code&gt;.&lt;/p&gt;
3097 &lt;p&gt;You can set up Visual Studio to be able to open a REPL with either the Release or Debug build by choosing &lt;em&gt;&lt;code&gt;Tools&lt;/code&gt;-&amp;gt;&lt;code&gt;Python&lt;/code&gt;-&amp;gt;&lt;code&gt;Python Environments&lt;/code&gt;&lt;/em&gt; from the top menu:&lt;/p&gt;
3098 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Environments.96a819ecf0b3.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/Environments.96a819ecf0b3.png&quot; width=&quot;3360&quot; height=&quot;2033&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Environments.96a819ecf0b3.png&amp;amp;w=840&amp;amp;sig=f8dd9b3b31d44c25cbe06d56078b0462cb0fa753 840w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Environments.96a819ecf0b3.png&amp;amp;w=1680&amp;amp;sig=e8ca69be87363b62ccda44bcf53bedd4e4e320c2 1680w, https://files.realpython.com/media/Environments.96a819ecf0b3.png 3360w&quot; sizes=&quot;75vw&quot; alt=&quot;Choosing Python environments&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3099 &lt;p&gt;Then click &lt;em&gt;Add Environment&lt;/em&gt; and then target the Debug or Release binary. The Debug binary will end in &lt;code&gt;_d.exe&lt;/code&gt;, for example, &lt;code&gt;python_d.exe&lt;/code&gt; and &lt;code&gt;pythonw_d.exe&lt;/code&gt;. You will most likely want to use the debug binary as it comes with Debugging support in Visual Studio and will be useful for this tutorial.&lt;/p&gt;
3100 &lt;p&gt;In the Add Environment window, target the &lt;code&gt;python_d.exe&lt;/code&gt; file as the interpreter inside the &lt;code&gt;PCBuild/win32&lt;/code&gt; and the &lt;code&gt;pythonw_d.exe&lt;/code&gt; as the windowed interpreter:&lt;/p&gt;
3101 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/environment3.d33858c1f6aa.PNG&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/environment3.d33858c1f6aa.PNG&quot; width=&quot;2048&quot; height=&quot;1352&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/environment3.d33858c1f6aa.PNG&amp;amp;w=512&amp;amp;sig=ffc6b359ac60d689f40f98233466cef35354d239 512w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/environment3.d33858c1f6aa.PNG&amp;amp;w=1024&amp;amp;sig=d881ce7ecabc62624fb2a5154102a5be2ff6a4db 1024w, https://files.realpython.com/media/environment3.d33858c1f6aa.PNG 2048w&quot; sizes=&quot;75vw&quot; alt=&quot;Adding an environment in VS2019&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3102 &lt;p&gt;Now, you can start a REPL session by clicking &lt;em&gt;Open Interactive Window&lt;/em&gt; in the Python Environments window and you will see the REPL for the compiled version of Python:&lt;/p&gt;
3103 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/environment4.7c9eade3b74e.PNG&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/environment4.7c9eade3b74e.PNG&quot; width=&quot;3360&quot; height=&quot;2033&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/environment4.7c9eade3b74e.PNG&amp;amp;w=840&amp;amp;sig=9e384e72bcfdebb39fe6dc23f21c239a0895ad51 840w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/environment4.7c9eade3b74e.PNG&amp;amp;w=1680&amp;amp;sig=be56aac5b9baffc9b8b0de4701527954ed32ef53 1680w, https://files.realpython.com/media/environment4.7c9eade3b74e.PNG 3360w&quot; sizes=&quot;75vw&quot; alt=&quot;Python Environment REPL&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3104 &lt;p&gt;During this tutorial there will be REPL sessions with example commands. I encourage you to use the Debug binary to run these REPL sessions in case you want to put in any breakpoints within the code.&lt;/p&gt;
3105 &lt;p&gt;Lastly, to make it easier to navigate the code, in the Solution View, click on the toggle button next to the Home icon to switch to Folder view:&lt;/p&gt;
3106 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/environments5.6462694398e3.6fb872a5f57d.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/environments5.6462694398e3.6fb872a5f57d.png&quot; width=&quot;1231&quot; height=&quot;692&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/environments5.6462694398e3.6fb872a5f57d.png&amp;amp;w=307&amp;amp;sig=14bf2b50bd86dfabedc3ee1ec75a60ebccd574c4 307w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/environments5.6462694398e3.6fb872a5f57d.png&amp;amp;w=615&amp;amp;sig=0d5644853d8c429ccc78fc1bced16d8f571f555d 615w, https://files.realpython.com/media/environments5.6462694398e3.6fb872a5f57d.png 1231w&quot; sizes=&quot;75vw&quot; alt=&quot;Switching Environment Mode&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3107 &lt;p&gt;Now you have a version of CPython compiled and ready to go, let&amp;rsquo;s find out how the CPython compiler works.&lt;/p&gt;
3108 &lt;h3 id=&quot;what-does-a-compiler-do&quot;&gt;What Does a Compiler Do?&lt;/h3&gt;
3109 &lt;p&gt;The purpose of a compiler is to convert one language into another. Think of a compiler like a translator. You would hire a translator to listen to you speaking in English and then speak in Japanese:&lt;/p&gt;
3110 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/t.38be306a7e83.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-75&quot; src=&quot;https://files.realpython.com/media/t.38be306a7e83.png&quot; width=&quot;960&quot; height=&quot;540&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/t.38be306a7e83.png&amp;amp;w=240&amp;amp;sig=2ad6eec49af1eaba79b83c099925e01a970d5efd 240w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/t.38be306a7e83.png&amp;amp;w=480&amp;amp;sig=033587107c8dceca7bcc292527a4c815fffb0b8d 480w, https://files.realpython.com/media/t.38be306a7e83.png 960w&quot; sizes=&quot;75vw&quot; alt=&quot;Translating from English to Japanese&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3111 &lt;p&gt;Some compilers will compile into a low-level machine code which can be executed directly on a system. Other compilers will compile into an intermediary language, to be executed by a virtual machine.&lt;/p&gt;
3112 &lt;p&gt;One important decision to make when choosing a compiler is the system portability requirements. &lt;a href=&quot;https://en.wikipedia.org/wiki/Java_bytecode&quot;&gt;Java&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Common_Language_Runtime&quot;&gt;.NET CLR&lt;/a&gt; will compile into an Intermediary Language so that the compiled code is portable across multiple systems architectures. C, Go, C++, and Pascal will compile into a low-level executable that will only work on systems similar to the one it was compiled. &lt;/p&gt;
3113 &lt;p&gt;Because Python applications are typically distributed as source code, the role of the Python runtime is to convert the Python source code and execute it in one step. Internally, the CPython runtime does compile your code. A popular misconception is that Python is an interpreted language. It is actually compiled.&lt;/p&gt;
3114 &lt;p&gt;Python code is not compiled into machine-code. It is compiled into a special low-level intermediary language called &lt;strong&gt;bytecode&lt;/strong&gt; that only CPython understands. This code is stored in &lt;code&gt;.pyc&lt;/code&gt; files in a hidden directory and cached for execution. If you run the same Python application twice without changing the source code, it&amp;rsquo;ll always be much faster the second time. This is because it loads the compiled bytecode and executes it directly.&lt;/p&gt;
3115 &lt;h3 id=&quot;why-is-cpython-written-in-c-and-not-python&quot;&gt;Why Is CPython Written in C and Not Python?&lt;/h3&gt;
3116 &lt;p&gt;The &lt;strong&gt;C&lt;/strong&gt; in CPython is a reference to the C programming language, implying that this Python distribution is written in the C language.&lt;/p&gt;
3117 &lt;p&gt;This statement is largely true: the compiler in CPython is written in pure C. However, many of the standard library modules are written in pure Python or a combination of C and Python.&lt;/p&gt;
3118 &lt;p&gt;&lt;strong&gt;So why is CPython written in C and not Python?&lt;/strong&gt;&lt;/p&gt;
3119 &lt;p&gt;The answer is located in how compilers work. There are two types of compiler:&lt;/p&gt;
3120 &lt;ol&gt;
3121 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Self-hosting&quot;&gt;Self-hosted compilers&lt;/a&gt;&lt;/strong&gt; are compilers written in the language they compile, such as the Go compiler.&lt;/li&gt;
3122 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Source-to-source_compiler&quot;&gt;Source-to-source compilers&lt;/a&gt;&lt;/strong&gt; are compilers written in another language that already have a compiler.&lt;/li&gt;
3123 &lt;/ol&gt;
3124 &lt;p&gt;If you&amp;rsquo;re writing a new programming language from scratch, you need an executable application to compile your compiler! You need a compiler to execute anything, so when new languages are developed, they&amp;rsquo;re often written first in an older, more established language.&lt;/p&gt;
3125 &lt;p&gt;A good example would be the Go programming language. The first Go compiler was written in C, then once Go could be compiled, the compiler was rewritten in Go. &lt;/p&gt;
3126 &lt;p&gt;CPython kept its C heritage: many of the standard library modules, like the &lt;code&gt;ssl&lt;/code&gt; module or the &lt;code&gt;sockets&lt;/code&gt; module, are written in C to access low-level operating system APIs.
3127 The APIs in the Windows and Linux kernels for &lt;a href=&quot;https://realpython.com/python-sockets/&quot;&gt;creating network sockets&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/working-with-files-in-python/&quot;&gt;working with the filesystem&lt;/a&gt; or &lt;a href=&quot;https://realpython.com/python-gui-with-wxpython/&quot;&gt;interacting with the display&lt;/a&gt; are all written in C. It made sense for Python&amp;rsquo;s extensibility layer to be focused on the C language. Later in this article, we will cover the Python Standard Library and the C modules.&lt;/p&gt;
3128 &lt;p&gt;There is a Python compiler written in Python called &lt;a href=&quot;https://pypy.org/&quot;&gt;PyPy&lt;/a&gt;. PyPy&amp;rsquo;s logo is an &lt;a href=&quot;https://en.wikipedia.org/wiki/Ouroboros&quot;&gt;Ouroboros&lt;/a&gt; to represent the self-hosting nature of the compiler.&lt;/p&gt;
3129 &lt;p&gt;Another example of a cross-compiler for Python is &lt;a href=&quot;https://www.jython.org/&quot;&gt;Jython&lt;/a&gt;. Jython is written in Java and compiles from Python source code into Java bytecode. In the same way that CPython makes it easy to import C libraries and use them from Python, Jython makes it easy to import and reference Java modules and classes.&lt;/p&gt;
3130 &lt;h3 id=&quot;the-python-language-specification&quot;&gt;The Python Language Specification&lt;/h3&gt;
3131 &lt;p&gt;Contained within the CPython source code is the definition of the Python language. This is the reference specification used by all the Python interpreters.&lt;/p&gt;
3132 &lt;p&gt;The specification is in both human-readable and machine-readable format. Inside the documentation is a detailed explanation of the Python language, what is allowed, and how each statement should behave.&lt;/p&gt;
3133 &lt;h4 id=&quot;documentation&quot;&gt;Documentation&lt;/h4&gt;
3134 &lt;p&gt;Located inside the &lt;code&gt;Doc/reference&lt;/code&gt; directory are &lt;a href=&quot;http://docutils.sourceforge.net/rst.html&quot;&gt;reStructuredText&lt;/a&gt; explanations of each of the features in the Python language. This forms the official Python reference guide on &lt;a href=&quot;https://docs.python.org/3/reference/&quot;&gt;docs.python.org&lt;/a&gt;.&lt;/p&gt;
3135 &lt;p&gt;Inside the directory are the files you need to understand the whole language, structure, and keywords:&lt;/p&gt;
3136 &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;cpython/Doc/reference
3137 |
3138 ├── compound_stmts.rst
3139 ├── datamodel.rst
3140 ├── executionmodel.rst
3141 ├── expressions.rst
3142 ├── grammar.rst
3143 ├── import.rst
3144 ├── index.rst
3145 ├── introduction.rst
3146 ├── lexical_analysis.rst
3147 ├── simple_stmts.rst
3148 └── toplevel_components.rst
3149 &lt;/pre&gt;&lt;/div&gt;
3150 
3151 &lt;p&gt;Inside &lt;code&gt;compound_stmts.rst&lt;/code&gt;, the documentation for compound statements, you can see a simple example defining the &lt;code&gt;with&lt;/code&gt; statement.&lt;/p&gt;
3152 &lt;p&gt;The &lt;code&gt;with&lt;/code&gt; statement can be used in multiple ways in Python, the simplest being the &lt;a href=&quot;https://dbader.org/blog/python-context-managers-and-with-statement&quot;&gt;instantiation of a context-manager&lt;/a&gt; and a nested block of code:&lt;/p&gt;
3153 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
3154    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
3155 &lt;/pre&gt;&lt;/div&gt;
3156 
3157 &lt;p&gt;You can assign the result to a variable using the &lt;code&gt;as&lt;/code&gt; keyword:&lt;/p&gt;
3158 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
3159    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
3160 &lt;/pre&gt;&lt;/div&gt;
3161 
3162 &lt;p&gt;You can also chain context managers together with a comma:&lt;/p&gt;
3163 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;jk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
3164    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
3165 &lt;/pre&gt;&lt;/div&gt;
3166 
3167 &lt;p&gt;Next, we&amp;rsquo;ll explore the computer-readable documentation of the Python language.&lt;/p&gt;
3168 &lt;h4 id=&quot;grammar&quot;&gt;Grammar&lt;/h4&gt;
3169 &lt;p&gt;The documentation contains the human-readable specification of the language, and the machine-readable specification is housed in a single file, &lt;a href=&quot;https://github.com/python/cpython/blob/master/Grammar/Grammar&quot;&gt;&lt;code&gt;Grammar/Grammar&lt;/code&gt;&lt;/a&gt;. &lt;/p&gt;
3170 &lt;p&gt;The Grammar file is written in a context-notation called &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Backus%E2%80%93Naur_form&quot;&gt;Backus-Naur Form (BNF)&lt;/a&gt;. BNF is not specific to Python and is often used as the notation for grammars in many other languages.&lt;/p&gt;
3171 &lt;p&gt;The concept of grammatical structure in a programming language is inspired by &lt;a href=&quot;https://en.wikipedia.org/wiki/Syntactic_Structures&quot;&gt;Noam Chomsky&amp;rsquo;s work on Syntactic Structures&lt;/a&gt; in the 1950s!&lt;/p&gt;
3172 &lt;p&gt;Python&amp;rsquo;s grammar file uses the Extended-BNF (EBNF) specification with regular-expression syntax. So, in the grammar file you can use:&lt;/p&gt;
3173 &lt;ul&gt;
3174 &lt;li&gt;&lt;strong&gt;&lt;code&gt;*&lt;/code&gt;&lt;/strong&gt; for repetition&lt;/li&gt;
3175 &lt;li&gt;&lt;strong&gt;&lt;code&gt;+&lt;/code&gt;&lt;/strong&gt; for at-least-once repetition&lt;/li&gt;
3176 &lt;li&gt;&lt;strong&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/strong&gt; for optional parts&lt;/li&gt;
3177 &lt;li&gt;&lt;strong&gt;&lt;code&gt;|&lt;/code&gt;&lt;/strong&gt; for alternatives&lt;/li&gt;
3178 &lt;li&gt;&lt;strong&gt;&lt;code&gt;()&lt;/code&gt;&lt;/strong&gt; for grouping&lt;/li&gt;
3179 &lt;/ul&gt;
3180 &lt;p&gt;If you search for the &lt;code&gt;with&lt;/code&gt; statement in the grammar file, at around line 80 you&amp;rsquo;ll see the definitions for the &lt;code&gt;with&lt;/code&gt; statement:&lt;/p&gt;
3181 &lt;div class=&quot;highlight text&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;with_stmt: &amp;#39;with&amp;#39; with_item (&amp;#39;,&amp;#39; with_item)*  &amp;#39;:&amp;#39; suite
3182 with_item: test [&amp;#39;as&amp;#39; expr]
3183 &lt;/pre&gt;&lt;/div&gt;
3184 
3185 &lt;p&gt;Anything in quotes is a string literal, which is how keywords are defined. So the &lt;code&gt;with_stmt&lt;/code&gt; is specified as:&lt;/p&gt;
3186 &lt;ol&gt;
3187 &lt;li&gt;Starting with the word &lt;code&gt;with&lt;/code&gt;&lt;/li&gt;
3188 &lt;li&gt;Followed by a &lt;code&gt;with_item&lt;/code&gt;, which is a &lt;code&gt;test&lt;/code&gt; and (optionally), the word &lt;code&gt;as&lt;/code&gt;, and an expression&lt;/li&gt;
3189 &lt;li&gt;Following one or many items, each separated by a comma&lt;/li&gt;
3190 &lt;li&gt;Ending with a &lt;code&gt;:&lt;/code&gt;&lt;/li&gt;
3191 &lt;li&gt;Followed by a &lt;code&gt;suite&lt;/code&gt;&lt;/li&gt;
3192 &lt;/ol&gt;
3193 &lt;p&gt;There are references to some other definitions in these two lines:&lt;/p&gt;
3194 &lt;ul&gt;
3195 &lt;li&gt;&lt;strong&gt;&lt;code&gt;suite&lt;/code&gt;&lt;/strong&gt; refers to a block of code with one or multiple statements&lt;/li&gt;
3196 &lt;li&gt;&lt;strong&gt;&lt;code&gt;test&lt;/code&gt;&lt;/strong&gt; refers to a simple statement that is evaluated&lt;/li&gt;
3197 &lt;li&gt;&lt;strong&gt;&lt;code&gt;expr&lt;/code&gt;&lt;/strong&gt; refers to a simple expression&lt;/li&gt;
3198 &lt;/ul&gt;
3199 &lt;p&gt;If you want to explore those in detail, the whole of the Python grammar is defined in this single file.&lt;/p&gt;
3200 &lt;p&gt;If you want to see a recent example of how grammar is used, in PEP 572 the &lt;strong&gt;colon equals&lt;/strong&gt; operator was added to the grammar file in &lt;a href=&quot;https://github.com/python/cpython/commit/8f59ee01be3d83d5513a9a3f654a237d77d80d9a#diff-cb0b9d6312c0d67f6d4aa1966766cedd&quot;&gt;this Git commit&lt;/a&gt;.&lt;/p&gt;
3201 &lt;h4 id=&quot;using-pgen&quot;&gt;Using &lt;code&gt;pgen&lt;/code&gt;&lt;/h4&gt;
3202 &lt;p&gt;The grammar file itself is never used by the Python compiler. Instead, a parser table created by a tool called &lt;code&gt;pgen&lt;/code&gt; is used. &lt;code&gt;pgen&lt;/code&gt; reads the grammar file and converts it into a parser table. If you make changes to the grammar file, you must regenerate the parser table and recompile Python.&lt;/p&gt;
3203 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
3204 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;pgen&lt;/code&gt; application was rewritten in Python 3.8 from C to &lt;a href=&quot;https://github.com/python/cpython/blob/master/Parser/pgen/pgen.py&quot;&gt;pure Python&lt;/a&gt;.&lt;/p&gt;
3205 &lt;/div&gt;
3206 &lt;p&gt;To see &lt;code&gt;pgen&lt;/code&gt; in action, let&amp;rsquo;s change part of the Python grammar. Around line 51 you will see the definition of a &lt;code&gt;pass&lt;/code&gt; statement:&lt;/p&gt;
3207 &lt;div class=&quot;highlight text&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;pass_stmt: &amp;#39;pass&amp;#39;
3208 &lt;/pre&gt;&lt;/div&gt;
3209 
3210 &lt;p&gt;Change that line to accept the keyword &lt;code&gt;&#39;pass&#39;&lt;/code&gt; or &lt;code&gt;&#39;proceed&#39;&lt;/code&gt; as keywords:&lt;/p&gt;
3211 &lt;div class=&quot;highlight text&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;pass_stmt: &amp;#39;pass&amp;#39; | &amp;#39;proceed&amp;#39;
3212 &lt;/pre&gt;&lt;/div&gt;
3213 
3214 &lt;p&gt;Now you need to rebuild the grammar files.
3215 On macOS and Linux, run &lt;code&gt;make regen-grammar&lt;/code&gt; to run &lt;code&gt;pgen&lt;/code&gt; over the altered grammar file. For Windows, there is no officially supported way of running &lt;code&gt;pgen&lt;/code&gt;. However, you can clone &lt;a href=&quot;https://github.com/tonybaloney/cpython/tree/pcbuildregen&quot;&gt;my fork&lt;/a&gt; and run &lt;code&gt;build.bat --regen&lt;/code&gt; from within the &lt;code&gt;PCBuild&lt;/code&gt; directory.&lt;/p&gt;
3216 &lt;p&gt;You should see an output similar to this, showing that the new &lt;code&gt;Include/graminit.h&lt;/code&gt; and &lt;code&gt;Python/graminit.c&lt;/code&gt; files have been generated:&lt;/p&gt;
3217 &lt;div class=&quot;highlight text&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;# Regenerate Doc/library/token-list.inc from Grammar/Tokens
3218 # using Tools/scripts/generate_token.py
3219 ...
3220 python3 ./Tools/scripts/update_file.py ./Include/graminit.h ./Include/graminit.h.new
3221 python3 ./Tools/scripts/update_file.py ./Python/graminit.c ./Python/graminit.c.new
3222 &lt;/pre&gt;&lt;/div&gt;
3223 
3224 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
3225 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;pgen&lt;/code&gt; works by converting the EBNF statements into a &lt;a href=&quot;https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton&quot;&gt;Non-deterministic Finite Automaton (NFA)&lt;/a&gt;, which is then turned into a &lt;a href=&quot;https://en.wikipedia.org/wiki/Deterministic_finite_automaton&quot;&gt;Deterministic Finite Automaton (DFA)&lt;/a&gt;.
3226 The DFAs are used by the parser as parsing tables in a special way that&amp;rsquo;s unique to CPython. This technique was &lt;a href=&quot;http://infolab.stanford.edu/~ullman/dragon/slides1.pdf&quot;&gt;formed at Stanford University&lt;/a&gt; and developed in the 1980s, just before the advent of Python.&lt;/p&gt;
3227 &lt;/div&gt;
3228 &lt;p&gt;With the regenerated parser tables, you need to recompile CPython to see the new syntax. Use the same compilation steps you used earlier for your operating system.&lt;/p&gt;
3229 &lt;p&gt;If the code compiled successfully, you can execute your new CPython binary and start a REPL.&lt;/p&gt;
3230 &lt;p&gt;In the REPL, you can now try defining a function and instead of using the &lt;code&gt;pass&lt;/code&gt; statement, use the &lt;code&gt;proceed&lt;/code&gt; keyword alternative that you compiled into the Python grammar:&lt;/p&gt;
3231 &lt;div class=&quot;highlight text&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Python 3.8.0b4 (tags/v3.8.0b4:d93605de72, Aug 30 2019, 10:00:03) 
3232 [Clang 10.0.1 (clang-1001.0.46.4)] on darwin
3233 Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.
3234 &amp;gt;&amp;gt;&amp;gt; def example():
3235 ...    proceed
3236 ... 
3237 &amp;gt;&amp;gt;&amp;gt; example()
3238 &lt;/pre&gt;&lt;/div&gt;
3239 
3240 &lt;p&gt;Well done! You&amp;rsquo;ve changed the CPython syntax and compiled your own version of CPython. Ship it!&lt;/p&gt;
3241 &lt;p&gt;Next, we&amp;rsquo;ll explore tokens and their relationship to grammar.&lt;/p&gt;
3242 &lt;h4 id=&quot;tokens&quot;&gt;Tokens&lt;/h4&gt;
3243 &lt;p&gt;Alongside the grammar file in the &lt;code&gt;Grammar&lt;/code&gt; folder is a &lt;a href=&quot;https://github.com/python/cpython/blob/master/Grammar/Tokens&quot;&gt;&lt;code&gt;Tokens&lt;/code&gt;&lt;/a&gt; file, which contains each of the unique types found as a leaf node in a parse tree. We will cover parser trees in depth later.
3244 Each token also has a name and a generated unique ID. The names are used to make it simpler to refer to in the tokenizer.&lt;/p&gt;
3245 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
3246 &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;Tokens&lt;/code&gt; file is a new feature in Python 3.8.&lt;/p&gt;
3247 &lt;/div&gt;
3248 &lt;p&gt;For example, the left parenthesis is called &lt;code&gt;LPAR&lt;/code&gt;, and semicolons are called &lt;code&gt;SEMI&lt;/code&gt;. You&amp;rsquo;ll see these tokens later in the article:&lt;/p&gt;
3249 &lt;div class=&quot;highlight text&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;LPAR                    &amp;#39;(&amp;#39;
3250 RPAR                    &amp;#39;)&amp;#39;
3251 LSQB                    &amp;#39;[&amp;#39;
3252 RSQB                    &amp;#39;]&amp;#39;
3253 COLON                   &amp;#39;:&amp;#39;
3254 COMMA                   &amp;#39;,&amp;#39;
3255 SEMI                    &amp;#39;;&amp;#39;
3256 &lt;/pre&gt;&lt;/div&gt;
3257 
3258 &lt;p&gt;As with the &lt;code&gt;Grammar&lt;/code&gt; file, if you change the &lt;code&gt;Tokens&lt;/code&gt; file, you need to run &lt;code&gt;pgen&lt;/code&gt; again. &lt;/p&gt;
3259 &lt;p&gt;To see tokens in action, you can use the &lt;code&gt;tokenize&lt;/code&gt; module in CPython. Create a simple Python script called &lt;code&gt;test_tokens.py&lt;/code&gt;:&lt;/p&gt;
3260 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Hello world!&lt;/span&gt;
3261 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
3262    &lt;span class=&quot;n&quot;&gt;proceed&lt;/span&gt;
3263 &lt;/pre&gt;&lt;/div&gt;
3264 
3265 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
3266 &lt;p&gt;For the rest of this tutorial, &lt;code&gt;./python.exe&lt;/code&gt; will refer to the compiled version of CPython. However, the actual command will depend on your system.&lt;/p&gt;
3267 &lt;p&gt;For Windows:&lt;/p&gt;
3268 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt; &amp;gt; python.exe&lt;/span&gt;
3269 &lt;/pre&gt;&lt;/div&gt;
3270 
3271 &lt;p&gt;For Linux:&lt;/p&gt;
3272 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt; &amp;gt; ./python&lt;/span&gt;
3273 &lt;/pre&gt;&lt;/div&gt;
3274 
3275 &lt;p&gt;For macOS:&lt;/p&gt;
3276 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt; &amp;gt; ./python.exe&lt;/span&gt;
3277 &lt;/pre&gt;&lt;/div&gt;
3278 
3279 &lt;/div&gt;
3280 &lt;p&gt;Then pass this file through a module built into the standard library called &lt;code&gt;tokenize&lt;/code&gt;. You will see the list of tokens, by line and character. Use the &lt;code&gt;-e&lt;/code&gt; flag to output the exact token name:&lt;/p&gt;
3281 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ./python.exe -m tokenize -e test_tokens.py
3282 
3283 &lt;span class=&quot;go&quot;&gt;0,0-0,0:            ENCODING       &amp;#39;utf-8&amp;#39;        &lt;/span&gt;
3284 &lt;span class=&quot;go&quot;&gt;1,0-1,14:           COMMENT        &amp;#39;# Hello world!&amp;#39;&lt;/span&gt;
3285 &lt;span class=&quot;go&quot;&gt;1,14-1,15:          NL             &amp;#39;\n&amp;#39;           &lt;/span&gt;
3286 &lt;span class=&quot;go&quot;&gt;2,0-2,3:            NAME           &amp;#39;def&amp;#39;          &lt;/span&gt;
3287 &lt;span class=&quot;go&quot;&gt;2,4-2,15:           NAME           &amp;#39;my_function&amp;#39;  &lt;/span&gt;
3288 &lt;span class=&quot;go&quot;&gt;2,15-2,16:          LPAR           &amp;#39;(&amp;#39;            &lt;/span&gt;
3289 &lt;span class=&quot;go&quot;&gt;2,16-2,17:          RPAR           &amp;#39;)&amp;#39;            &lt;/span&gt;
3290 &lt;span class=&quot;go&quot;&gt;2,17-2,18:          COLON          &amp;#39;:&amp;#39;            &lt;/span&gt;
3291 &lt;span class=&quot;go&quot;&gt;2,18-2,19:          NEWLINE        &amp;#39;\n&amp;#39;           &lt;/span&gt;
3292 &lt;span class=&quot;go&quot;&gt;3,0-3,3:            INDENT         &amp;#39;   &amp;#39;          &lt;/span&gt;
3293 &lt;span class=&quot;go&quot;&gt;3,3-3,7:            NAME           &amp;#39;proceed&amp;#39;         &lt;/span&gt;
3294 &lt;span class=&quot;go&quot;&gt;3,7-3,8:            NEWLINE        &amp;#39;\n&amp;#39;           &lt;/span&gt;
3295 &lt;span class=&quot;go&quot;&gt;4,0-4,0:            DEDENT         &amp;#39;&amp;#39;             &lt;/span&gt;
3296 &lt;span class=&quot;go&quot;&gt;4,0-4,0:            ENDMARKER      &amp;#39;&amp;#39;              &lt;/span&gt;
3297 &lt;/pre&gt;&lt;/div&gt;
3298 
3299 &lt;p&gt;In the output, the first column is the range of the line/column coordinates, the second column is the name of the token, and the final column is the value of the token.&lt;/p&gt;
3300 &lt;p&gt;In the output, the &lt;code&gt;tokenize&lt;/code&gt; module has implied some tokens that were not in the file. The &lt;code&gt;ENCODING&lt;/code&gt; token for &lt;code&gt;utf-8&lt;/code&gt;, and a blank line at the end, giving &lt;code&gt;DEDENT&lt;/code&gt; to close the function declaration and an &lt;code&gt;ENDMARKER&lt;/code&gt; to end the file.&lt;/p&gt;
3301 &lt;p&gt;It is best practice to have a blank line at the end of your Python source files. If you omit it, CPython adds it for you, with a tiny performance penalty.&lt;/p&gt;
3302 &lt;p&gt;The &lt;code&gt;tokenize&lt;/code&gt; module is written in pure Python and is located in &lt;a href=&quot;https://github.com/python/cpython/blob/master/Lib/tokenize.py&quot;&gt;&lt;code&gt;Lib/tokenize.py&lt;/code&gt;&lt;/a&gt; within the CPython source code.&lt;/p&gt;
3303 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
3304 &lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; There are two tokenizers in the CPython source code: one written in Python, demonstrated here, and another written in C.
3305 The tokenizer written in Python is meant as a utility, and the one written in C is used by the Python compiler. They have identical output and behavior. The version written in C is designed for performance and the module in Python is designed for debugging.&lt;/p&gt;
3306 &lt;/div&gt;
3307 &lt;p&gt;To see a verbose readout of the C tokenizer, you can run Python with the &lt;code&gt;-d&lt;/code&gt; flag. Using the &lt;code&gt;test_tokens.py&lt;/code&gt; script you created earlier, run it with the following:&lt;/p&gt;
3308 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ./python.exe -d test_tokens.py
3309 
3310 &lt;span class=&quot;go&quot;&gt;Token NAME/&amp;#39;def&amp;#39; ... It&amp;#39;s a keyword&lt;/span&gt;
3311 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;file_input&amp;#39;, state 0: Push &amp;#39;stmt&amp;#39;&lt;/span&gt;
3312 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;stmt&amp;#39;, state 0: Push &amp;#39;compound_stmt&amp;#39;&lt;/span&gt;
3313 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;compound_stmt&amp;#39;, state 0: Push &amp;#39;funcdef&amp;#39;&lt;/span&gt;
3314 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;funcdef&amp;#39;, state 0: Shift.&lt;/span&gt;
3315 &lt;span class=&quot;go&quot;&gt;Token NAME/&amp;#39;my_function&amp;#39; ... It&amp;#39;s a token we know&lt;/span&gt;
3316 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;funcdef&amp;#39;, state 1: Shift.&lt;/span&gt;
3317 &lt;span class=&quot;go&quot;&gt;Token LPAR/&amp;#39;(&amp;#39; ... It&amp;#39;s a token we know&lt;/span&gt;
3318 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;funcdef&amp;#39;, state 2: Push &amp;#39;parameters&amp;#39;&lt;/span&gt;
3319 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;parameters&amp;#39;, state 0: Shift.&lt;/span&gt;
3320 &lt;span class=&quot;go&quot;&gt;Token RPAR/&amp;#39;)&amp;#39; ... It&amp;#39;s a token we know&lt;/span&gt;
3321 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;parameters&amp;#39;, state 1: Shift.&lt;/span&gt;
3322 &lt;span class=&quot;go&quot;&gt;  DFA &amp;#39;parameters&amp;#39;, state 2: Direct pop.&lt;/span&gt;
3323 &lt;span class=&quot;go&quot;&gt;Token COLON/&amp;#39;:&amp;#39; ... It&amp;#39;s a token we know&lt;/span&gt;
3324 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;funcdef&amp;#39;, state 3: Shift.&lt;/span&gt;
3325 &lt;span class=&quot;go&quot;&gt;Token NEWLINE/&amp;#39;&amp;#39; ... It&amp;#39;s a token we know&lt;/span&gt;
3326 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;funcdef&amp;#39;, state 5: [switch func_body_suite to suite] Push &amp;#39;suite&amp;#39;&lt;/span&gt;
3327 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;suite&amp;#39;, state 0: Shift.&lt;/span&gt;
3328 &lt;span class=&quot;go&quot;&gt;Token INDENT/&amp;#39;&amp;#39; ... It&amp;#39;s a token we know&lt;/span&gt;
3329 &lt;span class=&quot;go&quot;&gt; DFA &amp;#39;suite&amp;#39;, state 1: Shift.&lt;/span&gt;
3330 &lt;span class=&quot;hll&quot;&gt;&lt;span class=&quot;go&quot;&gt;Token NAME/&amp;#39;proceed&amp;#39; ... It&amp;#39;s a keyword&lt;/span&gt;
3331 &lt;/span&gt;&lt;span class=&quot;go&quot;&gt; DFA &amp;#39;suite&amp;#39;, state 3: Push &amp;#39;stmt&amp;#39;&lt;/span&gt;
3332 &lt;span class=&quot;go&quot;&gt;...&lt;/span&gt;
3333 &lt;span class=&quot;go&quot;&gt;  ACCEPT.&lt;/span&gt;
3334 &lt;/pre&gt;&lt;/div&gt;
3335 
3336 &lt;p&gt;In the output, you can see that it highlighted &lt;code&gt;proceed&lt;/code&gt; as a keyword. In the next chapter, we&amp;rsquo;ll see how executing the Python binary gets to the tokenizer and what happens from there to execute your code.&lt;/p&gt;
3337 &lt;p&gt;Now that you have an overview of the Python grammar and the relationship between tokens and statements, there is a way to convert the &lt;code&gt;pgen&lt;/code&gt; output into an interactive graph.&lt;/p&gt;
3338 &lt;p&gt;Here is a screenshot of the Python 3.8a2 grammar:&lt;/p&gt;
3339 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/Screen_Shot_2019-03-12_at_2.31.16_pm.f36c3e99b8b4.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/Screen_Shot_2019-03-12_at_2.31.16_pm.f36c3e99b8b4.png&quot; width=&quot;3258&quot; height=&quot;2248&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screen_Shot_2019-03-12_at_2.31.16_pm.f36c3e99b8b4.png&amp;amp;w=814&amp;amp;sig=21666b4228a46a6bcc7aeca6d5263e62a3aeb6d5 814w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/Screen_Shot_2019-03-12_at_2.31.16_pm.f36c3e99b8b4.png&amp;amp;w=1629&amp;amp;sig=01404157eddc09548f8cf7d4e995da9806c36fac 1629w, https://files.realpython.com/media/Screen_Shot_2019-03-12_at_2.31.16_pm.f36c3e99b8b4.png 3258w&quot; sizes=&quot;75vw&quot; alt=&quot;Python 3.8 DFA node graph&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3340 &lt;p&gt;The Python package used to generate this graph, &lt;code&gt;instaviz&lt;/code&gt;, will be covered in a later chapter.&lt;/p&gt;
3341 &lt;h3 id=&quot;memory-management-in-cpython&quot;&gt;Memory Management in CPython&lt;/h3&gt;
3342 &lt;p&gt;Throughout this article, you will see references to a &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Python/pyarena.c#L128&quot;&gt;&lt;code&gt;PyArena&lt;/code&gt;&lt;/a&gt; object. The arena is one of CPython&amp;rsquo;s memory management structures. The code is within &lt;code&gt;Python/pyarena.c&lt;/code&gt; and contains a wrapper around C&amp;rsquo;s memory allocation and deallocation functions.&lt;/p&gt;
3343 &lt;p&gt;In a traditionally written C program, the developer &lt;em&gt;should&lt;/em&gt; allocate memory for data structures before writing into that data. This allocation marks the memory as belonging to the process with the operating system.&lt;/p&gt;
3344 &lt;p&gt;It is also up to the developer to deallocate, or &amp;ldquo;free,&amp;rdquo; the allocated memory when its no longer being used and return it to the operating system&amp;rsquo;s block table of free memory. 
3345 If a process allocates memory for a variable, say within a function or loop, when that function has completed, the memory is not automatically given back to the operating system in C. So if it hasn&amp;rsquo;t been explicitly deallocated in the C code, it causes a memory leak. The process will continue to take more memory each time that function runs until eventually, the system runs out of memory, and crashes!&lt;/p&gt;
3346 &lt;p&gt;Python takes that responsibility away from the programmer and uses two algorithms: &lt;a href=&quot;https://realpython.com/python-memory-management/&quot;&gt;a reference counter and a garbage collector&lt;/a&gt;.&lt;/p&gt;
3347 &lt;p&gt;Whenever an interpreter is instantiated, a &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Python/pyarena.c#L128&quot;&gt;&lt;code&gt;PyArena&lt;/code&gt;&lt;/a&gt; is created and attached one of the fields in the interpreter. During the lifecycle of a CPython interpreter, many arenas could be allocated. They are connected with a linked list. The arena stores a list of pointers to Python Objects as a &lt;code&gt;PyListObject&lt;/code&gt;. Whenever a new Python object is created, a pointer to it is added using &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Python/pyarena.c#L203&quot;&gt;&lt;code&gt;PyArena_AddPyObject()&lt;/code&gt;&lt;/a&gt;. This function call stores a pointer in the arena&amp;rsquo;s list, &lt;code&gt;a_objects&lt;/code&gt;.&lt;/p&gt;
3348 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
3349 &lt;p&gt;Even though Python doesn&amp;rsquo;t have pointers, there are some &lt;a href=&quot;https://realpython.com/pointers-in-python/&quot;&gt;interesting techniques&lt;/a&gt; to simulate the behavior of pointers.&lt;/p&gt;
3350 &lt;/div&gt;
3351 &lt;p&gt;The &lt;code&gt;PyArena&lt;/code&gt; serves a second function, which is to allocate and reference a list of raw memory blocks. For example, a &lt;code&gt;PyList&lt;/code&gt; would need extra memory if you added thousands of additional values. The &lt;code&gt;PyList&lt;/code&gt; object&amp;rsquo;s C code does not allocate memory directly. The object gets raw blocks of memory from the &lt;code&gt;PyArena&lt;/code&gt; by calling &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Python/pyarena.c#L180&quot;&gt;&lt;code&gt;PyArena_Malloc()&lt;/code&gt;&lt;/a&gt; from the &lt;code&gt;PyObject&lt;/code&gt; with the required memory size. This task is completed by another abstraction in &lt;code&gt;Objects/obmalloc.c&lt;/code&gt;. In the object allocation module, memory can be allocated, freed, and reallocated for a Python Object.&lt;/p&gt;
3352 &lt;p&gt;A linked list of allocated blocks is stored inside the arena, so that when an interpreter is stopped, all managed memory blocks can be deallocated in one go using &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Python/pyarena.c#L157&quot;&gt;&lt;code&gt;PyArena_Free()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
3353 &lt;p&gt;Take the &lt;code&gt;PyListObject&lt;/code&gt; example. If you were to &lt;code&gt;.append()&lt;/code&gt; an object to the end of a Python list, you don&amp;rsquo;t need to reallocate the memory used in the existing list beforehand. The &lt;code&gt;.append()&lt;/code&gt; method calls &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Objects/listobject.c#L36&quot;&gt;&lt;code&gt;list_resize()&lt;/code&gt;&lt;/a&gt; which handles memory allocation for lists. Each list object keeps a list of the amount of memory allocated. If the item you&amp;rsquo;re appending will fit inside the existing free memory, it is simply added. If the list needs more memory space, it is expanded. Lists are expanded in length as 0, 4, 8, 16, 25, 35, 46, 58, 72, 88.&lt;/p&gt;
3354 &lt;p&gt;&lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Objects/obmalloc.c#L618&quot;&gt;&lt;code&gt;PyMem_Realloc()&lt;/code&gt;&lt;/a&gt; is called to expand the memory allocated in a list. &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Objects/obmalloc.c#L618&quot;&gt;&lt;code&gt;PyMem_Realloc()&lt;/code&gt;&lt;/a&gt; is an API wrapper for &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Objects/obmalloc.c#L1913&quot;&gt;&lt;code&gt;pymalloc_realloc()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
3355 &lt;p&gt;Python also has a special wrapper for the C call &lt;code&gt;malloc()&lt;/code&gt;, which sets the max size of the memory allocation to help prevent buffer overflow errors (See &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Modules/overlapped.c#L28&quot;&gt;&lt;code&gt;PyMem_RawMalloc()&lt;/code&gt;&lt;/a&gt;).&lt;/p&gt;
3356 &lt;p&gt;In summary: &lt;/p&gt;
3357 &lt;ul&gt;
3358 &lt;li&gt;Allocation of raw memory blocks is done via &lt;code&gt;PyMem_RawAlloc()&lt;/code&gt;.&lt;/li&gt;
3359 &lt;li&gt;The pointers to Python objects are stored within the &lt;code&gt;PyArena&lt;/code&gt;.&lt;/li&gt;
3360 &lt;li&gt;&lt;code&gt;PyArena&lt;/code&gt; also stores a linked-list of allocated memory blocks.&lt;/li&gt;
3361 &lt;/ul&gt;
3362 &lt;p&gt;More information on the API is detailed on the &lt;a href=&quot;https://docs.python.org/3/c-api/memory.html&quot;&gt;CPython documentation&lt;/a&gt;.&lt;/p&gt;
3363 &lt;h4 id=&quot;reference-counting&quot;&gt;Reference Counting&lt;/h4&gt;
3364 &lt;p&gt;To create a variable in Python, you have to assign a value to a &lt;em&gt;uniquely&lt;/em&gt; named variable:&lt;/p&gt;
3365 &lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_variable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;180392&lt;/span&gt;
3366 &lt;/pre&gt;&lt;/div&gt;
3367 
3368 &lt;p&gt;Whenever a value is assigned to a variable in Python, the name of the variable is checked within the locals and globals scope to see if it already exists.&lt;/p&gt;
3369 &lt;p&gt;Because &lt;code&gt;my_variable&lt;/code&gt; is not already within the &lt;code&gt;locals()&lt;/code&gt; or &lt;code&gt;globals()&lt;/code&gt; dictionary, this new object is created, and the value is assigned as being the numeric constant &lt;code&gt;180392&lt;/code&gt;.&lt;/p&gt;
3370 &lt;p&gt;There is now one reference to &lt;code&gt;my_variable&lt;/code&gt;, so the reference counter for &lt;code&gt;my_variable&lt;/code&gt; is incremented by 1. &lt;/p&gt;
3371 &lt;p&gt;You will see function calls &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Objects/object.c#L239&quot;&gt;&lt;code&gt;Py_INCREF()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Objects/object.c#L245&quot;&gt;&lt;code&gt;Py_DECREF()&lt;/code&gt;&lt;/a&gt; throughout the C source code for CPython. These functions increment and decrement the count of references to that object.&lt;/p&gt;
3372 &lt;p&gt;References to an object are decremented when a variable falls outside of the scope in which it was declared. Scope in Python can refer to a function or method, a comprehension, or a lambda function. These are some of the more literal scopes, but there are many other implicit scopes, like passing variables to a function call.&lt;/p&gt;
3373 &lt;p&gt;The handling of incrementing and decrementing references based on the language is built into the CPython compiler and the core execution loop, &lt;code&gt;ceval.c&lt;/code&gt;, which we will cover in detail later in this article.&lt;/p&gt;
3374 &lt;p&gt;Whenever &lt;code&gt;Py_DECREF()&lt;/code&gt; is called, and the counter becomes 0, the &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Objects/obmalloc.c#L707&quot;&gt;&lt;code&gt;PyObject_Free()&lt;/code&gt;&lt;/a&gt; function is called. For that object &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Python/pyarena.c#L157&quot;&gt;&lt;code&gt;PyArena_Free()&lt;/code&gt;&lt;/a&gt; is called for all of the memory that was allocated. &lt;/p&gt;
3375 &lt;h4 id=&quot;garbage-collection&quot;&gt;Garbage Collection&lt;/h4&gt;
3376 &lt;p&gt;How often does your garbage get collected? Weekly, or fortnightly? &lt;/p&gt;
3377 &lt;p&gt;When you&amp;rsquo;re finished with something, you discard it and throw it in the trash. But that trash won&amp;rsquo;t get collected straight away. You need to wait for the garbage trucks to come and pick it up.&lt;/p&gt;
3378 &lt;p&gt;CPython has the same principle, using a garbage collection algorithm. CPython&amp;rsquo;s garbage collector is enabled by default, happens in the background and works to deallocate memory that&amp;rsquo;s been used for objects which are no longer in use.&lt;/p&gt;
3379 &lt;p&gt;Because the garbage collection algorithm is a lot more complex than the reference counter, it doesn&amp;rsquo;t happen all the time, otherwise, it would consume a huge amount of CPU resources. It happens periodically, after a set number of operations.&lt;/p&gt;
3380 &lt;p&gt;CPython&amp;rsquo;s standard library comes with a Python module to interface with the arena and the garbage collector, the &lt;code&gt;gc&lt;/code&gt; module. Here&amp;rsquo;s how to use the &lt;code&gt;gc&lt;/code&gt; module in debug mode:&lt;/p&gt;
3381 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;gc&lt;/span&gt;
3382 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_debug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DEBUG_STATS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
3383 &lt;/pre&gt;&lt;/div&gt;
3384 
3385 &lt;p&gt;This will print the statistics whenever the garbage collector is run.&lt;/p&gt;
3386 &lt;p&gt;You can get the threshold after which the garbage collector is run by calling &lt;code&gt;get_threshold()&lt;/code&gt;:&lt;/p&gt;
3387 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_threshold&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
3388 &lt;span class=&quot;go&quot;&gt;(700, 10, 10)&lt;/span&gt;
3389 &lt;/pre&gt;&lt;/div&gt;
3390 
3391 &lt;p&gt;You can also get the current threshold counts:&lt;/p&gt;
3392 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
3393 &lt;span class=&quot;go&quot;&gt;(688, 1, 1)&lt;/span&gt;
3394 &lt;/pre&gt;&lt;/div&gt;
3395 
3396 &lt;p&gt;Lastly, you can run the collection algorithm manually:&lt;/p&gt;
3397 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
3398 &lt;span class=&quot;go&quot;&gt;24&lt;/span&gt;
3399 &lt;/pre&gt;&lt;/div&gt;
3400 
3401 &lt;p&gt;This will call &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Modules/gcmodule.c#L987&quot;&gt;&lt;code&gt;collect()&lt;/code&gt;&lt;/a&gt; inside the &lt;code&gt;Modules/gcmodule.c&lt;/code&gt; file which contains the implementation of the garbage collector algorithm.&lt;/p&gt;
3402 &lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
3403 &lt;p&gt;In Part 1, you covered the structure of the source code repository, how to compile from source, and the Python language specification. These core concepts will be critical in Part 2 as you dive deeper into the Python interpreter process.&lt;/p&gt;
3404 &lt;h2 h1=&quot;h1&quot; id=&quot;part-2-the-python-interpreter-process&quot;&gt;Part 2: The Python Interpreter Process&lt;/h2&gt;
3405 &lt;p&gt;Now that you&amp;rsquo;ve seen the Python grammar and memory management, you can follow the process from typing &lt;code&gt;python&lt;/code&gt; to the part where your code is executed.&lt;/p&gt;
3406 &lt;p&gt;There are five ways the &lt;code&gt;python&lt;/code&gt; binary can be called:&lt;/p&gt;
3407 &lt;ol&gt;
3408 &lt;li&gt;To run a single command with &lt;code&gt;-c&lt;/code&gt; and a Python command&lt;/li&gt;
3409 &lt;li&gt;To start a module with &lt;code&gt;-m&lt;/code&gt; and the name of a module&lt;/li&gt;
3410 &lt;li&gt;To run a file with the filename&lt;/li&gt;
3411 &lt;li&gt;To run the &lt;code&gt;stdin&lt;/code&gt; input using a shell pipe&lt;/li&gt;
3412 &lt;li&gt;To start the REPL and execute commands one at a time&lt;/li&gt;
3413 &lt;/ol&gt;
3414 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
3415 &lt;p&gt;Python has so many ways to execute scripts, it can be a little overwhelming. Darren Jones has put together a &lt;a href=&quot;https://realpython.com/courses/running-python-scripts/&quot;&gt;great course on running Python scripts&lt;/a&gt; if you want to learn more.&lt;/p&gt;
3416 &lt;/div&gt;
3417 &lt;p&gt;The three source files you need to inspect to see this process are:&lt;/p&gt;
3418 &lt;ol&gt;
3419 &lt;li&gt;&lt;strong&gt;&lt;code&gt;Programs/python.c&lt;/code&gt;&lt;/strong&gt; is a simple entry point.&lt;/li&gt;
3420 &lt;li&gt;&lt;strong&gt;&lt;code&gt;Modules/main.c&lt;/code&gt;&lt;/strong&gt; contains the code to bring together the whole process, loading configuration, executing code and clearing up memory.&lt;/li&gt;
3421 &lt;li&gt;&lt;strong&gt;&lt;code&gt;Python/initconfig.c&lt;/code&gt;&lt;/strong&gt; loads the configuration from the system environment and merges it with any command-line flags.&lt;/li&gt;
3422 &lt;/ol&gt;
3423 &lt;p&gt;This diagram shows how each of those functions is called:&lt;/p&gt;
3424 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/swim-lanes-chart-1.9fb3000aad85.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/swim-lanes-chart-1.9fb3000aad85.png&quot; width=&quot;1046&quot; height=&quot;851&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/swim-lanes-chart-1.9fb3000aad85.png&amp;amp;w=261&amp;amp;sig=8aa36cedaf32be0236896cce2c32b6c4c4ec7e05 261w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/swim-lanes-chart-1.9fb3000aad85.png&amp;amp;w=523&amp;amp;sig=a447b53d2afa96dfd204b9265c8b439bd71272d7 523w, https://files.realpython.com/media/swim-lanes-chart-1.9fb3000aad85.png 1046w&quot; sizes=&quot;75vw&quot; alt=&quot;Python run swim lane diagram&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3425 &lt;p&gt;The execution mode is determined from the configuration.&lt;/p&gt;
3426 &lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
3427 &lt;p&gt;&lt;strong&gt;The CPython source code style:&lt;/strong&gt;&lt;/p&gt;
3428 &lt;p&gt;Similar to the &lt;a href=&quot;https://realpython.com/courses/writing-beautiful-python-code-pep-8/&quot;&gt;PEP8 style guide for Python code&lt;/a&gt;, there is an &lt;a href=&quot;https://www.python.org/dev/peps/pep-0007/&quot;&gt;official style guide&lt;/a&gt; for the CPython C code, designed originally in 2001 and updated for modern versions. &lt;/p&gt;
3429 &lt;p&gt;There are some naming standards which help when navigating the source code:&lt;/p&gt;
3430 &lt;ul&gt;
3431 &lt;li&gt;
3432 &lt;p&gt;Use a &lt;code&gt;Py&lt;/code&gt; prefix for public functions, never for static functions. The &lt;code&gt;Py_&lt;/code&gt; prefix is reserved for global service routines like &lt;code&gt;Py_FatalError&lt;/code&gt;. Specific groups of routines (like specific object type APIs) use a longer prefix, such as &lt;code&gt;PyString_&lt;/code&gt; for string functions.&lt;/p&gt;
3433 &lt;/li&gt;
3434 &lt;li&gt;
3435 &lt;p&gt;Public functions and variables use MixedCase with underscores, like this: &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Objects/object.c#L924&quot;&gt;&lt;code&gt;PyObject_GetAttr&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Include/modsupport.h#L20&quot;&gt;&lt;code&gt;Py_BuildValue&lt;/code&gt;&lt;/a&gt;, &lt;code&gt;PyExc_TypeError&lt;/code&gt;.&lt;/p&gt;
3436 &lt;/li&gt;
3437 &lt;li&gt;
3438 &lt;p&gt;Occasionally an &amp;ldquo;internal&amp;rdquo; function has to be visible to the loader. We use the &lt;code&gt;_Py&lt;/code&gt; prefix for this, for example, &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Objects/object.c#L464&quot;&gt;&lt;code&gt;_PyObject_Dump&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
3439 &lt;/li&gt;
3440 &lt;li&gt;
3441 &lt;p&gt;Macros should have a MixedCase prefix and then use upper case, for example &lt;code&gt;PyString_AS_STRING&lt;/code&gt;, &lt;code&gt;Py_PRINT_RAW&lt;/code&gt;.&lt;/p&gt;
3442 &lt;/li&gt;
3443 &lt;/ul&gt;
3444 &lt;/div&gt;
3445 &lt;h3 id=&quot;establishing-runtime-configuration&quot;&gt;Establishing Runtime Configuration&lt;/h3&gt;
3446 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/swim-lanes-chart-1.9fb3000aad85.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/swim-lanes-chart-1.9fb3000aad85.png&quot; width=&quot;1046&quot; height=&quot;851&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/swim-lanes-chart-1.9fb3000aad85.png&amp;amp;w=261&amp;amp;sig=8aa36cedaf32be0236896cce2c32b6c4c4ec7e05 261w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/swim-lanes-chart-1.9fb3000aad85.png&amp;amp;w=523&amp;amp;sig=a447b53d2afa96dfd204b9265c8b439bd71272d7 523w, https://files.realpython.com/media/swim-lanes-chart-1.9fb3000aad85.png 1046w&quot; sizes=&quot;75vw&quot; alt=&quot;Python run swim lane diagram&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3447 &lt;p&gt;In the swimlanes, you can see that before any Python code is executed, the runtime first establishes the configuration.
3448 The configuration of the runtime is a data structure defined in &lt;code&gt;Include/cpython/initconfig.h&lt;/code&gt; named &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Include/cpython/initconfig.h#L407&quot;&gt;&lt;code&gt;PyConfig&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
3449 &lt;p&gt;The configuration data structure includes things like:&lt;/p&gt;
3450 &lt;ul&gt;
3451 &lt;li&gt;Runtime flags for various modes like debug and optimized mode&lt;/li&gt;
3452 &lt;li&gt;The execution mode, such as whether a filename was passed, &lt;code&gt;stdin&lt;/code&gt; was provided or a module name&lt;/li&gt;
3453 &lt;li&gt;Extended option, specified by &lt;code&gt;-X &amp;lt;option&amp;gt;&lt;/code&gt;&lt;/li&gt;
3454 &lt;li&gt;Environment variables for runtime settings&lt;/li&gt;
3455 &lt;/ul&gt;
3456 &lt;p&gt;The configuration data is primarily used by the CPython runtime to enable and disable various features.&lt;/p&gt;
3457 &lt;p&gt;Python also comes with several &lt;a href=&quot;https://docs.python.org/3/using/cmdline.html&quot;&gt;Command Line Interface Options&lt;/a&gt;. In Python you can enable verbose mode with the &lt;code&gt;-v&lt;/code&gt; flag. In verbose mode, Python will print messages to the screen when modules are loaded:&lt;/p&gt;
3458 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ./python.exe -v -c &lt;span class=&quot;s2&quot;&gt;&amp;quot;print(&amp;#39;hello world&amp;#39;)&amp;quot;&lt;/span&gt;
3459 
3460 
3461 &lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; installing zipimport hook
3462 &lt;span class=&quot;go&quot;&gt;import zipimport # builtin&lt;/span&gt;
3463 &lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; installed zipimport hook
3464 &lt;span class=&quot;go&quot;&gt;...&lt;/span&gt;
3465 &lt;/pre&gt;&lt;/div&gt;
3466 
3467 &lt;p&gt;You will see a hundred lines or more with all the imports of your user site-packages and anything else in the system environment.&lt;/p&gt;
3468 &lt;p&gt;You can see the definition of this flag within &lt;code&gt;Include/cpython/initconfig.h&lt;/code&gt; inside the &lt;code&gt;struct&lt;/code&gt; for &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Include/cpython/initconfig.h#L407&quot;&gt;&lt;code&gt;PyConfig&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
3469 &lt;div class=&quot;highlight c&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/* --- PyConfig ---------------------------------------------- */&lt;/span&gt;
3470 
3471 &lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
3472     &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_config_version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;cm&quot;&gt;/* Internal configuration version,&lt;/span&gt;
3473 &lt;span class=&quot;cm&quot;&gt;                             used for ABI compatibility */&lt;/span&gt;
3474     &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_config_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;cm&quot;&gt;/* _PyConfigInitEnum value */&lt;/span&gt;
3475 
3476     &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
3477 
3478     &lt;span class=&quot;cm&quot;&gt;/* If greater than 0, enable the verbose mode: print a message each time a&lt;/span&gt;
3479 &lt;span class=&quot;cm&quot;&gt;       module is initialized, showing the place (filename or built-in module)&lt;/span&gt;
3480 &lt;span class=&quot;cm&quot;&gt;       from which it is loaded.&lt;/span&gt;
3481 
3482 &lt;span class=&quot;cm&quot;&gt;       If greater or equal to 2, print a message for each file that is checked&lt;/span&gt;
3483 &lt;span class=&quot;cm&quot;&gt;       for when searching for a module. Also provides information on module&lt;/span&gt;
3484 &lt;span class=&quot;cm&quot;&gt;       cleanup at exit.&lt;/span&gt;
3485 
3486 &lt;span class=&quot;cm&quot;&gt;       Incremented by the -v option. Set by the PYTHONVERBOSE environment&lt;/span&gt;
3487 &lt;span class=&quot;cm&quot;&gt;       variable. If set to -1 (default), inherit Py_VerboseFlag value. */&lt;/span&gt;
3488     &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;verbose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
3489 &lt;/pre&gt;&lt;/div&gt;
3490 
3491 &lt;p&gt;In &lt;code&gt;Python/initconfig.c&lt;/code&gt;, the logic for reading settings from environment variables and runtime command-line flags is established.&lt;/p&gt;
3492 &lt;p&gt;In the &lt;code&gt;config_read_env_vars&lt;/code&gt; function, the environment variables are read and used to assign the values for the configuration settings:&lt;/p&gt;
3493 &lt;div class=&quot;highlight c&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyStatus&lt;/span&gt;
3494 &lt;span class=&quot;nf&quot;&gt;config_read_env_vars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
3495 &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
3496     &lt;span class=&quot;n&quot;&gt;PyStatus&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
3497     &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;use_env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;use_environment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
3498 
3499     &lt;span class=&quot;cm&quot;&gt;/* Get environment variables */&lt;/span&gt;
3500 &lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;_Py_get_env_flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;use_env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parser_debug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;PYTHONDEBUG&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
3501 &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;_Py_get_env_flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;use_env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;verbose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;PYTHONVERBOSE&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
3502     &lt;span class=&quot;n&quot;&gt;_Py_get_env_flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;use_env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optimization_level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;PYTHONOPTIMIZE&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
3503     &lt;span class=&quot;n&quot;&gt;_Py_get_env_flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;use_env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;PYTHONINSPECT&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
3504 &lt;/pre&gt;&lt;/div&gt;
3505 
3506 &lt;p&gt;For the verbose setting, you can see that the value of &lt;code&gt;PYTHONVERBOSE&lt;/code&gt; is used to set the value of &lt;code&gt;&amp;amp;config-&amp;gt;verbose&lt;/code&gt;, if &lt;code&gt;PYTHONVERBOSE&lt;/code&gt; is found. If the environment variable does not exist, then the default value of &lt;code&gt;-1&lt;/code&gt; will remain.&lt;/p&gt;
3507 &lt;p&gt;Then in &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Python/initconfig.c#L1828&quot;&gt;&lt;code&gt;config_parse_cmdline&lt;/code&gt;&lt;/a&gt; within &lt;code&gt;initconfig.c&lt;/code&gt; again, the command-line flag is used to set the value, if provided:&lt;/p&gt;
3508 &lt;div class=&quot;highlight c&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyStatus&lt;/span&gt;
3509 &lt;span class=&quot;nf&quot;&gt;config_parse_cmdline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyWideStringList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warnoptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
3510                      &lt;span class=&quot;n&quot;&gt;Py_ssize_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opt_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
3511 &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
3512 &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
3513 
3514         &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
3515 &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
3516 
3517         &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&amp;#39;v&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
3518 &lt;span class=&quot;hll&quot;&gt;            &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;verbose&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
3519 &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
3520 &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
3521         &lt;span class=&quot;cm&quot;&gt;/* This space reserved for other options */&lt;/span&gt;
3522 
3523         &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
3524             &lt;span class=&quot;cm&quot;&gt;/* unknown argument: parsing failed */&lt;/span&gt;
3525             &lt;span class=&quot;n&quot;&gt;config_usage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;program&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
3526             &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_PyStatus_EXIT&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;
3527         &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
3528     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
3529 &lt;/pre&gt;&lt;/div&gt;
3530 
3531 &lt;p&gt;This value is later copied to a global variable &lt;code&gt;Py_VerboseFlag&lt;/code&gt; by the &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Python/initconfig.c#L134&quot;&gt;&lt;code&gt;_Py_GetGlobalVariablesAsDict&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;
3532 &lt;p&gt;Within a Python session, you can access the runtime flags, like verbose mode, quiet mode, using the &lt;code&gt;sys.flags&lt;/code&gt; named tuple.
3533 The &lt;code&gt;-X&lt;/code&gt; flags are all available inside the &lt;code&gt;sys._xoptions&lt;/code&gt; dictionary:&lt;/p&gt;
3534 &lt;div class=&quot;highlight python repl&quot;&gt;&lt;span class=&quot;repl-toggle&quot; title=&quot;Toggle REPL prompts and output&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;$ ./python.exe -X dev -q       &lt;/span&gt;
3535 
3536 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
3537 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;
3538 &lt;span class=&quot;go&quot;&gt;sys.flags(debug=0, inspect=0, interactive=0, optimize=0, dont_write_bytecode=0, &lt;/span&gt;
3539 &lt;span class=&quot;go&quot;&gt; no_user_site=0, no_site=0, ignore_environment=0, verbose=0, bytes_warning=0, &lt;/span&gt;
3540 &lt;span class=&quot;go&quot;&gt; quiet=1, hash_randomization=1, isolated=0, dev_mode=True, utf8_mode=0)&lt;/span&gt;
3541 
3542 &lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_xoptions&lt;/span&gt;
3543 &lt;span class=&quot;go&quot;&gt;{&amp;#39;dev&amp;#39;: True}&lt;/span&gt;
3544 &lt;/pre&gt;&lt;/div&gt;
3545 
3546 &lt;p&gt;As well as the runtime configuration in &lt;code&gt;initconfig.h&lt;/code&gt;, there is also the build configuration, which is located inside &lt;code&gt;pyconfig.h&lt;/code&gt; in the root folder. This file is created dynamically in the &lt;code&gt;configure&lt;/code&gt; step in the build process, or by Visual Studio for Windows systems.&lt;/p&gt;
3547 &lt;p&gt;You can see the build configuration by running:&lt;/p&gt;
3548 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ./python.exe -m sysconfig
3549 &lt;/pre&gt;&lt;/div&gt;
3550 
3551 &lt;h3 id=&quot;reading-filesinput&quot;&gt;Reading Files/Input&lt;/h3&gt;
3552 &lt;p&gt;Once CPython has the runtime configuration and the command-line arguments, it can establish what it needs to execute.&lt;/p&gt;
3553 &lt;p&gt;This task is handled by the &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Modules/main.c#L665&quot;&gt;&lt;code&gt;pymain_main&lt;/code&gt;&lt;/a&gt; function inside &lt;code&gt;Modules/main.c&lt;/code&gt;. Depending on the newly created &lt;code&gt;config&lt;/code&gt; instance, CPython will now execute code provided via several options.&lt;/p&gt;
3554 &lt;h4 id=&quot;input-via-c&quot;&gt;Input via &lt;code&gt;-c&lt;/code&gt;&lt;/h4&gt;
3555 &lt;p&gt;The simplest is providing CPython a command with the &lt;code&gt;-c&lt;/code&gt; option and a Python program inside quotes.&lt;/p&gt;
3556 &lt;p&gt;For example:&lt;/p&gt;
3557 &lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ./python.exe -c &lt;span class=&quot;s2&quot;&gt;&amp;quot;print(&amp;#39;hi&amp;#39;)&amp;quot;&lt;/span&gt;
3558 &lt;span class=&quot;go&quot;&gt;hi&lt;/span&gt;
3559 &lt;/pre&gt;&lt;/div&gt;
3560 
3561 &lt;p&gt;Here is the full flowchart of how this happens:&lt;/p&gt;
3562 &lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pymain_run_command.f5da561ba7d5.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/pymain_run_command.f5da561ba7d5.png&quot; width=&quot;1041&quot; height=&quot;751&quot; srcset=&quot;https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pymain_run_command.f5da561ba7d5.png&amp;amp;w=260&amp;amp;sig=f7f802b23e900bf42b29804ee80ed0dd0eaec6a4 260w, https://robocrop.realpython.net/?url=https%3A//files.realpython.com/media/pymain_run_command.f5da561ba7d5.png&amp;amp;w=520&amp;amp;sig=3079060f305945fd3556ce7cd453fac965a6ec27 520w, https://files.realpython.com/media/pymain_run_command.f5da561ba7d5.png 1041w&quot; sizes=&quot;75vw&quot; alt=&quot;Flow chart of pymain_run_command&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
3563 &lt;p&gt;First, the &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Modules/main.c#L240&quot;&gt;&lt;code&gt;pymain_run_command()&lt;/code&gt;&lt;/a&gt; function is executed inside &lt;code&gt;Modules/main.c&lt;/code&gt; taking the command passed in &lt;code&gt;-c&lt;/code&gt; as an argument in the C type &lt;code&gt;wchar_t*&lt;/code&gt;. The &lt;code&gt;wchar_t*&lt;/code&gt; type is often used as a low-level storage type for Unicode data across CPython as the size of the type can store UTF8 characters.&lt;/p&gt;
3564 &lt;p&gt;When converting the &lt;code&gt;wchar_t*&lt;/code&gt; to a Python string, the &lt;code&gt;Objects/unicodeobject.c&lt;/code&gt; file has a helper function &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Objects/unicodeobject.c#L2088&quot;&gt;&lt;code&gt;PyUnicode_FromWideChar()&lt;/code&gt;&lt;/a&gt; that returns a &lt;code&gt;PyObject&lt;/code&gt;, of type &lt;code&gt;str&lt;/code&gt;. The encoding to UTF8 is then done by &lt;code&gt;PyUnicode_AsUTF8String()&lt;/code&gt; on the Python &lt;code&gt;str&lt;/code&gt; object to convert it to a Python &lt;code&gt;bytes&lt;/code&gt; object. &lt;/p&gt;
3565 &lt;p&gt;Once this is complete, &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Modules/main.c#L240&quot;&gt;&lt;code&gt;pymain_run_command()&lt;/code&gt;&lt;/a&gt; will then pass the Python bytes object to &lt;a href=&quot;https://github.com/python/cpython/blob/d93605de7232da5e6a182fd1d5c220639e900159/Python/pythonrun.c#L453&quot;&gt;&lt;code&gt;PyRun_SimpleStringFlags()&lt;/code&gt;&lt;/a&gt; for execution, but first converting the &lt;code&gt;bytes&lt;/code&gt; to a &lt;code&gt;str&lt;/code&gt; type again:&lt;/p&gt;
3566 &lt;div class=&quot;highlight c&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;
3567 &lt;span class=&quot;nf&quot;&gt;pymain_run_command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;wchar_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyCompilerFlags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
3568 &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
3569     &lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unicode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
3570     &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
3571 
3572     &lt;span class=&quot;n&quot;&gt;unicode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyUnicode_FromWideChar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;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;
3573     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unicode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
3574         &lt;span class=&quot;k&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
3575     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
3576 
3577