From 02316ee7ed572ab456b331115c1287399ef0d6db Mon Sep 17 00:00:00 2001 From: Dave Whipp Date: Wed, 2 Oct 2024 11:36:22 +0300 Subject: [PATCH] Reorganize stuff about string concatenation --- .../nb/appendix-6-question-solutions.ipynb | 2 +- .../chapter-02/nb/00-python-basics.ipynb | 192 ++++++++---------- .../chapter-02/nb/02-text-and-numbers.ipynb | 161 ++++++++++++++- 3 files changed, 242 insertions(+), 113 deletions(-) diff --git a/source/back-matter/nb/appendix-6-question-solutions.ipynb b/source/back-matter/nb/appendix-6-question-solutions.ipynb index a2bae727..8503fce7 100644 --- a/source/back-matter/nb/appendix-6-question-solutions.ipynb +++ b/source/back-matter/nb/appendix-6-question-solutions.ipynb @@ -103,7 +103,7 @@ "### Question 2.5\n", "\n", "```python\n", - "'Hot62.6'\n", + "ValueError\n", "```" ] }, diff --git a/source/part1/chapter-02/nb/00-python-basics.ipynb b/source/part1/chapter-02/nb/00-python-basics.ipynb index 20b7c545..22c8ac1c 100644 --- a/source/part1/chapter-02/nb/00-python-basics.ipynb +++ b/source/part1/chapter-02/nb/00-python-basics.ipynb @@ -908,7 +908,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Let's also check the type of `tempFahrenheit`. What happens if you try to combine `tempFahrenheit` and `weatherForecast` in a single math equation such as `tempFahrenheit = tempFahrenheit + 5.0 * weatherForecast`?" + "Let's also check the type of `tempFahrenheit`. What happens if you try to combine `tempFahrenheit` and `weatherForecast` in a single math equation such as `tempFahrenheit = tempFahrenheit + weatherForecast`?" ] }, { @@ -928,19 +928,19 @@ "outputs": [ { "ename": "TypeError", - "evalue": "can't multiply sequence by non-int of type 'float'", + "evalue": "unsupported operand type(s) for +: 'float' and 'str'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[25], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28mtype\u001b[39m(tempFahrenheit)\n\u001b[0;32m----> 2\u001b[0m tempFahrenheit \u001b[38;5;241m=\u001b[39m tempFahrenheit \u001b[38;5;241m+\u001b[39m \u001b[38;5;241;43m5.0\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mweatherForecast\u001b[49m\n", - "\u001b[0;31mTypeError\u001b[0m: can't multiply sequence by non-int of type 'float'" + "Cell \u001b[0;32mIn[25], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28mtype\u001b[39m(tempFahrenheit)\n\u001b[0;32m----> 2\u001b[0m tempFahrenheit \u001b[38;5;241m=\u001b[39m \u001b[43mtempFahrenheit\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mweatherForecast\u001b[49m\n", + "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'float' and 'str'" ] } ], "source": [ "type(tempFahrenheit)\n", - "tempFahrenheit = tempFahrenheit + 5.0 * weatherForecast" + "tempFahrenheit = tempFahrenheit + weatherForecast" ] }, { @@ -950,7 +950,7 @@ "editable": true }, "source": [ - "In this case we get at `TypeError` because we are trying to execute a math operation with data types that are not compatible. There is no way in Python to multpily decimal values with a character string." + "In this case we get at `TypeError` because we are trying to execute a math operation with data types that are not compatible. It is not possible to add a number directly to a character string in Python. In order for addition to work, the data types need to be compatible with one another." ] }, { @@ -1047,7 +1047,48 @@ "source": [ "## Making different data types work together\n", "\n", - "In the previous section we saw that not all Python data types are directly compatible with others, which may result in a `TypeError` being raised. This means that (1) it is important to be aware of the data type of variables and (2) some additional steps may be needed to make different data compatible. In the example in the previous section we had `tempFahrenheit` (type `float`) and `weatherForecast` (type `str`) that were not compatible. How can we address this issue if we would like to work with those data together?" + "In the previous section we saw that not all Python data types are directly compatible with others, which may result in a `TypeError` being raised. This means that (1) it is important to be aware of the data type of variables and (2) some additional steps may be needed to make different data compatible. Let's consider an example where we try to combine `tempFahrenheit` (type `float`) with another temperature value. In this case, the other temperature is stored in a character string `forecastHighStr` (type `str`) with a value of `\"77.0\"`. As we know, data of type `float` and type `str` are not compatible for math operations. Let's start by defining `forecastHighStr` and then see how we can we address this issue to make these data work together." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'77.0'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "forecastHighStr = \"77.0\"\n", + "forecastHighStr" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "str" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "type(forecastHighStr)" ] }, { @@ -1062,12 +1103,12 @@ "source": [ "### Converting data from one type to another\n", "\n", - "It is not the case that things like the `tempFahrenheit` and `weatherForecast` cannot be combined at all, but in order to combine a character string with a number we need to perform a *{term}`type conversion`* to make them compatible. Let's convert `tempFahrenheit` to a character string using the `str()` function. We can store the converted variable as `tempFahrenheitStr`." + "It is not the case that things like the `tempFahrenheit` and `forecastHighStr` cannot be combined at all, but in order to combine a character string with a number we need to perform a *{term}`type conversion`* to make them compatible. Let's convert `forecastHighStr` to a floating point number using the `float()` function. We can store the converted variable as `forecastHigh`." ] }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 30, "metadata": { "editable": true, "slideshow": { @@ -1077,7 +1118,7 @@ }, "outputs": [], "source": [ - "tempFahrenheitStr = str(tempFahrenheit)" + "forecastHigh = float(forecastHighStr)" ] }, { @@ -1090,12 +1131,12 @@ "tags": [] }, "source": [ - "We can confirm the type has changed by checking the type of `tempFahrenheitStr` or by checking the output of a code cell with the variable." + "We can confirm the type has changed by checking the type of `forecastHigh` or by checking the output of a code cell with the variable." ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 31, "metadata": { "editable": true, "slideshow": { @@ -1107,21 +1148,21 @@ { "data": { "text/plain": [ - "str" + "float" ] }, - "execution_count": 29, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "type(tempFahrenheitStr)" + "type(forecastHigh)" ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 32, "metadata": { "editable": true, "slideshow": { @@ -1133,16 +1174,16 @@ { "data": { "text/plain": [ - "'62.6'" + "77.0" ] }, - "execution_count": 30, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "tempFahrenheitStr" + "forecastHigh" ] }, { @@ -1155,12 +1196,12 @@ "tags": [] }, "source": [ - "As you can see, `str()` converts a numerical value into a character string with the same numbers as before. Similar to using `str()` to convert numbers to character strings, `int()` can be used to convert strings or floating point numbers to integers, and `float()` can be used to convert strings or integers to floating point numbers. For example, we could convert `tempFahrenheit` to an integer as follows." + "As you can see, `float()` converts a character string to a decimal value representing the number stored in the string. `float()` can be used to convert strings or integers to floating point numbers, however `float()` can only convert strings that represent numerical values. For example, `float(\"Cold\")` will raise a `ValueError` because `\"Cold\"` cannot be converted to a number directly. Similar to `float()`, `str()` can convert numbers to character strings, and `int()` can be used to convert strings or floating point numbers to integers. For example, we could convert `tempFahrenheit` to an integer as follows." ] }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 33, "metadata": { "editable": true, "slideshow": { @@ -1188,7 +1229,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 34, "metadata": { "editable": true, "slideshow": { @@ -1203,7 +1244,7 @@ "int" ] }, - "execution_count": 32, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -1214,7 +1255,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 35, "metadata": { "editable": true, "slideshow": { @@ -1229,7 +1270,7 @@ "62" ] }, - "execution_count": 33, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -1270,7 +1311,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 36, "metadata": { "editable": true, "slideshow": { @@ -1287,7 +1328,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 37, "metadata": { "editable": true, "slideshow": { @@ -1327,12 +1368,12 @@ "source": [ "#### Question 2.5\n", "\n", - "What output would you expect to see when you execute `print(weatherForecast + tempFahrenheitStr)`?" + "What output would you expect to see when you execute `float(weatherForecast)`?" ] }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 38, "metadata": { "editable": true, "slideshow": { @@ -1349,7 +1390,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 39, "metadata": { "editable": true, "slideshow": { @@ -1357,96 +1398,27 @@ }, "tags": [ "remove_book_cell", - "hide-cell" + "hide-cell", + "raises-exception" ] }, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hot62.6\n" + "ename": "ValueError", + "evalue": "could not convert string to float: 'Hot'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[39], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# Solution\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[38;5;28;43mfloat\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mweatherForecast\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[0;31mValueError\u001b[0m: could not convert string to float: 'Hot'" ] } ], "source": [ "# Solution\n", "\n", - "print(weatherForecast + tempFahrenheitStr)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "### Combining text and numbers\n", - "\n", - "Although most mathematical operations are applied to numerical values, a common way to combine character strings is using the addition operator `+`. Let's create a text string in the variable `temp_and_forecast` that is the combination of the `tempFahrenheit` and `weatherForecast` variables. Once we define `temp_and_forecast`, we can print it to the screen to see the result." - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "temp_and_forecast = (\n", - " \"The current temperature is \"\n", - " + str(tempFahrenheit)\n", - " + \" and the forecast for today is \"\n", - " + weatherForecast\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'The current temperature is 62.6 and the forecast for today is Hot'" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "temp_and_forecast" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "Note that here we are converting `tempFahrenheit` to a character string using the `str()` function within the assignment to the variable `temp_and_forecast`. Alternatively, we could have simply combined `tempFahrenheitStr` and `weatherForecast`." + "float(weatherForecast)" ] } ], diff --git a/source/part1/chapter-02/nb/02-text-and-numbers.ipynb b/source/part1/chapter-02/nb/02-text-and-numbers.ipynb index 27801871..5f4350f6 100644 --- a/source/part1/chapter-02/nb/02-text-and-numbers.ipynb +++ b/source/part1/chapter-02/nb/02-text-and-numbers.ipynb @@ -197,8 +197,8 @@ "source": [ "## Manipulating character strings\n", "\n", - "Here we demonstrate some of the most useful string manipulation techniques, such as splitting strings based on a given character, replacing characters with new ones, slicing strings, etc. \n", - "The aim is to produce a list of weather station locations in Helsinki that are represented in uppercase text (i.e., `KUMPULA, KAISANIEMI, HARMAJA`). The text that we will begin working with is below:" + "Here we demonstrate some of the most useful string manipulation techniques, such as splitting strings based on a given character, replacing characters with new ones, slicing strings, concatenating strings, etc. \n", + "The aim is to produce the following text, which contains a list of weather station locations in Helsinki that are represented in uppercase text: `Our selection includes 3 weather stations (KUMPULA, KAISANIEMI, HARMAJA). The first observation is from 01/01/1882.`). The text that we will begin working with is below." ] }, { @@ -501,6 +501,163 @@ "print(stations_lower)\n", "print(stations_capitalize)" ] + }, + { + "cell_type": "markdown", + "id": "b6648bc9-098f-43d6-9bf8-b4cf3c7b213f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Concatenating strings\n", + "\n", + "Although most mathematical operations are applied to numerical values, a common way to combine (or concatenate) character strings is using the addition operator `+`. Let's try to complete our task of creating our target sentences by concatenating three separate character strings into one. As a reminder, the text we are aiming to produce reads `Our selection includes 3 weather stations (KUMPULA, KAISANIEMI, HARMAJA). The first observation is from 01/01/1882.`. We can first define some values we will need to create the target text." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "05d9e1bf-0b47-4eb6-a152-6c31d878bc18", + "metadata": {}, + "outputs": [], + "source": [ + "first_day = \"1\"\n", + "first_month = \"1\"\n", + "first_year = \"1882\"\n", + "number_of_stations = \"3\"" + ] + }, + { + "cell_type": "markdown", + "id": "a8ec3923-4614-4dd9-94df-4759e37c266d", + "metadata": {}, + "source": [ + "Note that if we were working with numerical values we would need to convert them to character strings using the `str()` function. Luckily, we already have character strings, so we can proceed with creating our sentences.\n", + "\n", + "As you may have noticed, out date should have the day and month represented with two characters (i.e., with a leading zero). We could use the `+` operator to add together `\"0\"` and our day or month value (e.g., `first_day = \"0\" + first_day`), however adding leading zeros to text is a common operation for ensuring consistent widths of text in data files, for example. Because of this, we can use the `.zfill()` function for strings to add leading zeros to our day and month values, as shown below." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "762b2cfc-f8da-4291-a52d-86622b088959", + "metadata": {}, + "outputs": [], + "source": [ + "first_day = first_day.zfill(2)\n", + "first_month = first_month.zfill(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "bc6d4c0a-e049-4bd3-8e4b-05d5ae8bcd28", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'01'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "first_day" + ] + }, + { + "cell_type": "markdown", + "id": "b611c6e7-4324-484b-94b4-5ff3449a12bf", + "metadata": {}, + "source": [ + "As you can see, the `.zfill()` function adds leading zeros before a number up to the number of characters specified when using it. In our case, we specified we want `2` characters, so one leading zero was added to our character strings. At this point, we can create a date string we can use for creating our sentences." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "73098ae9-2da2-4b46-8277-98a72f8ffc28", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'01/01/1882'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "date = first_day + \"/\" + first_month + \"/\" + first_year\n", + "date" + ] + }, + { + "cell_type": "markdown", + "id": "98294e72-6f96-4d10-b0e9-62d233e6c017", + "metadata": {}, + "source": [ + "Looks good. Now we can define the remaining pieces needed to create our sentences and concatenate them to form the target sentences." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "284b811d-a4f1-4aea-b498-f5d4bbe1e72e", + "metadata": {}, + "outputs": [], + "source": [ + "first_part = \"Our selection includes \" + number_of_stations\n", + "second_part = \" weather stations (\" + stations_upper\n", + "third_part = \"). The first observation is from \" + date + \".\"" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "6987cfc7-57fa-435f-bb8a-3a03e066f505", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Our selection includes 3 weather stations (KUMPULA, KAISANIEMI, HARMAJA). The first observation is from 01/01/1882.'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sentences = first_part + second_part + third_part\n", + "sentences" + ] + }, + { + "cell_type": "markdown", + "id": "9549e138-5a9b-4c80-a370-ff1400199c6c", + "metadata": {}, + "source": [ + "Nice! By simply breaking down the sentence into smaller character string segments we were able to use the `+` operator to create two sentences containing several numerical values combined in various ways. Well done!" + ] } ], "metadata": {