Start by setting up a development branch for this issue.
Something isn't quite right with the GPT generated code!
I asked Phind to help me:
create a basic unittest that will test the rps-game.py script
Its suggested a complete rewrite - and lost track op the purpose.
>To create a basic unit test for the `rps-game.py` script, you'll first need to refactor the `Hand` class methods into functions that can be imported and tested independently. Then, you can write tests using Python's built-in `unittest` framework.
>
>### Step 1: Refactor `rps-game.py`
>
>First, let's refactor the `Hand` class to separate the logic into functions that can be easily tested. We'll move the `play` method outside of the `Hand` class and adjust it accordingly.
>
>**Refactored `rps-game.py`:**
>
>```python
>import random
>
>def get_outcomes():
> return {
> "paper": ["rock"],
> "scissors": ["paper"],
> "rock": ["scissors"]
> }
>
>def determine_opponent(hand):
> return random.choice(["paper", "scissors", "rock"])
>
>def check_win(player_hand, opponent_hand):
> outcomes = get_outcomes()
> if opponent_hand in outcomes[player_hand]:
> return True
> elif player_hand == opponent_hand:
> return False
> else:
> return False
>
>def play_game(player_hand, opponent_hand):
> if check_win(player_hand, opponent_hand):
> return f"{player_hand} wins against {opponent_hand}!"
> elif player_hand == opponent_hand:
> return f"It's a tie Both {player_hand} and {opponent_hand} played."
> else:
> return f"{opponent_hand} wins against {player_hand}."
>```
But I stopped it, since it had completely gotten rid of my Hand class. So I clarified:
Please refactor the rps_game.py scripts with respect for the Hand class - I'd like to keep that
And this time it looks like we're on to something:
Certainly Let's refactor the rps_game.py script to maintain the Hand class while making it easier to test. We'll introduce a method within the Hand class to encapsulate the logic for determining the outcome of a game, which can then be tested separately.
Refactored rps_game.py:
import argparse
import random
class Hand:
def __init__(self, name):
self.name = name
def play(self, opponent):
outcomes = {
"paper": ["rock"],
"scissors": ["paper"],
"rock": ["scissors"]
}
if opponent in outcomes[self.name]:
return f"{self.name} wins against {opponent}!"
elif self.name == opponent:
return f"It's a tie Both {self.name} and {opponent} played."
else:
return f"{opponent} wins against {self.name}."
def choose_random_hand():
return Hand(random.choice(["paper", "scissors", "rock"]))
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Play a game of Rock, Paper, Scissors.")
parser.add_argument("--hand", type=str, choices=["paper", "scissors", "rock"], help="Your hand ('paper', 'scissors', or 'rock')")
args = parser.parse_args()
script_hand = choose_random_hand()
print(f"You chose: {args.hand}")
print(f"The script chose: {script_hand.name}")
print(script_hand.play(args.hand))
Explanation:
The Hand class now includes a play method that takes an opponent's hand as an argument. This method returns the outcome of the game between the two hands.
A new function choose_random_hand is introduced to select a random hand for the script, keeping the logic separate from the main execution flow.
The argparse part remains unchanged, allowing the user to input their choice via command-line arguments.
Testing the Hand Class:
With the Hand class refactored, we can now write tests specifically for the play method. Assuming you have the unittest module available, here's how you could structure a test case:
Test file: test_hand.py:
import unittest
from src.rps_game import Hand
class TestHand(unittest.TestCase):
def setUp(self):
self.paper = Hand('paper')
self.scissors = Hand('scissors')
self.rock = Hand('rock')
def test_paper_vs_rock(self):
outcome = self.paper.play("rock")
self.assertEqual(outcome, "paper wins against rock!")
def test_scissors_vs_paper(self):
outcome = self.scissors.play("paper")
self.assertEqual(outcome, "scissors wins against paper!")
def test_rock_vs_scissors(self):
outcome = self.rock.play("scissors")
self.assertEqual(outcome, "rock wins against scissors!")
def test_tie(self):
outcome = self.rock.play("rock")
self.assertEqual(outcome, "It's a tie Both rock and rock played.")
if __name__ == '__main__':
unittest.main()
Running the Tests:
To run the tests, execute the following command in your terminal:
pipenv run python -m unittest tests/test_hand.py
This setup allows you to test the Hand class's behavior in isolation, ensuring that each hand behaves correctly according to the rules of Rock, Paper, Scissors.
Follow the instructions from Phind:
Replace the script with it's new content and add the unit test, put it in a tests folder
NOTE: Phind gets way more credit than justified here - I fixed quite a few skews, so I've cheated a bit and the output you see above on rps_game.py and test_hand.py are not exactly what Phind suggested. But close'ish.
ALSO NOTE: You need to have an empty file __init__.py in both the root directory and the src directory for this to work.
Wrap up your development branch and deliver to main
Start by setting up a development branch for this issue.
Something isn't quite right with the GPT generated code!
I asked Phind to help me:
Its suggested a complete rewrite - and lost track op the purpose.
>To create a basic unit test for the `rps-game.py` script, you'll first need to refactor the `Hand` class methods into functions that can be imported and tested independently. Then, you can write tests using Python's built-in `unittest` framework. > >### Step 1: Refactor `rps-game.py` > >First, let's refactor the `Hand` class to separate the logic into functions that can be easily tested. We'll move the `play` method outside of the `Hand` class and adjust it accordingly. > >**Refactored `rps-game.py`:** > >```python >import random > >def get_outcomes(): > return { > "paper": ["rock"], > "scissors": ["paper"], > "rock": ["scissors"] > } > >def determine_opponent(hand): > return random.choice(["paper", "scissors", "rock"]) > >def check_win(player_hand, opponent_hand): > outcomes = get_outcomes() > if opponent_hand in outcomes[player_hand]: > return True > elif player_hand == opponent_hand: > return False > else: > return False > >def play_game(player_hand, opponent_hand): > if check_win(player_hand, opponent_hand): > return f"{player_hand} wins against {opponent_hand}!" > elif player_hand == opponent_hand: > return f"It's a tie Both {player_hand} and {opponent_hand} played." > else: > return f"{opponent_hand} wins against {player_hand}." >```But I stopped it, since it had completely gotten rid of my
Hand
class. So I clarified:And this time it looks like we're on to something:
Follow the instructions from Phind:
Replace the script with it's new content and add the unit test, put it in a
tests
folderNOTE: Phind gets way more credit than justified here - I fixed quite a few skews, so I've cheated a bit and the output you see above on
rps_game.py
andtest_hand.py
are not exactly what Phind suggested. But close'ish.ALSO NOTE: You need to have an empty file
__init__.py
in both the root directory and thesrc
directory for this to work.Wrap up your development branch and deliver to
main