Python: Add tests for bounce and bowling

This commit is contained in:
Martin Thoma
2022-03-23 11:44:46 +01:00
parent 0064fd328a
commit e66d2df028
4 changed files with 360 additions and 14 deletions

View File

@@ -6,7 +6,7 @@ A physics simulation
Ported by Dave LeCompte Ported by Dave LeCompte
""" """
from typing import Tuple from typing import Tuple, List
PAGE_WIDTH = 64 PAGE_WIDTH = 64
@@ -51,8 +51,8 @@ def print_at_tab(line: str, tab: int, s: str) -> str:
return line return line
def run_simulation(delta_t, v0, coeff_rest) -> None: def run_simulation(delta_t: float, v0: float, coeff_rest: float) -> None:
bounce_time = [0] * 20 # time of each bounce bounce_time: List[float] = [0] * 20 # time of each bounce
print("FEET") print("FEET")
print() print()
@@ -67,7 +67,7 @@ def run_simulation(delta_t, v0, coeff_rest) -> None:
line = "" line = ""
if int(h) == h: if int(h) == h:
line += str(int(h)) line += str(int(h))
total_time = 0 total_time: float = 0
for i in range(1, sim_dur + 1): for i in range(1, sim_dur + 1):
tm: float = 0 tm: float = 0
while tm <= bounce_time[i]: while tm <= bounce_time[i]:

View File

@@ -0,0 +1,72 @@
import io
from _pytest.monkeypatch import MonkeyPatch
from _pytest.capture import CaptureFixture
from bounce import main
def test_bounce(monkeypatch: MonkeyPatch, capsys: CaptureFixture[str]) -> None:
time_increment = 0.1
velocity = 30
coefficient = 1
monkeypatch.setattr(
"sys.stdin",
io.StringIO(f"{time_increment:0.1f}\n{velocity}\n{coefficient}\n"),
)
main()
actual = capsys.readouterr().out
expected = """ BOUNCE
CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
THIS SIMULATION LETS YOU SPECIFY THE INITIAL VELOCITY
OF A BALL THROWN STRAIGHT UP, AND THE COEFFICIENT OF
ELASTICITY OF THE BALL. PLEASE USE A DECIMAL FRACTION
COEFFICIENCY (LESS THAN 1).
YOU ALSO SPECIFY THE TIME INCREMENT TO BE USED IN
'STROBING' THE BALL'S FLIGHT (TRY .1 INITIALLY).
TIME INCREMENT (SEC)?
VELOCITY (FPS)?
COEFFICIENT?
FEET
14 000 000 000
0 0 0
13 0 0 0 0 0 0
12 0 0 0 0 0 0
11 0 0 0
0 0 0
10
0 0 0
9 0 0 0
8
0 0 0
7 0 0 0
6
0 0 0
5 0 0 0
4
3 0 0 0
2 0 0 0
1
00 0 0
...................................................................
0 1 2 3 4 5 6
SECONDS
""" # noqa: W291
assert actual.split("\n") == expected.split("\n")

View File

@@ -1,14 +1,15 @@
import random import random
from typing import List
def simulate_roll(pins) -> None: def simulate_roll(pins: List[int]) -> None:
for _ in range(20): for _ in range(20):
x = random.randint(0, 14) x = random.randint(0, 14)
if x < len(pins): if x < len(pins):
pins[x] = 1 pins[x] = 1
def calculate_score(rolls) -> int: def calculate_score(rolls: List[int]) -> int:
score = 0 score = 0
frame = 1 frame = 1
b = 1 b = 1
@@ -32,11 +33,11 @@ def calculate_score(rolls) -> int:
class Player: class Player:
def __init__(self, name): def __init__(self, name: str):
self.name = name self.name = name
self.rolls = [] self.rolls: List[int] = []
def play_frame(self, frame): def play_frame(self, frame: int) -> None:
extra = 0 extra = 0
prev_score = 0 prev_score = 0
pins = [0] * 10 # reset the pins pins = [0] * 10 # reset the pins
@@ -73,10 +74,10 @@ class Player:
score = sum(pins) score = sum(pins)
self.rolls.append(score) self.rolls.append(score)
def __str__(self): def __str__(self) -> str:
return f"{self.name}: {self.rolls}, total:{calculate_score(self.rolls)}" return f"{self.name}: {self.rolls}, total:{calculate_score(self.rolls)}"
def show(self, pins): def show(self, pins: List[int]) -> None:
pins_iter = iter(pins) pins_iter = iter(pins)
print() print()
for row in range(4): for row in range(4):
@@ -87,14 +88,14 @@ class Player:
print() print()
def centreText(text, width): def centre_text(text: str, width: int) -> str:
t = len(text) t = len(text)
return (" " * ((width - t) // 2)) + text return (" " * ((width - t) // 2)) + text
def main() -> None: def main() -> None:
print(centreText("Bowl", 80)) print(centre_text("Bowl", 80))
print(centreText("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY", 80)) print(centre_text("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY", 80))
print() print()
print("WELCOME TO THE ALLEY.") print("WELCOME TO THE ALLEY.")
print("BRING YOUR FRIENDS.") print("BRING YOUR FRIENDS.")

View File

@@ -0,0 +1,273 @@
import io
from typing import List
from _pytest.capture import CaptureFixture
from _pytest.monkeypatch import MonkeyPatch
from bowling import main
def test_bowling_strikes(monkeypatch: MonkeyPatch, capsys: CaptureFixture[str]) -> None:
def perfect_roll(pins: List[int]) -> None:
for i in range(20):
x = i
if x < len(pins):
pins[x] = 1
monkeypatch.setattr("bowling.simulate_roll", perfect_roll)
instructions1 = "Y"
players1 = 1
name1 = "Martin"
another_game1 = "Y"
instructions2 = "N"
players2 = 2
name21 = "Anna"
name22 = "Bob"
another_game2 = "N"
monkeypatch.setattr(
"sys.stdin",
io.StringIO(
f"{instructions1}\n{players1}\n{name1}\n{another_game1}\n"
f"{instructions2}\n{players2}\n{name21}\n{name22}\n{another_game2}"
),
)
main()
actual = capsys.readouterr().out
expected = """ Bowl
CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
WELCOME TO THE ALLEY.
BRING YOUR FRIENDS.
OKAY LET'S FIRST GET ACQUAINTED.
THE INSTRUCTIONS (Y/N)? THE GAME OF BOWLING TAKES MIND AND SKILL. DURING THE GAME
THE COMPUTER WILL KEEP SCORE. YOU MAY COMPETE WITH
OTHER PLAYERS[UP TO FOUR]. YOU WILL BE PLAYING TEN FRAMES.
ON THE PIN DIAGRAM 'O' MEANS THE PIN IS DOWN...'+' MEANS THE
PIN IS STANDING. AFTER THE GAME THE COMPUTER WILL SHOW YOUR
SCORES.
FIRST OF ALL...HOW MANY ARE PLAYING?
VERY GOOD...
Enter name for player 1:
O O O O
O O O
O O
O
10 for Martin
STRIKE!!!
O O O O
O O O
O O
O
10 for Martin
STRIKE!!!
O O O O
O O O
O O
O
10 for Martin
STRIKE!!!
O O O O
O O O
O O
O
10 for Martin
STRIKE!!!
O O O O
O O O
O O
O
10 for Martin
STRIKE!!!
O O O O
O O O
O O
O
10 for Martin
STRIKE!!!
O O O O
O O O
O O
O
10 for Martin
STRIKE!!!
O O O O
O O O
O O
O
10 for Martin
STRIKE!!!
O O O O
O O O
O O
O
10 for Martin
STRIKE!!!
O O O O
O O O
O O
O
10 for Martin
STRIKE!!!
Extra rolls for Martin
Martin: [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], total:300
DO YOU WANT ANOTHER GAME?
THE INSTRUCTIONS (Y/N)? FIRST OF ALL...HOW MANY ARE PLAYING?
VERY GOOD...
Enter name for player 1: Enter name for player 2:
O O O O
O O O
O O
O
10 for Anna
STRIKE!!!
O O O O
O O O
O O
O
10 for Bob
STRIKE!!!
O O O O
O O O
O O
O
10 for Anna
STRIKE!!!
O O O O
O O O
O O
O
10 for Bob
STRIKE!!!
O O O O
O O O
O O
O
10 for Anna
STRIKE!!!
O O O O
O O O
O O
O
10 for Bob
STRIKE!!!
O O O O
O O O
O O
O
10 for Anna
STRIKE!!!
O O O O
O O O
O O
O
10 for Bob
STRIKE!!!
O O O O
O O O
O O
O
10 for Anna
STRIKE!!!
O O O O
O O O
O O
O
10 for Bob
STRIKE!!!
O O O O
O O O
O O
O
10 for Anna
STRIKE!!!
O O O O
O O O
O O
O
10 for Bob
STRIKE!!!
O O O O
O O O
O O
O
10 for Anna
STRIKE!!!
O O O O
O O O
O O
O
10 for Bob
STRIKE!!!
O O O O
O O O
O O
O
10 for Anna
STRIKE!!!
O O O O
O O O
O O
O
10 for Bob
STRIKE!!!
O O O O
O O O
O O
O
10 for Anna
STRIKE!!!
O O O O
O O O
O O
O
10 for Bob
STRIKE!!!
O O O O
O O O
O O
O
10 for Anna
STRIKE!!!
Extra rolls for Anna
O O O O
O O O
O O
O
10 for Bob
STRIKE!!!
Extra rolls for Bob
Anna: [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], total:300
Bob: [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], total:300
DO YOU WANT ANOTHER GAME? """ # noqa: W291
assert actual.split("\n") == expected.split("\n")