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
9 changes: 6 additions & 3 deletions episodes/06-floating-point-data.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ places. This can be affected by:

- Choice of algorithm.
- Precise order of operations.
- Order in which parallel processes finish.
- Inherent randomness in the calculation.

We could therefore test our code using `assert result == 2.34958124890e-31`,
Expand All @@ -54,8 +53,8 @@ it is best to use a _relative_ tolerance:
from math import fabs

def test_float_rtol():
actual = my_function()
expected = 7.31926e12 # Reference solution
actual = my_function()
rtol = 1e-3
# Use fabs to ensure a positive result!
assert fabs((actual - expected) / expected) < rtol
Expand All @@ -69,8 +68,8 @@ tolerance:
from math import fabs

def test_float_atol():
actual = my_function()
expected = 0.0 # Reference solution
actual = my_function()
atol = 1e-5
# Use fabs to ensure a positive result!
assert fabs(actual - expected) < atol
Expand All @@ -90,6 +89,10 @@ inefficiently!).
import random

def estimate_pi(iterations):
"""
Estimate pi by counting the number of random points
inside a quarter circle of radius 1
"""
num_inside = 0
for _ in range(iterations):
x = random.random()
Expand Down
19 changes: 10 additions & 9 deletions episodes/08-parametrization.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ This test is quite long and repetitive. We can use parametrization to make it mo
import pytest

@pytest.mark.parametrize(
("p1x, p1y, p2x, p2y, p3x, p3y, expected"),
"p1x, p1y, p2x, p2y, p3x, p3y, expected",
[
pytest.param(0, 0, 2, 0, 1, 1.7320, 1.7320, id="Equilateral triangle"),
pytest.param(0, 0, 2, 0, 1, 1.732, 1.732, id="Equilateral triangle"),
pytest.param(0, 0, 3, 0, 0, 4, 6, id="Right-angled triangle"),
pytest.param(0, 0, 4, 0, 2, 8, 16, id="Isosceles triangle"),
pytest.param(0, 0, 3, 0, 1, 4, 6, id="Scalene triangle"),
Expand All @@ -119,13 +119,14 @@ Let's have a look at how this works.

Similar to how fixtures are defined, the `@pytest.mark.parametrize` line is a decorator, letting pytest know that this is a parametrized test.

- The first argument is a tuple, a list of the names of the parameters you want to use in your test. For example
`("p1x, p2y, p2x, p2y, p3x, p3y, expected")` means that we will use the parameters `p1x`, `p1y`, `p2x`, `p2y`, `p3x`, `p3y` and `expected` in our test.
- The first argument is a string listing the names of the parameters you want to use in your test. For example
`"p1x, p2y, p2x, p2y, p3x, p3y, expected"` means that we will use the parameters `p1x`, `p1y`, `p2x`, `p2y`, `p3x`, `p3y` and `expected` in our test.

- The second argument is a list of `pytest.param` objects. Each `pytest.param` object is a tuple of the values you want to test, with an optional `id` argument to give a name to the test.
For example, `pytest.param(0, 0, 2, 0, 1, 1.7320, 6, id="Equilateral triangle")` means that we will test the function with the parameters `0, 0, 2, 0, 1, 1.7320, 6` and give it the name "Equilateral triangle".
- The second argument is a list of `pytest.param` objects. Each `pytest.param` object contains the values you want to test, with an optional `id` argument to give a name to the test.

(note that if the test fails you will see the id in the output, so it's useful to give them meaningful names to help you understand what went wrong.)
For example, `pytest.param(0, 0, 2, 0, 1, 1.732, 1.732, id="Equilateral triangle")` means that we will test the function with the parameters `0, 0, 2, 0, 1, 1.732, 1.732` and give it the name "Equilateral triangle".

Note that if the test fails you will see the id in the output, so it's useful to give them meaningful names to help you understand what went wrong.

- The test function will be run once for each set of parameters in the list.

Expand All @@ -135,7 +136,7 @@ This is a much more concise way to write tests for functions that need to be tes

::::::::::::::::::::::::::::::::::::: challenge

## Challenge - Practice with Parametrization
## Practice with Parametrization

Add the following function to `advanced/advanced_calculator.py` and write a parametrized test for it in `tests/test_advanced_calculator.py` that tests the function with a range of different inputs
using parametrization.
Expand All @@ -158,7 +159,7 @@ def is_prime(n: int) -> bool:
import pytest

@pytest.mark.parametrize(
("n, expected"),
"n, expected",
[
pytest.param(0, False, id="0 is not prime"),
pytest.param(1, False, id="1 is not prime"),
Expand Down
Loading