Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Module 6: Testing Code #125

Draft
wants to merge 161 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 139 commits
Commits
Show all changes
161 commits
Select commit Hold shift + click to select a range
26865b2
Begin section on testing code
rsokl Dec 7, 2019
ce05d2c
work on intro
rsokl Dec 7, 2019
1042780
complete first cut of intro
rsokl Dec 7, 2019
ea239ec
working on motivation
rsokl Dec 7, 2019
4b7cf34
work on motivation
rsokl Dec 8, 2019
b996874
continue developing motivation
rsokl Dec 8, 2019
1126909
complete draft of motivations
rsokl Dec 8, 2019
9ed1048
fix inconsistency in count_vowels docstring
rsokl Dec 8, 2019
37b5509
fix inconsistency in count_vowels docstring
rsokl Dec 8, 2019
26625d3
fix inconsistency between docstring and type-hint
rsokl Dec 8, 2019
fd6e029
add first example
rsokl Dec 8, 2019
f76dd1e
discuss asserts
rsokl Dec 8, 2019
af93863
minor wording changes
rsokl Dec 10, 2019
9407a00
Merge branch 'master' into testing-code
rsokl Dec 15, 2019
f398f88
minor formatting fix: italicized was broken
rsokl Dec 15, 2019
f89496c
finish section on count-vowels test
rsokl Dec 15, 2019
1e1e885
touch up working in first couple of sections
rsokl Dec 15, 2019
1932d55
complete section on assertions
rsokl Dec 15, 2019
94b494a
Add section on testing tests
rsokl Dec 15, 2019
a3c9ce3
add test suite to package structure
rsokl Dec 15, 2019
6812366
use consistent voice in testing tests
rsokl Dec 15, 2019
cbdd2b5
rearrange mateirals: testing tests goes before assertions
rsokl Dec 16, 2019
8155a13
move testing-code material to its own module
rsokl Dec 20, 2019
5801b68
fix rst delimiter length mismatch for module 5
rsokl Dec 20, 2019
8132f20
introduce merge-max-mappings
rsokl Dec 20, 2019
2fbd4e6
adding summary to basic test structure
rsokl Dec 20, 2019
42117d2
add test example for merge-max-dicts
rsokl Dec 20, 2019
8672564
Finish intro to testing
rsokl Dec 21, 2019
5378e3b
add initial pytest section
rsokl Dec 21, 2019
5a84be9
remove ipynb pairing
rsokl Dec 21, 2019
3acb67c
fix bad import in setuptools code snippet
rsokl Dec 21, 2019
d10ce3c
fix docstring formatting in numpy-broadcasting
rsokl Dec 22, 2019
fc2c7b1
progress on pytest section - basic project layout
rsokl Dec 22, 2019
38efd62
minor revision to wording in Install Your Own Package
rsokl Dec 23, 2019
10edfd2
complete section on installing your own source code
rsokl Dec 23, 2019
e946e47
add material for populating/running a test suite
rsokl Dec 23, 2019
30ebcf0
add module 6 to index.rst, and add add relevant md files to subsection
rsokl Dec 24, 2019
3f021e3
fix sub-bullet indentation
rsokl Dec 24, 2019
a847706
add centered image to Pytest; add warning about nosetest etc
rsokl Dec 24, 2019
762fa86
general text cleanup / typo fixes
rsokl Dec 26, 2019
dd6f4e5
add IDE images to _build/_images
rsokl Dec 26, 2019
af19faa
Add IDE images, links, and descritpions for testing
rsokl Dec 26, 2019
3c5fa9f
fix some wording
rsokl Dec 26, 2019
79c1b6b
fix some wording
rsokl Dec 26, 2019
0ba2d6d
Finish enriched assertions
rsokl Dec 27, 2019
5c9f55f
begin parameterization discussion
rsokl Dec 27, 2019
36399c5
finish discussion of parameterization
rsokl Dec 28, 2019
2be94ad
wording / typo fixes
rsokl Dec 28, 2019
1c18e0a
complete discussion of fixtures
rsokl Dec 28, 2019
ce7b392
fix wording and add fixture tests
rsokl Dec 28, 2019
4e4be51
conf.py -> conftest.py
rsokl Dec 28, 2019
9f02917
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 4, 2020
25f8a82
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 4, 2020
d34a21b
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 4, 2020
4d932e6
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 4, 2020
f11eddb
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 4, 2020
9e1704d
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 4, 2020
e041c1d
Update Python/Module6_Testing/Pytest.md
rsokl Jan 4, 2020
5815248
Update Python/Module6_Testing/Pytest.md
rsokl Jan 4, 2020
63ccf3a
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 4, 2020
4b2f2c4
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 4, 2020
bf8363b
Update Python/Module6_Testing/Pytest.md
rsokl Jan 4, 2020
398f566
Update Python/Module6_Testing/Pytest.md
rsokl Jan 4, 2020
9bf072f
Update Python/Module6_Testing/Pytest.md
rsokl Jan 4, 2020
06882ef
Update Python/Module6_Testing/Pytest.md
rsokl Jan 4, 2020
2b6f6a6
Update Python/Module6_Testing/Pytest.md
rsokl Jan 4, 2020
0f3e5a1
Update Python/Module6_Testing/Pytest.md
rsokl Jan 4, 2020
8dfda2d
Update Python/Module5_OddsAndEnds/Modules_and_Packages.md
rsokl Jan 4, 2020
871ba15
add python_requires and change setup.py commands to pip
rsokl Jan 4, 2020
a46350e
formalizing -> automating
rsokl Jan 4, 2020
a6ff50f
PNG -> png
rsokl Jan 4, 2020
fb2f548
add disable assertions
rsokl Jan 4, 2020
a95409f
add discussion of mutation testing
rsokl Jan 4, 2020
fe51dbf
foul swoop is not a phrase... it is fell swoop
rsokl Jan 4, 2020
9c8611d
add caveat about mutations
rsokl Jan 4, 2020
2832232
add comments to fixture
rsokl Jan 4, 2020
6355e4a
Peter edits
rsokl Jan 4, 2020
8059abb
improve wording to not say fail so many times
rsokl Jan 4, 2020
cb3d952
fix type: >? should be >=
rsokl Jan 4, 2020
8b02be7
Change module title to Testing OUR Code; add hypothesis section
rsokl Jan 5, 2020
34013dd
remove redundant content
rsokl Jan 5, 2020
22995ce
update meta description for pytest section
rsokl Jan 5, 2020
df038b9
working on hypothesis intro
rsokl Jan 5, 2020
c20c37a
add description of len size limit
rsokl Jan 5, 2020
10f572b
fix punctuation
rsokl Jan 5, 2020
61fab2f
Update Python/Module5_OddsAndEnds/Modules_and_Packages.md
rsokl Jan 11, 2020
558c164
Merge branch 'testing-code' of mit:rsokl/Learning_Python into testing…
rsokl Jan 11, 2020
feccc6c
link to pytest site
rsokl Jan 11, 2020
7c043cf
Update Python/Module5_OddsAndEnds/Modules_and_Packages.md
rsokl Jan 11, 2020
0b7d559
Update Python/Module5_OddsAndEnds/Modules_and_Packages.md
rsokl Jan 11, 2020
c0ebc83
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 11, 2020
9adde9e
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 11, 2020
3649d3a
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 11, 2020
7f9c0fb
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 11, 2020
125b2df
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 11, 2020
3b17250
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 11, 2020
d7c8fca
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 11, 2020
7f717bb
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 11, 2020
446fe1d
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 11, 2020
96b3b04
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 11, 2020
79f418c
Update Python/Module6_Testing/Intro_to_Testing.md
rsokl Jan 11, 2020
3d66b48
Update Python/Module6_Testing/Pytest.md
rsokl Jan 11, 2020
b32ab37
Update Python/Module6_Testing/Pytest.md
rsokl Jan 11, 2020
1841a84
Update Python/Module6_Testing/Pytest.md
rsokl Jan 11, 2020
cd78e8c
Update Python/Module6_Testing/Pytest.md
rsokl Jan 11, 2020
f7107ed
Update Python/Module6_Testing/Pytest.md
rsokl Jan 11, 2020
5de8830
Update Python/Module6_Testing/Pytest.md
rsokl Jan 11, 2020
da824f0
Update Python/Module6_Testing/Pytest.md
rsokl Jan 11, 2020
35bd28e
Update Python/Module6_Testing/Pytest.md
rsokl Jan 11, 2020
6efb684
Update Python/Module6_Testing/Hypothesis.md
rsokl Jan 11, 2020
149aa78
Update Python/Module6_Testing/Hypothesis.md
rsokl Jan 11, 2020
72c0fc1
Update Python/Module6_Testing/Hypothesis.md
rsokl Jan 11, 2020
3c8f49d
Update Python/Module6_Testing/Hypothesis.md
rsokl Jan 11, 2020
a5a027f
clean up sentence
rsokl Feb 16, 2020
d9a01f9
Merge branch 'master' into testing-code
rsokl Mar 28, 2020
ebeeddc
Adds discussion of given decorator
rsokl Mar 28, 2020
3e3a154
Finish discussion of core strats; add initial sub section
rsokl Mar 28, 2020
265cfff
fix formatting
rsokl Mar 28, 2020
a8ff23d
Zac edits: default conda channel and cpython docs
rsokl Mar 29, 2020
4d68755
add reading comprehension: improving tests with hypothesis
rsokl Mar 29, 2020
273d34b
Add discussion of: .map(), .filter(), st.data(), and @example()
rsokl Mar 29, 2020
0d1177f
fix some formatting
rsokl Mar 29, 2020
c4267ed
add some docs to example
rsokl Mar 29, 2020
6d4a94a
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
0b3e4c0
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
6821619
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
5588f16
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
ea4207e
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
bd88886
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
40c7161
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
de0a696
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
97d6e73
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
ea9d6ab
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
88eacf1
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
3667ffc
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
3936c71
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
bf61b1b
Update Python/Module6_Testing/Hypothesis.md
rsokl Mar 30, 2020
6633bb8
add hypothesis practice exercises
rsokl Apr 4, 2020
fd703e1
add beginning of Writing Your Own Strategies
rsokl Apr 5, 2020
6d3875a
Merge branch 'master' into testing-code
rsokl Apr 18, 2020
674361a
Update Python/Module6_Testing/Hypothesis_Practice_Exercises.md
rsokl Feb 12, 2021
3be2da0
fix merge conflicts
rsokl Aug 21, 2022
20f2bf8
fix header level
rsokl Aug 21, 2022
9157db1
fix kernel info
rsokl Aug 21, 2022
cd38087
Reformat decorator aside and fix clunky wording
rsokl Aug 21, 2022
590e2cb
Introduction to Testing -> The Basics of Writing Tests for Python Code
rsokl Aug 21, 2022
624ca60
Fix meta descriptions
rsokl Aug 21, 2022
4bded9e
Add hypothesis practice exercises
rsokl Aug 21, 2022
5a9567c
Merge branch 'testing-code' of github.com:rsokl/Learning_Python into …
rsokl Aug 22, 2022
25e25f4
remove distutils ref
rsokl Aug 22, 2022
407dc7d
Apply suggestions from code review
rsokl Aug 22, 2022
eb5f2a7
Merge branch 'testing-code' of github.com:rsokl/Learning_Python into …
rsokl Aug 22, 2022
0f74df1
Ease up on discussion of len esge case
rsokl Aug 22, 2022
56366e9
Update Python/Module6_Testing/Hypothesis.md
rsokl Aug 22, 2022
36262f7
Update Python/Module6_Testing/Hypothesis.md
rsokl Aug 22, 2022
0b1f2dc
Update Python/Module6_Testing/Hypothesis.md
rsokl Aug 22, 2022
2b0da48
Merge branch 'testing-code' of github.com:rsokl/Learning_Python into …
rsokl Aug 22, 2022
2baed1d
be more precise in description of st.text()
rsokl Aug 23, 2022
c97ee7a
Update Python/Module6_Testing/Hypothesis.md
rsokl Aug 23, 2022
b643bb3
Fix description of lambda, and make use of term 'strategy' consistent
rsokl Aug 23, 2022
a3cd86c
Merge branch 'testing-code' of github.com:rsokl/Learning_Python into …
rsokl Aug 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Python/Module2_EssentialsOfPython/Functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ Write a function named `count_even`. It should accept one input argument, named

<!-- #region -->
## The `return` Statement
In general, any Python object can follow a function's `return` statement. Furthermore, an **empty** `return` statement can be specified, or the **return** statement of a function can be omitted altogether. In both of these cases, *the function will return the `None` object*.
In general, any Python object can follow a function's `return` statement. Furthermore, an **empty** `return` statement can be specified, or the **return** statement of a function can be omitted altogether. In both of these cases, *the function will return the* `None` *object*.

```python
# this function returns `None`
Expand Down
74 changes: 37 additions & 37 deletions Python/Module3_IntroducingNumpy/Broadcasting.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jupyter:
extension: .md
format_name: markdown
format_version: '1.2'
jupytext_version: 1.3.0rc1
jupytext_version: 1.3.0
kernelspec:
display_name: Python 3
language: python
Expand Down Expand Up @@ -486,16 +486,16 @@ Performing this computation using for-loops proceeds as follows:
def pairwise_dists_looped(x, y):
""" Computing pairwise distances using for-loops

Parameters
----------
x : numpy.ndarray, shape=(M, D)
y : numpy.ndarray, shape=(N, D)
Parameters
----------
x : numpy.ndarray, shape=(M, D)
y : numpy.ndarray, shape=(N, D)

Returns
-------
numpy.ndarray, shape=(M, N)
The Euclidean distance between each pair of
rows between `x` and `y`."""
Returns
-------
numpy.ndarray, shape=(M, N)
The Euclidean distance between each pair of
rows between `x` and `y`."""
# `dists[i, j]` will store the Euclidean
# distance between `x[i]` and `y[j]`
dists = np.empty((5, 6))
Expand Down Expand Up @@ -545,18 +545,18 @@ Voilà! We have produced the distances in a vectorized way. Let's write this out
def pairwise_dists_crude(x, y):
""" Computing pairwise distances using vectorization.

This method uses memory-inefficient broadcasting.
Parameters
----------
x : numpy.ndarray, shape=(M, D)
y : numpy.ndarray, shape=(N, D)
Returns
-------
numpy.ndarray, shape=(M, N)
The Euclidean distance between each pair of
rows between `x` and `y`."""
This method uses memory-inefficient broadcasting.

Parameters
----------
x : numpy.ndarray, shape=(M, D)
y : numpy.ndarray, shape=(N, D)

Returns
-------
numpy.ndarray, shape=(M, N)
The Euclidean distance between each pair of
rows between `x` and `y`."""
# The use of `np.newaxis` here is equivalent to our
# use of the `reshape` function
return np.sqrt(np.sum((x[:, np.newaxis] - y[np.newaxis])**2, axis=2))
Expand Down Expand Up @@ -628,23 +628,23 @@ In total, we have successfully used vectorization to compute the all pairs of di

```python
def pairwise_dists(x, y):
""" Computing pairwise distances using memory-efficient
vectorization.

Parameters
----------
x : numpy.ndarray, shape=(M, D)
y : numpy.ndarray, shape=(N, D)

Returns
-------
numpy.ndarray, shape=(M, N)
The Euclidean distance between each pair of
rows between `x` and `y`."""
""" Computing pairwise distances using memory-efficient
vectorization.

Parameters
----------
x : numpy.ndarray, shape=(M, D)
y : numpy.ndarray, shape=(N, D)

Returns
-------
numpy.ndarray, shape=(M, N)
The Euclidean distance between each pair of
rows between `x` and `y`."""
dists = -2 * np.matmul(x, y.T)
dists += np.sum(x**2, axis=1)[:, np.newaxis]
dists += np.sum(x**2, axis=1)[:, np.newaxis]
dists += np.sum(y**2, axis=1)
return np.sqrt(dists)
return np.sqrt(dists)
```


Expand Down
37 changes: 24 additions & 13 deletions Python/Module5_OddsAndEnds/Modules_and_Packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jupyter:
extension: .md
format_name: markdown
format_version: '1.2'
jupytext_version: 1.3.0rc1
jupytext_version: 1.3.0
kernelspec:
display_name: Python 3
language: python
Expand Down Expand Up @@ -406,15 +406,15 @@ It must be mentioned that we are sweeping some details under the rug here. Insta

### Installing Your Own Python Package

Suppose that we are happy with the work we have done on our `face_detector` project. We will want to install this package - placing it in our site-packages directory so that we can import it irrespective of our Python interpreter's working directory. Here we will construct a basic setup script that will allow us to accomplish this.
Suppose that we are happy with the work we have done on our `face_detector` project. We will want to install this package - placing it in our site-packages directory so that we can import it irrespective of our Python interpreter's working directory. Here we will construct a basic setup script that will allow us to accomplish this. For completeness, we will also indicate how one would include a test suite alongside the source code in this directory structure.

We note outright that the purpose of this section is strictly to provide you with the minimum set of instructions needed to install a package. We will not be diving into what is going on under the hood at all. Please refer to [An Introduction to Distutils](https://docs.python.org/3/distutils/introduction.html#an-introduction-to-distutils) and [Packaging Your Project](https://packaging.python.org/tutorials/packaging-projects/#packaging-your-project) for a deeper treatment of this topic.
rsokl marked this conversation as resolved.
Show resolved Hide resolved

Carrying on, we will want to create a setup-script, `setup.py`, *in the same directory as our package*. That is, our directory structure should look like:

```
- setup.py
- face_detection/
- setup.py # script responsible for installing `face_detection` package
- face_detection/ # source code of `face_detection` package
|-- __init__.py
|-- utils.py
|-- database.py
Expand All @@ -423,31 +423,42 @@ Carrying on, we will want to create a setup-script, `setup.py`, *in the same dir
|-- __init__.py
|-- calibration.py
|-- config.py
- tests/ # test-suite for `face_detection` package (to be run using pytest)
|-- conftest.py # optional configuration file for pytest
rsokl marked this conversation as resolved.
Show resolved Hide resolved
|-- test_utils.py
|-- test_database.py
|-- test_model.py
|-- camera/
|-- test_calibration.py
|-- test_config.py
```

A `tests/` directory can be included at the same directory level as `setup.py` and `face_detection/`.
This is the recommended structure for using [pytest](https://docs.pytest.org/en/latest/) as our test-runner.

<!-- #region -->
The bare bones build script for preparing your package for installation, `setup.py`, is as follows:

```python
# contents of setup.py
import setuptools
from setuptools import find_packages, setup

setuptools.setup(
setup(
name="face_detection",
version="1.0",
packages=setuptools.find_packages(),
version="1.0.0",
packages=find_packages(exclude=["tests", "tests.*"]),
python_requires=">=3.5",
)
```


The `exclude` expression is used to ensure that specific directories or files are not included in the installation of `face_detection`. We use `exclude=["tests", "tests.*"]` to avoid installing the test-suite alongside `face_detection`.
<!-- #endregion -->

If you read through the additional materials linked above, you will see that there are many more fields of optional information that can be provided in this setup script, such as the author name, any installation requirements that the package has, and more.

Armed with this script, we are ready to install our package locally on our machine! In your terminal, navigate to the directory containing this setup script and your package that it being installed. Run

```shell
python setup.py install
pip install .
```

and voilà, your package `face_detection` will have been installed to site-packages. You are now free to import this package from any directory on your machine. In order to uninstall this package from your machine execute the following from your terminal:
Expand All @@ -456,10 +467,10 @@ and voilà, your package `face_detection` will have been installed to site-packa
pip uninstall face_detection
```

One final but important detail. The installed version of your package will no longer "see" the source code. That is, if you go on to make any changes to your code, you will have to uninstall and reinstall your package before your will see the effects system-wide. Instead you can install your package in develop mode, such that a symbolic link to your source code is placed in your site-packages. Thus any changes that you make to your code will immediately be reflected in your system-wide installation. Thus, instead of running `python setup.py install`, execute the following to install a package in develop mode:
One final but important detail: the installed version of your package will no longer "see" the source code. That is, if you go on to make any changes to your code, you will have to uninstall and reinstall your package before your will see the effects system-wide. Instead, you can install your package in "development mode", such that a symbolic link to your source code is placed in your site-packages. Thus, any changes that you make to your code will immediately be reflected in your system-wide installation. You can add the `--editable` flag to pip to install a package in development mode:

```shell
python setup.py develop
pip install --editable .
```


Expand Down
12 changes: 7 additions & 5 deletions Python/Module5_OddsAndEnds/Writing_Good_Code.md
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ To be more concrete, let's revisit our `count_vowels` function:

```python
def count_vowels(x: str, include_y: bool = False) -> int:
"""Returns the number of vowels contained in `in_string`"""
"""Returns the number of vowels contained in `x`"""
vowels = set("aeiouAEIOU")
if include_y:
vowels.update("yY")
Expand Down Expand Up @@ -774,14 +774,16 @@ def pairwise_dists(x: np.ndarray, y: np.ndarray) -> np.ndarray:
Parameters
----------
x : numpy.ndarray, shape=(M, D)
An optional description of ``x``
An array of M, D-dimensional vectors.

y : numpy.ndarray, shape=(N, D)
An optional description of ``y``
An array of N, D-dimensional vectors.

Returns
-------
numpy.ndarray, shape=(M, N)
The pairwise distances
The pairwise distances between the M rows of ``x`` and the N
rows of ``y``.

Notes
-----
Expand Down Expand Up @@ -829,7 +831,7 @@ def compute_student_stats(grade_book: Dict[str, Iterable[float]],

Parameters
----------
grade_book : Dict[str, List[float]]
grade_book : Dict[str, Iterable[float]]
The dictionary (name -> grades) of all of the students'
grades.

Expand Down