-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add example code with advanced topic tests
- Loading branch information
1 parent
de4e9f2
commit 866bbba
Showing
7 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
python treasurehunt.py | ||
python -m doctest -v terrain_slope.py | ||
pytest -n auto -svv test_terrain_slope.py | ||
pytest -n auto -svv test_treasure_search.py | ||
pytest -n auto -svv test_hypothesis_slope.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import math | ||
|
||
|
||
def calculate_slope(a: tuple[float, float], b: tuple[float, float]) -> float: | ||
""" | ||
>>> calculate_slope((1.0, 0.0), (2.0, 0.0)) | ||
0.0 | ||
>>> calculate_slope((1.0, 0.0), (2.0, 1.0)) | ||
1.0 | ||
>>> calculate_slope((1.0, 0.0), (2.0, "mystring")) | ||
Traceback (most recent call last): | ||
File "<stdin>", line 1, in <module> | ||
File "/Users/ANDRLI/Project/tdd/treasurehunt.py", line 35, in calculate_slope | ||
return (b[1] - a[1]) / (b[0] - a[0]) | ||
TypeError: unsupported operand type(s) for -: 'str' and 'float' | ||
""" | ||
|
||
# (y2 - y1) / (x2 - x1) | ||
return (b[1] - a[1]) / (b[0] - a[0]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from unittest.mock import patch | ||
|
||
import pytest | ||
|
||
import treasurehunt | ||
|
||
|
||
@patch("treasurehunt.read_coordinates") | ||
def test_another_treasure(mock_read_coordinates): | ||
mock_read_coordinates.return_value = [ | ||
(0.0, 0.0), | ||
(1.0, 0.0), | ||
(2.0, 0.5), | ||
(3.0, 1.0), | ||
(4.0, 4.0), | ||
] | ||
|
||
point = treasurehunt.treasure_search() | ||
assert pytest.approx(point) == (4.0, 4.0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from hypothesis import given, reproduce_failure | ||
from hypothesis import strategies as st | ||
|
||
from treasurehunt import calculate_slope | ||
|
||
|
||
@given( | ||
st.floats(min_value=0.0, max_value=10.0), | ||
st.floats(min_value=0.0, max_value=10.0), | ||
st.floats(min_value=0.0, max_value=10.0), | ||
st.floats(min_value=0.0, max_value=10.0), | ||
) | ||
def test_that_calculate_slope_does_not_raise(_x1, _y1, _x2, _y2): | ||
calculate_slope((_x1, _y1), (_x2, _y2)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import pytest | ||
|
||
from terrain_slope import calculate_slope | ||
|
||
|
||
def test_simple_slopes(): | ||
assert pytest.approx(calculate_slope((1.0, 0.0), (2.0, 1.0))) == 1.0 | ||
assert pytest.approx(calculate_slope((1.0, 0.0), (2.0, 0.0))) == 0.0 | ||
assert pytest.approx(calculate_slope((1.0, 0.0), (2.0, -1.0))) == -1.0 | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"_x1, _y1, _x2, _y2, result", | ||
[ | ||
(1.0, 1.0, 2.0, 2.0, 1.0), | ||
(2.0, 3.0, 4.0, 4.0, 0.5), | ||
(1.0, 1.0, 2.0, 0.0, -1.0), | ||
(2.0, 4.0, 4.0, 3.0, -0.5), | ||
], | ||
) | ||
def test_input_slopes(_x1, _y1, _x2, _y2, result): | ||
assert pytest.approx(calculate_slope((_x1, _y1), (_x2, _y2))) == result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from pathlib import Path | ||
from typing import Union | ||
|
||
import pytest | ||
|
||
import treasurehunt | ||
|
||
|
||
def test_find_treasure(monkeypatch): | ||
def mock_read_coordinates(file_name: Union[str, Path]): | ||
return [(0.0, 0.0), (1.0, 0.0), (2.0, 2.0)] | ||
|
||
monkeypatch.setattr(treasurehunt, "read_coordinates", mock_read_coordinates) | ||
point = treasurehunt.treasure_search() | ||
assert pytest.approx(point) == (2.0, 2.0) | ||
|
||
|
||
def test_find_treasure_raises_on_flat_ground(monkeypatch): | ||
def mock_read_coordinates(file_name: Union[str, Path]): | ||
return [(0.0, 0.0), (1.0, 0.0), (2.0, 0.0)] | ||
|
||
monkeypatch.setattr(treasurehunt, "read_coordinates", mock_read_coordinates) | ||
|
||
with pytest.raises(RuntimeError, match="Cannot find treasure"): | ||
treasurehunt.treasure_search() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from pathlib import Path | ||
from typing import List, Tuple, Union | ||
|
||
from terrain_slope import calculate_slope | ||
|
||
|
||
def read_coordinates(file_name: Union[str, Path]) -> List[Tuple[float, float]]: | ||
""" | ||
Will read a file of comma separated strings and turn it | ||
into a list | ||
""" | ||
coordinates = [] | ||
with open(file_name, "r", encoding="utf-8") as input_file: | ||
for line in input_file: | ||
_x, _y = line.strip().split(",") | ||
coordinates.append((float(_x), float(_y))) | ||
return sorted(coordinates) | ||
|
||
|
||
def treasure_search() -> Tuple[float, float]: | ||
""" | ||
Loads a treasure map, and step by step calculates the slope | ||
to find the treasure (if any) and returns (x, y) of that point | ||
""" | ||
treasure_map_file = "../../maps/treasure_map_1.txt" | ||
treasure_map = read_coordinates(treasure_map_file) | ||
previous_pos = None | ||
|
||
for current_pos in treasure_map: | ||
if previous_pos: | ||
slope = calculate_slope(previous_pos, current_pos) | ||
|
||
if slope >= 1.0: | ||
print(f"Found treasure at ({current_pos[0]}, {current_pos[1]})") | ||
return current_pos | ||
|
||
previous_pos = current_pos | ||
|
||
raise RuntimeError("Cannot find treasure") | ||
|
||
|
||
def main(): | ||
treasure_search() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |