Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 57 additions & 52 deletions 04_input_output.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@
" - [Reading/Writing CSV files](#Reading/Writing-CSV-files)\n",
" - [Quiz on CSV](#Quiz-on-CSV)\n",
" - [Exercises](#Exercises)\n",
" - [Exercise 1: CSV to dictionary 🌶️](#Exercise-1:-CSV-to-dictionary-🌶️)\n",
" - [Exercise 2: Counting words 🌶️](#Exercise-2:-Counting-words-🌶️)\n",
" - [Exercise 3: Letter statistics 🌶️🌶️](#Exercise-3:-Letter-statistics-🌶️🌶️)\n",
" - [Exercise 4: Translating words 🌶️🌶️](#Exercise-4:-Translating-words-🌶️🌶️)\n",
" - [Exercise 5: Binary format 🌶️🌶️🌶️](#Exercise-5:-Binary-format-🌶️🌶️🌶️)"
" - [Exercise 1: CSV to dictionary](#Exercise-1:-CSV-to-dictionary)\n",
" - [Exercise 2: Counting words](#Exercise-2:-Counting-words)\n",
" - [Exercise 3: Letter statistics](#Exercise-3:-Letter-statistics)\n",
" - [Exercise 4: Translating words](#Exercise-4:-Translating-words)\n",
" - [Exercise 5: Binary format](#Exercise-5:-Binary-format)"
]
},
{
Expand Down Expand Up @@ -75,13 +75,7 @@
"- connecting to databases or other network services\n",
"\n",
"\n",
"The majority of these operations are covered by the Python standard library. We are going to see how to use them in this chapter.\n",
"\n",
"<div class=\"alert alert-block alert-info\">\n",
" <h4><b>Note</b></h4>\n",
"In reference to the chapter on functional programming, it is interesting to note that these functions perform <b>side-effects</b>. Therefore, any code containing these operations is no longer <b>pure</b> and is not referentially transparent. The same function can return different values for the same argument if called multiple times, and the function can have <b>long-distance</b> effects. That means they can modify the program state elsewhere, leading to unexpected results.<br><br>\n",
"Therefore, we suggest separating input and output from the other computations in your program. For example, if you have a complex calculation requiring several user inputs at several stages of the process, consider writing a function that only performs the calculation given all inputs and then requires all inputs separately, for example, through a single file. This makes your code easier to debug, test and understand.\n",
"</div>"
"The majority of these operations are covered by the Python standard library. We are going to see how to use them in this chapter."
]
},
{
Expand All @@ -108,8 +102,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"It is also possible to print any other python object using `print`. \n",
"In that case, the `__str__` **magic method** on that object's class is [called](https://docs.python.org/3/reference/datamodel.html#object.__str__)."
"It is also possible to print any other python object using `print`."
]
},
{
Expand Down Expand Up @@ -245,7 +238,7 @@
"metadata": {},
"outputs": [],
"source": [
"%%ipytest debug\n",
"%%ipytest\n",
"\n",
"def solution_print_odd(n: int) -> None: \n",
" \"\"\"Prints all odd numbers from 1 to n\n",
Expand All @@ -255,8 +248,7 @@
"\n",
" Returns:\n",
" - None (prints to console)\n",
" \"\"\"\n",
" pass"
" \"\"\""
]
},
{
Expand Down Expand Up @@ -287,7 +279,6 @@
" Returns:\n",
" - None (prints to console)\n",
" \"\"\"\n",
" pass\n",
"\n",
"solution_print_salutation()"
]
Expand Down Expand Up @@ -526,7 +517,7 @@
"metadata": {},
"source": [
"\n",
"1. Modify the function `solution_find_all_files` to find all files and directories in the [data](./tutorial/tests/data/) (./tutorial/tests/data/) directory and return them as a list of `Path` objects\n",
"1. Modify the function `solution_find_all_files` to find all files and directories in the ```/tutorial/tests/data``` directory and return them as a list of `Path` objects\n",
"\n",
"<div class=\"alert alert-block alert-info\">\n",
" <b>Hint:</b> The path to the data directory is available as the argument <code>current_path</code> of the function <code>solution_find_all_files</code>\n",
Expand Down Expand Up @@ -613,8 +604,7 @@
"\n",
" Returns:\n",
" - The number of directories in the directory\n",
" \"\"\"\n",
" pass\n"
" \"\"\""
]
},
{
Expand All @@ -627,9 +617,9 @@
"### Reading from a file\n",
"\n",
"We now want to learn how to read text from a file. \n",
"Let's see how to do this with an example: we want to open the file [hello.txt](./data/hello.txt) and read its contents.\n",
"Let's see how to do this with an example: we want to open the file [hello.txt](./tutorial/tests/data/hello.txt) and read its contents.\n",
"\n",
"1. The path is already identified, we know the file is in `./data/hello.txt`. We save this in a variable `path`.\n",
"1. The path is already identified, we know the file is in [hello.txt](./tutorial/tests/data/hello.txt). We save this in a variable `path`.\n",
"2. We now can use the built-in function [`open`](https://docs.python.org/3/library/functions.html#open) to open the file. This function returns a [file object](https://docs.python.org/3/glossary.html#term-file-object) that we can use to further manipulate the file. To ensure we only open the file for reading, we pass the string \"r\" to the second argument of `open`.\n",
"3. Now we can read the contents using `read`, `readline` or `readlines`. `read` reads the whole file content into a single string, `readline` reads one line, while `readlines` reads the whole file content as a list of strings, one item per line in the file. This knowledge is useful when we only want to read part of a file or when the file is too big to fit in memory and we can only read parts.\n",
"4. Finally, we close the file using the `close` method on the file object.\n"
Expand Down Expand Up @@ -773,7 +763,7 @@
" Returns:\n",
" - A list of strings, each representing a line in the file\n",
" \"\"\"\n",
" pass"
" return"
]
},
{
Expand All @@ -787,7 +777,7 @@
"- We use `write` to write a *string* to the file. Other types of object should be converted to string before being written.\n",
"\n",
"\n",
"Let's see this in action by writing your name in a file called `me.txt` in [data](./data/)"
"Let's see this in action by writing your name in a file called `me.txt` in ```/tutorial/tests/data```"
]
},
{
Expand Down Expand Up @@ -902,26 +892,31 @@
"\n",
" Returns:\n",
" - None (writes to file)\n",
" \"\"\"\n",
" pass"
" \"\"\""
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"2. Modify the function `solution_read_write_file` to read the lines from the file `input_file` and write them in the form `line, length`, to the file `output_file`. Here `line` is the line of text in `input_file` **without the line ending**, `length` is **number of characters** in that line **without the line separator**.\n",
"If `input_file` contains these lines:\n",
"2. Modify the function `solution_read_write_file` to read the lines from the file `input_file` and write them in the form `line, length`, to the file `output_file`. Here `line` is the line of text in `input_file` **without the line ending (\\r\\n)**, `length` is **number of characters** in that line. The characters are added automatically by the operating system when reading a file. Windows uses **\\r\\n** whereas Linux and MacOS use only **\\n**. To remove the line ending characters, use ```strip(\"\\r\\n\")```, e.g.: ```line.strip(\"\\r\\n\")```.\n",
"\n",
" If `input_file` contains these lines:\n",
" \n",
" ```\n",
" first\n",
" second\n",
" ```\n",
" \n",
" we expect the output file to contain these lines:\n",
" \n",
" ```\n",
" first, 5\n",
" second, 6\n",
" ```"
" ```\n",
" \n",
" Do not forget to add a **\\n** when writing lines in the file."
]
},
{
Expand All @@ -945,8 +940,7 @@
"\n",
" Returns:\n",
" - None (writes to file)\n",
" \"\"\"\n",
" pass"
" \"\"\""
]
},
{
Expand Down Expand Up @@ -1201,7 +1195,9 @@
"source": [
"message = \"Ciao\"\n",
"message_secret = bytes(message, \"utf-8\")\n",
"[print(f\"The `uft8` codepoint is = {enc}, the bytes representation = {enc.to_bytes(4, 'little')}, the representation is {chr(enc)}\") for plain, enc in zip(message, message_secret)]"
"print_messages = [f\"The `uft8` codepoint is = {enc}, the bytes representation = {enc.to_bytes(4, 'little')}, the representation is {chr(enc)}\" for plain, enc in zip(message, message_secret)]\n",
"for msg in print_messages:\n",
" print(msg)"
]
},
{
Expand All @@ -1225,7 +1221,7 @@
"These packages are outside of the scope of this tutorial and will not be covered here.\n",
"\n",
"\n",
"Let's see how to read csv files using `csv` with an example by reading [example.csv](./data/example.csv):"
"Let's see how to read csv files using `csv` with an example by reading [example.csv](./tutorial/tests/data/example.csv):"
]
},
{
Expand Down Expand Up @@ -1330,7 +1326,7 @@
"tags": []
},
"source": [
"### Exercise 1: CSV to dictionary 🌶️"
"### Exercise 1: CSV to dictionary"
]
},
{
Expand All @@ -1340,6 +1336,8 @@
"tags": []
},
"source": [
"**Difficulty: 🌶️**\n",
"\n",
"Write a function that reads a CSV file and returns a dictionary.\n",
"\n",
"- The dictionary keys are in the first **column**\n",
Expand Down Expand Up @@ -1404,7 +1402,7 @@
" Returns:\n",
" - A dictionary with each row represented as a key, value pair\n",
" \"\"\"\n",
" pass"
" return"
]
},
{
Expand All @@ -1414,7 +1412,7 @@
"tags": []
},
"source": [
"### Exercise 2: Counting words 🌶️"
"### Exercise 2: Counting words"
]
},
{
Expand All @@ -1424,6 +1422,8 @@
"tags": []
},
"source": [
"**Difficulty: 🌶️**\n",
"\n",
"Write a function to read all the lines from `input_file` and count the number of words in the file. The solution should be a single number.\n",
"\n",
"For example, for the file\n",
Expand All @@ -1443,7 +1443,7 @@
" The file is available as the parameter <code>input_file</code> of <code>solution_exercise2</code> function\n",
" </li>\n",
" <li>\n",
" A word consists of <b>printable</b> characters without whitespaces, line breaks etc. Have a look at the basic_datatypes notebook if you forgot how to split a text into it's words.\n",
" A word consists of <b>printable</b> characters without whitespaces, line breaks etc. Have a look at the basic_datatypes notebook if you forgot how to split a text into its words.\n",
" </li>\n",
" </ul>\n",
"</div>\n",
Expand Down Expand Up @@ -1472,7 +1472,7 @@
" Returns:\n",
" - The number of words in the file\n",
" \"\"\"\n",
" pass"
" return"
]
},
{
Expand All @@ -1482,7 +1482,7 @@
"tags": []
},
"source": [
"### Exercise 3: Letter statistics 🌶️🌶️"
"### Exercise 3: Letter statistics"
]
},
{
Expand All @@ -1492,7 +1492,9 @@
"tags": []
},
"source": [
"Write a function that reads all the lines from `lines.txt` and counts the occurences of every letter present in all the words.\n",
"**Difficulty: 🌶️🌶️**\n",
"\n",
"Write a function that reads all the lines from [lines.txt](./tutorial/tests/data/lines.txt) and counts the occurences of every letter present in all the words.\n",
"\n",
"The result should be a dictionary, where each key-value pair is like `{letter: count}`. For example, `{a: 5}` means that the letter `a` appeared five times in this file.\n",
"\n",
Expand Down Expand Up @@ -1522,7 +1524,7 @@
"metadata": {},
"outputs": [],
"source": [
"%%ipytest input_output\n",
"%%ipytest\n",
"\n",
"import pathlib as pl\n",
"import string\n",
Expand All @@ -1538,7 +1540,7 @@
" Returns:\n",
" - A dictionary with a count of each letter\n",
" \"\"\"\n",
" pass"
" return"
]
},
{
Expand All @@ -1548,7 +1550,7 @@
"tags": []
},
"source": [
"### Exercise 4: Translating words 🌶️🌶️"
"### Exercise 4: Translating words"
]
},
{
Expand All @@ -1558,7 +1560,9 @@
"tags": []
},
"source": [
"Write a function which takes the words from the file `english.txt` and translates them to Italian using the dictionary file `dict.csv`. The output should be a **list of tuples** with the pair `italian, english` if the word is found and nothing otherwise.\n",
"**Difficulty: 🌶️🌶️**\n",
"\n",
"Write a function which takes the words from the file [english.txt](./tutorial/tests/data/english.txt) and translates them to Italian using the dictionary file [dict.csv](./tutorial/tests/data/dict.csv). The output should be a **list of tuples** with the pair `italian, english` **if the word is found and nothing otherwise**.\n",
"\n",
"For example, given the `english.txt` file:\n",
"\n",
Expand Down Expand Up @@ -1600,6 +1604,7 @@
"source": [
"%%ipytest\n",
"\n",
"import csv\n",
"import pathlib as pl\n",
"\n",
"def solution_exercise4(english: pl.Path, dictionary: pl.Path) -> list[(str, str)]:\n",
Expand All @@ -1615,8 +1620,7 @@
" Returns:\n",
" - A list of tuples with the english / italian words\n",
" \"\"\"\n",
"\n",
" pass"
" return"
]
},
{
Expand All @@ -1626,7 +1630,7 @@
"tags": []
},
"source": [
"### Exercise 5: Binary format 🌶️🌶️🌶️"
"### Exercise 5: Binary format"
]
},
{
Expand All @@ -1636,8 +1640,9 @@
"tags": []
},
"source": [
"**Difficulty: 🌶️🌶️🌶️**\n",
"\n",
"The file `super_secret.dat` contains a secret message. We know that the message is stored in binary format as a sequence of bytes. The message starts with the byte sequence `b'\\xff\\xee\\xdd\\xcc\\xbb\\xaa'` and finishes with `b'\\xaa\\xbb\\xcc\\xdd\\xee\\xff'`. \n",
"The file `secret_file` contains a secret message. We know that the message is stored in binary format as a sequence of bytes. The message starts with the byte sequence `b'\\xff\\xee\\xdd\\xcc\\xbb\\xaa'` and finishes with `b'\\xaa\\xbb\\xcc\\xdd\\xee\\xff'`. \n",
"Write a function that reads the file and returns **only** the secret message as a string.\n",
"\n",
"\n",
Expand Down Expand Up @@ -1678,14 +1683,14 @@
" Returns:\n",
" - The secret message\n",
" \"\"\"\n",
" pass"
" return"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "Python 3",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
Expand All @@ -1699,7 +1704,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.4"
"version": "3.13.5"
}
},
"nbformat": 4,
Expand Down
Loading