Refurbish chapter 02

- streamline text
- streamline example functions
- move section on built-ins to beginning
- add notes on the concept of a callable
This commit is contained in:
Alexander Hess 2020-02-05 18:31:52 +01:00
parent 3bbcc3a04d
commit 3754297c93
4 changed files with 1639 additions and 715 deletions

File diff suppressed because it is too large Load diff

View file

@ -67,7 +67,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q3**: What does it mean for a variable to **go out of scope**?"
"**Q3**: What does it mean for a variable to go out of **scope**?"
]
},
{
@ -95,7 +95,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q5**: Explain the concept of **forwarding** a function **call**."
"**Q5**: Explain the concept of **forwarding** a **function call**."
]
},
{
@ -119,6 +119,20 @@
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q7**: What are **callables**? How do they relate to `function` objects?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
@ -137,7 +151,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q7**: A mere function **call** is just an **expression**."
"**Q8**: A mere function **call** is just an **expression**."
]
},
{
@ -151,7 +165,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q8**: When using the `import` statement, we need to ensure that the imported attributes do **not** overwrite any already defined variables and functions."
"**Q9**: When using the `import` statement, we need to ensure that the imported attributes do *not* overwrite any already defined variables and functions."
]
},
{
@ -165,7 +179,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q9:** Functions always have a name by which we can call them."
"**Q10:** Functions always have a name by which we can call them."
]
},
{
@ -179,7 +193,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q10**: The [standard library](https://docs.python.org/3/library/index.html) is a collection of numerical tools often used in scientific computing, for example, advanced mathematical functions or utilities for simulation."
"**Q11**: The [standard library](https://docs.python.org/3/library/index.html) is a collection of numerical tools often used in scientific computing, for example, advanced mathematical functions or utilities for simulation."
]
},
{

View file

@ -32,7 +32,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q1.1**: The [volume of a sphere](https://en.wikipedia.org/wiki/Sphere) is defined as $\\frac{4}{3} * \\pi * r^3$. Calculate this value for $r=10.0$ and round it to 10 digits after the comma. Use the [standard library](https://docs.python.org/3/library/index.html) to obtain a good approximation of $\\pi$."
"**Q1**: The [volume of a sphere](https://en.wikipedia.org/wiki/Sphere) is defined as $\\frac{4}{3} * \\pi * r^3$. Calculate this value for $r=10.0$ and round it to 10 digits after the comma. Use the [standard library](https://docs.python.org/3/library/index.html) to obtain a good approximation of $\\pi$."
]
},
{
@ -66,7 +66,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q1.2**: Encapsulate the logic into a function `sphere_volume()` that takes one *positional* argument `radius` and one *keyword-only* argument `digits` defaulting to `5`. The volume should be returned as a `float` object under *all* circumstances. Document your work appropriately in a docstring according to [Google's Python Style Guide](https://github.com/google/styleguide/blob/gh-pages/pyguide.md)."
"**Q2**: Encapsulate the logic into a function `sphere_volume()` that takes one *positional* argument `radius` and one *keyword-only* argument `digits` defaulting to `5`. The volume should be returned as a `float` object under *all* circumstances. Document your work appropriately in a docstring according to [Google's Python Style Guide](https://github.com/google/styleguide/blob/gh-pages/pyguide.md)."
]
},
{
@ -83,7 +83,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q1.3**: Evaluate the function with `radius = 100.0` and 1, 5, 10, 15, and 20 digits respectively."
"**Q3**: Evaluate the function with `radius = 100.0` and 1, 5, 10, 15, and 20 digits respectively."
]
},
{
@ -144,7 +144,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q1.4**: What observation do you make?"
"**Q4**: What observation do you make?"
]
},
{
@ -158,7 +158,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q1.5**: Using the [range()](https://docs.python.org/3/library/functions.html#func-range) built-in, write a `for`-loop and calculate the volume of a sphere with `radius = 42.0` for all `digits` from `1` through `20`. Print out each volume on a separate line.\n",
"**Q5**: Using the [range()](https://docs.python.org/3/library/functions.html#func-range) built-in, write a `for`-loop and calculate the volume of a sphere with `radius = 42.0` for all `digits` from `1` through `20`. Print out each volume on a separate line.\n",
"\n",
"Note: This is the first task where you need to use the built-in [print()](https://docs.python.org/3/library/functions.html#print) function."
]
@ -186,7 +186,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Q1.6**: What lesson do you learn about the `float` type?"
"**Q6**: What lesson do you learn about the `float` type?"
]
},
{

View file

@ -15,16 +15,17 @@ be used outside the module with a single underscore "_". This way, we can
design the code within a module in a modular fashion and only "export" what we
want.
Here, all three functions internally forward the computation to an internal
utility function _scaled_average() that contains all the logic common to the
three functions. Also, we define one _default_scalar variable that is used as
the default for the scalar parameter in each of the functions.
Here, all three functions internally forward parts of their computations
to the utility functions _round_all() and _scaled_average() that contain all
the logic common to the three functions.
While this example is stylized, it shows how Python modules are often
designed.
"""
_default_scalar = 1
def _round_all(numbers):
"""Internal utility function to round all numbers in a list."""
return [round(n) for n in numbers]
def _scaled_average(numbers, scalar):
@ -33,43 +34,43 @@ def _scaled_average(numbers, scalar):
return scalar * average
def average(numbers, *, scalar=_default_scalar):
def average(numbers, *, scalar=1):
"""Calculate the average of all numbers in a list.
Args:
numbers (list): list of numbers; may be integers or floats
scalar (float, optional): the scalar that multiplies the
average of the even numbers
numbers (list of int's/float's): numbers to be averaged;
if non-whole numbers are provided, they are rounded
scalar (float, optional): multiplies the average; defaults to 1
Returns:
float: (scaled) average
"""
return _scaled_average(numbers, scalar)
return _scaled_average(_round_all(numbers), scalar)
def average_evens(numbers, *, scalar=_default_scalar):
def average_evens(numbers, *, scalar=1):
"""Calculate the average of all even numbers in a list.
Args:
numbers (list): list of numbers; may be integers or floats
scalar (float, optional): the scalar that multiplies the
average of the even numbers
numbers (list of int's/float's): numbers to be averaged;
if non-whole numbers are provided, they are rounded
scalar (float, optional): multiplies the average; defaults to 1
Returns:
float: (scaled) average
"""
return _scaled_average([n for n in numbers if n % 2 == 0], scalar)
return _scaled_average([n for n in _round_all(numbers) if n % 2 == 0], scalar)
def average_odds(numbers, *, scalar=_default_scalar):
def average_odds(numbers, *, scalar=1):
"""Calculate the average of all odd numbers in a list.
Args:
numbers (list): list of numbers; may be integers or floats
scalar (float, optional): the scalar that multiplies the
average of the even numbers
numbers (list of int's/float's): numbers to be averaged;
if non-whole numbers are provided, they are rounded
scalar (float, optional): multiplies the average; defaults to 1
Returns:
float: (scaled) average
"""
return _scaled_average([n for n in numbers if n % 2 != 0], scalar)
return _scaled_average([n for n in _round_all(numbers) if n % 2 != 0], scalar)