Add initial version of chapter 09's exercises, part 1

This commit is contained in:
Alexander Hess 2020-10-22 18:26:17 +02:00
parent a52178732a
commit f02a5f0e01
Signed by: alexander
GPG key ID: 344EA5AB10D868E0
2 changed files with 431 additions and 0 deletions

View file

@ -0,0 +1,428 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Note**: Click on \"*Kernel*\" > \"*Restart Kernel and Run All*\" in [JupyterLab](https://jupyterlab.readthedocs.io/en/stable/) *after* finishing the exercises to ensure that your solution runs top to bottom *without* any errors. If you cannot run this file on your machine, you may want to open it [in the cloud <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_mb.png\">](https://mybinder.org/v2/gh/webartifex/intro-to-python/develop?urlpath=lab/tree/09_mappings/01_exercises.ipynb)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Chapter 9: Mappings & Sets (Coding Exercises)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The exercises below assume that you have read the [first part <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_nb.png\">](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/develop/09_mappings/00_content.ipynb) of Chapter 9.\n",
"\n",
"The `...`'s in the code cells indicate where you need to fill in code snippets. The number of `...`'s within a code cell give you a rough idea of how many lines of code are needed to solve the task. You should not need to create any additional code cells for your final solution. However, you may want to use temporary code cells to try out some ideas."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Working with Nested Data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's write some code to analyze the historic soccer game [Brazil vs. Germany <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_wiki.png\">](https://en.wikipedia.org/wiki/Brazil_v_Germany_%282014_FIFA_World_Cup%29) during the 2014 World Cup.\n",
"\n",
"Below, `players` consists of two nested `dict` objects, one for each team, that hold `tuple` objects (i.e., records) with information on the players. Besides the jersey number, name, and position, each `tuple` objects contains a `list` object with the times when the player scored."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"players = {\n",
" \"Brazil\": [\n",
" (12, \"Júlio César\", \"Goalkeeper\", []),\n",
" (4, \"David Luiz\", \"Defender\", []),\n",
" (6, \"Marcelo\", \"Defender\", []),\n",
" (13, \"Dante\", \"Defender\", []),\n",
" (23, \"Maicon\", \"Defender\", []),\n",
" (5, \"Fernandinho\", \"Midfielder\", []),\n",
" (7, \"Hulk\", \"Midfielder\", []),\n",
" (8, \"Paulinho\", \"Midfielder\", []),\n",
" (11, \"Oscar\", \"Midfielder\", [90]),\n",
" (16, \"Ramires\", \"Midfielder\", []),\n",
" (17, \"Luiz Gustavo\", \"Midfielder\", []),\n",
" (19, \"Willian\", \"Midfielder\", []),\n",
" (9, \"Fred\", \"Striker\", []),\n",
" ],\n",
" \"Germany\": [\n",
" (1, \"Manuel Neuer\", \"Goalkeeper\", []),\n",
" (4, \"Benedikt Höwedes\", \"Defender\", []),\n",
" (5, \"Mats Hummels\", \"Defender\", []),\n",
" (16, \"Philipp Lahm\", \"Defender\", []),\n",
" (17, \"Per Mertesacker\", \"Defender\", []),\n",
" (20, \"Jérôme Boateng\", \"Defender\", []),\n",
" (6, \"Sami Khedira\", \"Midfielder\", [29]),\n",
" (7, \"Bastian Schweinsteiger\", \"Midfielder\", []),\n",
" (8, \"Mesut Özil\", \"Midfielder\", []),\n",
" (13, \"Thomas Müller\", \"Midfielder\", [11]),\n",
" (14, \"Julian Draxler\", \"Midfielder\", []),\n",
" (18, \"Toni Kroos\", \"Midfielder\", [24, 26]),\n",
" (9, \"André Schürrle\", \"Striker\", [69, 79]),\n",
" (11, \"Miroslav Klose\", \"Striker\", [23]),\n",
" ],\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q1**: Write a dictionary comprehension to derive a new `dict` object, called `brazilian_players`, that maps a Brazilian player's name to his position!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"brazilian_players = {...: ...}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"brazilian_players"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q2**: Generalize the code fragment into a `get_players()` function: Passed a `team` name, it returns a `dict` object like `brazilian_players`. Verify that the function works for the German team as well!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_players(team):\n",
" \"\"\"Creates a dictionary mapping the players' names to their position.\"\"\"\n",
" return {...: ...}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"get_players(\"Germany\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Often, we are given a `dict` object like the one returned from `get_players()`: Its main characteristic is that it maps a large set of unique keys (i.e., the players' names) onto a smaller set of non-unique values (i.e., the positions).\n",
"\n",
"**Q3**: Create a generic `invert()` function that swaps the keys and values of a `mapping` argument passed to it and returns them in a *new* `dict` object! Ensure that *no* key gets lost! Verify your implementation with the `brazilian_players` dictionary!\n",
"\n",
"Hints: Think of this as a grouping operation. The *new* values are `list` or `tuple` objects that hold the original keys. You may want to use either the [defaultdict <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/collections.html#collections.defaultdict) type from the [collections <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/collections.html) module in the [standard library <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/index.html) or the [.setdefault() <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) method on the ordinary `dict` type."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def invert(mapping):\n",
" \"\"\"Invert the keys and values of a mapping argument.\"\"\"\n",
" ...\n",
" ...\n",
" ...\n",
" return ..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"invert(brazilian_players)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q4**: Write a `score_at_minute()` function: It takes two arguments, `team` and `minute`, and returns the number of goals the `team` has scored up until this time in the game.\n",
"\n",
"Hints: The function may reference the global `players` for simplicity. Earn bonus points if you can write this in a one-line expression using some *reduction* function and a `generator` expression."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def score_at_minute(team, minute):\n",
" \"\"\"Determine the number of goals scored by a team until a given minute.\"\"\"\n",
" ...\n",
" ...\n",
" ...\n",
" ...\n",
" ...\n",
" return ..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The score at half time was:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score_at_minute(\"Brazil\", 45)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score_at_minute(\"Germany\", 45)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The final score was:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score_at_minute(\"Brazil\", 90)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score_at_minute(\"Germany\", 90)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q5**: Write a `goals_by_player()` function that takes an argument like the global `players`, and returns a `dict` object mapping the players to the number of goals they scored!\n",
"\n",
"Hints: Do *not* \"hard code\" the names of the teams! Earn bonus points if you can solve it in a one-line `dict` comprehension."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def goals_by_player(players):\n",
" \"\"\"Create a dictionary mapping the players' names to the number of goals.\"\"\"\n",
" ...\n",
" ...\n",
" ...\n",
" ...\n",
" return ..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"goals_by_player(players)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q6**: Write a `dict` comprehension to filter out the players who did *not* score from the preceding result.\n",
"\n",
"Hints: Reference the `goals_by_player()` function from before."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"{...: ...}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q7**: Write a `all_goals()` function that takes one argument like the global `players` and returns a `list` object containing $2$-element `tuple` objects where the first element is the minute a player scored and the second his name! The list should be sorted by the time.\n",
"\n",
"Hints: You may want to use either the built-in [sorted() <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/functions.html#sorted) function or the `list` type's [.sort() <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/stdtypes.html#list.sort) method. Earn bonus points if you can write a one-line expression with a `generator` expression."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def all_goals(players):\n",
" \"\"\"Create a time table of the individual goals.\"\"\"\n",
" ...\n",
" ...\n",
" ...\n",
" ...\n",
" ...\n",
" return ..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"all_goals(players)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q8**: Lastly, write a `summary()` function that takes one argument like the global `players` and prints out a concise report of the goals, the score at the half, and the final result.\n",
"\n",
"Hints: Use the `all_goals()` and `score_at_minute()` functions from before.\n",
"\n",
"The output should look similar to this:\n",
"```\n",
"12' Gerd Müller scores\n",
"...\n",
"HALFTIME: TeamA 1 TeamB 2\n",
"77' Ronaldo scores\n",
"...\n",
"FINAL: TeamA 1 TeamB 3\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def summary(players):\n",
" \"\"\"Create a written summary of the game.\"\"\"\n",
" # Create two lists with the goals of either half.\n",
" ...\n",
" ...\n",
" ...\n",
"\n",
" # Print the goals of the first half.\n",
" ...\n",
" ...\n",
"\n",
" # Print the half time score.\n",
" ...\n",
" ...\n",
" ...\n",
" ...\n",
" ...\n",
"\n",
" # Print the goals of the second half.\n",
" ...\n",
" ...\n",
"\n",
" # Print the final score.\n",
" ...\n",
" ...\n",
" ...\n",
" ...\n",
" ..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"summary(players)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.6"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": false,
"sideBar": true,
"skip_h1_title": true,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": false,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View file

@ -237,3 +237,6 @@ If this is not possible,
Hash Tables; Hash Tables;
`dict` Methods & Behavior; `dict` Methods & Behavior;
`dict` Comprehension) `dict` Comprehension)
- [exercises <img height="12" style="display: inline-block" src="static/link/to_nb.png">](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/develop/09_mappings/01_exercises.ipynb)
[<img height="12" style="display: inline-block" src="static/link/to_mb.png">](https://mybinder.org/v2/gh/webartifex/intro-to-python/develop?urlpath=lab/tree/09_mappings/01_exercises.ipynb)
(Working with Nested Data)