{"id":"l-pda-1-2","courseId":"python-data-analysis","lang":"en","kind":"lesson","summary":"Store values in variables, tell integers, floats, strings, booleans and None apart, and convert text like &quot; $129.00&quot; into a number you can calculate with.","html":"<p>An order line arrives from a messy export: the unit price reads <code dir=\"ltr\">$129.00</code>, the quantity reads <code dir=\"ltr\">2</code>, and a 15% coupon was applied. A human reads that and calculates the line revenue in their head. Python cannot, yet: to Python, <code dir=\"ltr\">&quot;$129.00&quot;</code> is a piece of text, no more a number than the word <code dir=\"ltr\">&quot;skillet&quot;</code>. Knowing what kind of value you are holding is the first skill of data work.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Values and variables</h2>\n<p>A value is a piece of data: <code dir=\"ltr\">2</code>, <code dir=\"ltr\">129.0</code>, <code dir=\"ltr\">&quot;Cast Iron Skillet&quot;</code>, <code dir=\"ltr\">True</code>. A variable is a name you attach to a value with <code dir=\"ltr\">=</code> so you can use it later.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"0\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">product </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"Cast Iron Skillet 26cm\"</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">unit_price </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 39</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">quantity </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 2</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">line_total </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> unit_price </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> quantity</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(product, line_total)</span></span></code></pre><div class=\"run-output\" data-run-output=\"0\" hidden></div></div>\n<p>Read <code dir=\"ltr\">line_total = unit_price * quantity</code> from right to left: Python computes the right side first, then points the name on the left at the result. Variable names use lowercase words joined by underscores (<code dir=\"ltr\">unit_price</code>, not <code dir=\"ltr\">UnitPrice</code> or <code dir=\"ltr\">unitprice</code>); that convention is called snake_case and every Python codebase you will read follows it.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">Every value has a type</h2>\n<p>The type decides what you can do with a value. <code dir=\"ltr\">type()</code> reveals it:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"1\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">type</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))            </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># int: whole numbers</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">type</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">129.0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))        </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># float: numbers with a decimal point</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">type</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"129.00\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))     </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># str: text, in single or double quotes</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">type</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">True</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))         </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># bool: True or False</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">type</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">None</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))         </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># NoneType: \"no value here\"</span></span></code></pre><div class=\"run-output\" data-run-output=\"1\" hidden></div></div>\n<p>Notice that <code dir=\"ltr\">&quot;129.00&quot;</code> is a <code dir=\"ltr\">str</code>. Quotes make text, even when the characters inside look like digits. That single fact explains a whole family of data bugs: a column that looks numeric but was read as text sorts <code dir=\"ltr\">&quot;100&quot;</code> before <code dir=\"ltr\">&quot;20&quot;</code> and refuses to sum.</p>\n<h3 id=\"sec-3\" tabindex=\"-1\">Arithmetic</h3>\n<p>Numbers support the operators you expect, plus three that matter in analysis:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"2\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">10</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> /</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 4</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># 2.5  true division, always a float</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">10</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> //</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 4</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)   </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># 2    floor division: whole boxes of 4</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">10</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> %</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 4</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># 2    remainder: items left over</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> **</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># 8    power</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.1</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0.2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># 0.30000000000000004</span></span></code></pre><div class=\"run-output\" data-run-output=\"2\" hidden></div></div>\n<p>The last line is not a Python bug. Computers store decimals in binary, so most decimal fractions are stored as a tiny approximation. For money you round at the end with <code dir=\"ltr\">round(value, 2)</code>, and you never compare two floats with <code dir=\"ltr\">==</code> after a calculation unless you rounded both. Section 4 returns to this when totals do not quite match.</p>\n<p>One more surprise hides in <code dir=\"ltr\">round()</code> itself. Python rounds exact halves to the nearest even digit, so <code dir=\"ltr\">round(0.5)</code> is <code dir=\"ltr\">0</code> and <code dir=\"ltr\">round(2.5)</code> is <code dir=\"ltr\">2</code>, and a value like <code dir=\"ltr\">2.675</code> is stored as slightly less than it looks, so <code dir=\"ltr\">round(2.675, 2)</code> gives <code dir=\"ltr\">2.67</code>. For analysis and reporting that never matters. For invoices, where every cent must follow an accounting rule, Python’s <code dir=\"ltr\">decimal</code> module exists; you will not need it in this course, but now you know where to look when a finance colleague asks.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">Text is a sequence of characters</h2>\n<p>Strings come with methods: functions attached to the value, called with a dot. These are the ones you will use constantly:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"3\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">raw </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"  united KINGDOM \"</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(raw.strip())                 </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># remove spaces at both ends</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(raw.strip().title())         </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># \"United Kingdom\"</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(raw.upper())                 </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># all capitals</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"$129.00\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.replace(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"$\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))  </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># swap one substring for another</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">len</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Cartwheel\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))            </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># number of characters: 9</span></span></code></pre><div class=\"run-output\" data-run-output=\"3\" hidden></div></div>\n<p>Every one of these returns a <strong>new</strong> string. Strings are immutable: <code dir=\"ltr\">raw.strip()</code> does not change <code dir=\"ltr\">raw</code>. If you want to keep the cleaned version, assign it: <code dir=\"ltr\">country = raw.strip().title()</code>.</p>\n<h2 id=\"sec-5\" tabindex=\"-1\">Converting between types</h2>\n<p><code dir=\"ltr\">int()</code>, <code dir=\"ltr\">float()</code> and <code dir=\"ltr\">str()</code> convert values, but only when the conversion makes sense:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"4\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">quantity </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> int</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"2\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">price </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> float</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"129.00\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">label </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"Qty: \"</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> str</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(quantity)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(quantity </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> price, label)</span></span></code></pre><div class=\"run-output\" data-run-output=\"4\" hidden></div></div>\n<p><code dir=\"ltr\">float(&quot;$129.00&quot;)</code> fails with <code dir=\"ltr\">ValueError: could not convert string to float: '$129.00'</code>. The fix is to clean first, then convert. You chain methods left to right, each one working on the result of the previous one:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"5\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"5\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">price_text </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \" $129.00\"</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">price </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> float</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(price_text.strip().replace(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"$\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">discount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0.15</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">line_revenue </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> round</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> *</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> price </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> -</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> discount), </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(price, line_revenue)</span></span></code></pre><div class=\"run-output\" data-run-output=\"5\" hidden></div></div>\n<p>That is the revenue formula Cartwheel uses for every order line: quantity times unit price times one minus the discount. You will apply it to thousands of rows at once in Section 2; here you see it for one.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">Common mistake</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Adding text to a number</span></p>\n<p><code dir=\"ltr\">&quot;Qty: &quot; + 2</code> raises <code dir=\"ltr\">TypeError: can only concatenate str (not &quot;int&quot;) to str</code>. Python never guesses whether you meant text or maths. Convert explicitly, <code dir=\"ltr\">&quot;Qty: &quot; + str(2)</code>, or use an f-string, which Lesson 1.5 covers.</p>\n</aside>\n<h2 id=\"sec-6\" tabindex=\"-1\">Booleans and comparisons</h2>\n<p>Comparisons produce <code dir=\"ltr\">True</code> or <code dir=\"ltr\">False</code>, and these answer yes/no questions about your data:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"6\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"6\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">line_revenue </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 219.3</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(line_revenue </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">>=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 200</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)       </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># True</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(line_revenue </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">==</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 219.3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)     </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># True: equal values</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"web\"</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> !=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"mobile_app\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)     </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># True: not equal</span></span></code></pre><div class=\"run-output\" data-run-output=\"6\" hidden></div></div>\n<p>One <code dir=\"ltr\">=</code> assigns; two <code dir=\"ltr\">==</code> compares. Mixing them up is the most common typo for new programmers, and Python helps by rejecting <code dir=\"ltr\">if x = 3:</code> as a syntax error.</p>\n<p><code dir=\"ltr\">None</code> is a separate value that means “nothing here”. A missing coupon code or an unknown satisfaction score would be <code dir=\"ltr\">None</code> in plain Python. pandas uses its own markers for missing data, and Section 3 is about handling them carefully.</p>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">Tip</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Check types when results look odd</span></p>\n<p>When a number behaves strangely (it will not add, it sorts wrongly, it prints with quotes), print <code dir=\"ltr\">type(value)</code> before anything else. Nine times out of ten, a number is secretly text.</p>\n</aside>\n<p>The exercise below turns one messy export row into real numbers. Next, you store many values at once in lists and dictionaries.</p>\n","toc":[{"id":"sec-1","text":"Values and variables","level":2},{"id":"sec-2","text":"Every value has a type","level":2},{"id":"sec-3","text":"Arithmetic","level":3},{"id":"sec-4","text":"Text is a sequence of characters","level":2},{"id":"sec-5","text":"Converting between types","level":2},{"id":"sec-6","text":"Booleans and comparisons","level":2}],"takeaways":["A variable is a name pointing at a value; <code dir=\"ltr\">=</code> assigns, <code dir=\"ltr\">==</code> compares.","Every value has a type, and <code dir=\"ltr\">type()</code> tells you which one; most bugs in data work are a value having the type you did not expect.","<code dir=\"ltr\">/</code> always returns a float, <code dir=\"ltr\">//</code> drops the remainder, and <code dir=\"ltr\">%</code> gives the remainder.","String methods such as <code dir=\"ltr\">strip()</code> and <code dir=\"ltr\">replace()</code> return a new string; they never change the original.","Convert text to numbers with <code dir=\"ltr\">int()</code> and <code dir=\"ltr\">float()</code> only after removing symbols like <code dir=\"ltr\">$</code> and spaces."],"further":[{"title":"An Informal Introduction to Python (numbers and text)","url":"https://docs.python.org/3/tutorial/introduction.html"},{"title":"Built-in Types - String Methods","url":"https://docs.python.org/3/library/stdtypes.html#string-methods"},{"title":"Floating-Point Arithmetic: Issues and Limitations","url":"https://docs.python.org/3/tutorial/floatingpoint.html"}],"quiz":[{"q":"<p>What does this print?</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">price </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"39\"</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(price </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">78</code>","why":"That would need <code dir=\"ltr\">int(price) * 2</code>. As written, <code dir=\"ltr\">price</code> is text."},{"text":"<code dir=\"ltr\">3939</code>","why":"Correct. Multiplying a string by an integer repeats it. The value came in as text, so the maths never happened."},{"text":"A <code dir=\"ltr\">TypeError</code>","why":"<code dir=\"ltr\">str * int</code> is allowed in Python (it repeats the string). The error happens with <code dir=\"ltr\">str + int</code>."}],"answer":1},{"q":"<p>Which line turns <code dir=\"ltr\">&quot;$1,250.00&quot;</code> into the float <code dir=\"ltr\">1250.0</code>?</p>","options":[{"text":"<code dir=\"ltr\">float(&quot;$1,250.00&quot;)</code>","why":"<code dir=\"ltr\">float()</code> accepts digits, a decimal point, a sign, an exponent and surrounding spaces, but not <code dir=\"ltr\">$</code> or a thousands comma, so this raises <code dir=\"ltr\">ValueError</code>."},{"text":"<code dir=\"ltr\">int(&quot;$1,250.00&quot;.replace(&quot;$&quot;, &quot;&quot;))</code>","why":"The comma is still there, and <code dir=\"ltr\">int()</code> would reject the <code dir=\"ltr\">.00</code> anyway."},{"text":"<code dir=\"ltr\">float(&quot;$1,250.00&quot;.replace(&quot;$&quot;, &quot;&quot;).replace(&quot;,&quot;, &quot;&quot;))</code>","why":"Correct. Remove every symbol first, then convert the clean digits."},{"text":"<code dir=\"ltr\">str(&quot;$1,250.00&quot;).strip()</code>","why":"<code dir=\"ltr\">strip()</code> only removes whitespace at the ends, and the result is still a string."}],"answer":2},{"q":"<p>What is the value of <code dir=\"ltr\">10 / 4</code> and <code dir=\"ltr\">10 // 4</code>?</p>","options":[{"text":"<code dir=\"ltr\">2.5</code> and <code dir=\"ltr\">2</code>","why":"Correct. True division always returns a float; floor division drops the fractional part."},{"text":"<code dir=\"ltr\">2</code> and <code dir=\"ltr\">2.5</code>","why":"It is the other way round. <code dir=\"ltr\">//</code> is the operator that rounds down."},{"text":"<code dir=\"ltr\">2.5</code> and <code dir=\"ltr\">2.5</code>","why":"<code dir=\"ltr\">//</code> is floor division and never keeps the fractional part."}],"answer":0},{"q":"<p>A customer’s coupon code is unknown. Which value best represents that in Python?</p>","options":[{"text":"The empty string <code dir=\"ltr\">&quot;&quot;</code>","why":"An empty string is a real value (text with no characters). It can mean “no coupon” or “unknown”, which is exactly the ambiguity you want to avoid."},{"text":"The number <code dir=\"ltr\">0</code>","why":"Zero is a real number and would be counted in sums and averages as if it were data."},{"text":"<code dir=\"ltr\">None</code>","why":"Correct. <code dir=\"ltr\">None</code> is Python’s built-in marker for “no value here”. pandas has its own missing markers, which you meet in Section 3."}],"answer":2}],"exercise":{"kind":"python","files":[],"starter":"# One row from Cartwheel's messy export, exactly as it arrived\nprice_text = \" $129.00\"\nquantity_text = \"2\"\ndiscount = 0.15\n\n# 1. Turn price_text into a float\nprice = None\n\n# 2. Turn quantity_text into an int\nquantity = None\n\n# 3. Line revenue = quantity * price * (1 - discount), rounded to 2 decimals\nline_revenue = None\n\n# 4. True when line_revenue is 200 or more\nis_large = None\n","solution":"price_text = \" $129.00\"\nquantity_text = \"2\"\ndiscount = 0.15\n\nprice = float(price_text.strip().replace(\"$\", \"\"))\nquantity = int(quantity_text)\nline_revenue = round(quantity * price * (1 - discount), 2)\nis_large = line_revenue >= 200\n","checks":[{"id":"price-float","test":"type(price) is float and price == 129.0"},{"id":"quantity-int","test":"type(quantity) is int and quantity == 2"},{"id":"revenue","test":"isinstance(line_revenue, float) and line_revenue == 219.3"},{"id":"is-large","test":"is_large is True"}],"title":"Turn a messy row into numbers","prompt":"<p>A row from the messy export gives you <code dir=\"ltr\">price_text = &quot; $129.00&quot;</code>, <code dir=\"ltr\">quantity_text = &quot;2&quot;</code> and <code dir=\"ltr\">discount = 0.15</code>. Create <code dir=\"ltr\">price</code> (a float), <code dir=\"ltr\">quantity</code> (an int), <code dir=\"ltr\">line_revenue</code> (quantity × price × (1 − discount), rounded to 2 decimals) and <code dir=\"ltr\">is_large</code> (a boolean: <code dir=\"ltr\">True</code> when <code dir=\"ltr\">line_revenue</code> is 200 or more). Calculate from the variables; don’t type the answers in by hand.</p>\n","hints":["<code dir=\"ltr\">float()</code> and <code dir=\"ltr\">int()</code> convert text, but only clean text: digits and a decimal point.","Remove the space with <code dir=\"ltr\">.strip()</code> and the dollar sign with <code dir=\"ltr\">.replace(&quot;$&quot;, &quot;&quot;)</code> before calling <code dir=\"ltr\">float()</code>.","<code dir=\"ltr\">line_revenue = round(quantity * price * (1 - discount), 2)</code> and <code dir=\"ltr\">is_large = line_revenue &gt;= 200</code>."],"explanation":"<p><code dir=\"ltr\">price_text.strip().replace(&quot;$&quot;, &quot;&quot;)</code> produces <code dir=\"ltr\">&quot;129.00&quot;</code>, which <code dir=\"ltr\">float()</code> accepts. <code dir=\"ltr\">int(&quot;2&quot;)</code> gives the integer 2. The revenue formula multiplies three numbers; without <code dir=\"ltr\">round()</code> you would get <code dir=\"ltr\">219.29999999999998</code> because of how floats are stored. A comparison like <code dir=\"ltr\">line_revenue &gt;= 200</code> already evaluates to <code dir=\"ltr\">True</code> or <code dir=\"ltr\">False</code>, so you assign it directly; there is no need for an <code dir=\"ltr\">if</code>.</p>\n","checkLabels":{"price-float":"<code dir=\"ltr\">price</code> is the float 129.0","quantity-int":"<code dir=\"ltr\">quantity</code> is the integer 2","revenue":"<code dir=\"ltr\">line_revenue</code> is 219.3","is-large":"<code dir=\"ltr\">is_large</code> is <code dir=\"ltr\">True</code>"}},"words":720,"readMinutes":3}