How to patch multiple repeated inputs in python unit test? - python

I'm trying to unit test a function that can have multiple repeated inputs from within a while statement:
def ask_yes_or_no(prompt):
while True:
answer = input(prompt)
if answer.capitalize()[0] == 'Y':
return True
elif answer.capitalize()[0] == 'N':
return False
def human_move(computer_score, human_score):
total = 0
roll_again = True
while roll_again:
if ask_yes_or_no('Roll again? '):
points = roll()
print('You rolled a ' + str(points))
if points == 1:
total = 0
roll_again = False
else:
total += points
else:
roll_again = False
So far I've used the mock module with a with statement to simulate the input. e.g.:
def test_human_move(self):
random.seed(900)
with unittest.mock.patch('builtins.input', return_value = 'N'):
self.assertEqual(human_move(0,0), 0)
However this only works for a single one time input. Is there a way to simulate a repeated input> For instance if the user input ('Y', 'Y', 'Y', 'N')?
Sorry if that's not a very clear explanation.
Thanks.

Related

Can I add two VALUES to a dictionary from user input?

I keep getting an error when I run this functions. Everything goes through and then it shows this error. I have tried adding .items() to the end when I print the dictionary and still throws this error.
CLARIFICATION just realized. Not getting any type errors or anything. It prints fine but when doesn't add the second variable to the dictionary. Instead it prints this..
{'Frappe': ('small', function type_of_milk at 0x000002BE2BCD2F78>)}
def order():
ready_to_order = True
while ready_to_order != False:
ordering_q = input(
"""Do you know what you would like to order or do you need to see the menu?
[M]enu or [R]eady to order or [Q]uit: """)
if ordering_q.upper() == "Q":
sys.exit()
elif ordering_q.upper() == "M":
print(Menu())
elif ordering_q.upper() == "R":
ready_to_order = False
else:
print("Please enter valid letters only, try again.")
print(" ")
print(" ")
add_cart = True
while add_cart != False:
order1 = input("What would you like to order?")
if order1.upper() == "Done":
add_cart = False
elif order1 == 'a1':
print("Frappe added to cart")
global total_order
total_order += 3
drink_size()
type_of_milk()
order_dict['Frappe'] = (drink_sizes, type_of_milk)
add_cart = False
print(order_dict)
This line:
order_dict['Frappe'] = (drink_sizes, type_of_milk)
is adding the function type_of_milk to your dict, which is why you see function type_of_milk at 0x000002BE2BCD2F78> when you print the dict out. Maybe you meant to say type_of_milk()?

making tic tac toe, code is complete without error messages but wont run?

This is my first project, I used a lot of resources from others with the same project and this is what I have come up with. I am using Jupyter notebook. I am not getting any more error messages in my code, but for some reason I can't get it to run? Also, any advice or improvements in my code would also be appreciated.
I've tried to just call the tic_tac_toe() command but nothing comes up and I'm not sure why.
def tic_tac_toe():
brd = [None] + list(range(1,10))
end = False
winner = ((1,2,3),(4,5,6),(7,8,9),(1,4,7),(2,5,8),(3,6,9),(1,5,9), (3,5,7))
from IPython.display import clear_output
def show_board():
print(brd[1]+'|'+brd[2]+'|'+brd[3])
print(brd[4]+'|'+brd[5]+'|'+brd[6])
print(brd[7]+'|'+brd[8]+'|'+brd[9])
print()
def player_input():
marker = ''
while marker != 'x' and marker != 'o':
marker = input('Do you want to be x or o?: ')
player1 = marker
if player1 == 'x':
player2 ='o'
else:
player2 = 'x'
player_markers = [player1,player2]
def choose_number():
while True:
try:
val = int(input())
if val in brd:
return val
else:
print('\n Please choose another number')
except ValueError:
print('\n Please choose another number')
def game_over():
for a, b, c in winner:
if brd[a] == brd[b] == brd[c]:
print("{0} wins!\n".format(board[a]))
print("Congrats\n")
return True
if 9 == sum((pos == 'x' or pos == 'o') for pos in board):
print("The game ends in a tie\n")
return True
for player in 'x' or 'o' * 9:
draw()
if is_game_over():
break
print("{0} pick your move".format(player))
brd[choose_number()] = player
print()
while True:
tac_tac_toe()
if input("Play again (y/n)\n") != "y":
break
I'm not sure why it is not running normally.
There's a couple things wrong with your code here. Your indentation for one. Also wondering why your functions are all in another function. You also create a bunch of functions but never call most of them. And have some functions that do not seem to exist. There are also a lot of logic errors here and there.
Try this instead:
# numpy is a package that has a lot of helpful functions and lets you manipulate
# numbers and arrays in many more useful ways than the standard Python list allows you to
import numpy as np
def show_board(brd):
print(brd[0]+'|'+brd[1]+'|'+brd[2])
print(brd[3]+'|'+brd[4]+'|'+brd[5])
print(brd[6]+'|'+brd[7]+'|'+brd[8])
print()
def player_input():
marker = ''
while marker != 'x' and marker != 'o':
marker = input('Do you want to be x or o?: ')
player1 = marker
if player1 == 'x':
player2 ='o'
else:
player2 = 'x'
player_markers = [player1,player2]
return player_markers
def choose_number(brd):
while True:
try:
val = int(input())
if brd[val-1] == "_":
return val
else:
print('\nNumber already taken. Please choose another number:')
except ValueError:
print('\nYou did not enter a number. Please enter a valid number:')
def is_game_over(winner, brd):
for a, b, c in winner:
if brd[a] != "_" and (brd[a] == brd[b] == brd[c]):
print("{} wins!\n".format(brd[a]))
print("Congrats\n")
return True
if 9 == sum((pos == 'x' or pos == 'o') for pos in brd):
print("The game ends in a tie\n")
return True
# I split this function in two because the "is_game_over" code was included here
# instead of being by itself.
def game_over(winner, brd, player_markers):
last = 0
# The first player is the one stored in "player_markers[0]"
player = player_markers[0]
# There are nine turns so that is what this is for. It has nothing to do with
# 'x' or 'o'. And one more turn is added for the "is_game_over" to work in
# case of a tie.
for i in range(10):
if is_game_over(winner, brd):
break
print()
print("{0} pick your move [1-9]:".format(player))
brd[choose_number(brd)-1] = player
show_board(brd)
# This is added to change from one player to another
# by checking who was the last one (look up ternary operators)
player = player_markers[1] if last==0 else player_markers[0]
last = 1 if last==0 else 0
def tic_tac_toe():
brd = ["_"] * 9
end = False
winner = ((1,2,3),(4,5,6),(7,8,9),(1,4,7),(2,5,8),(3,6,9),(1,5,9),(3,5,7))
winner = np.array([list(elem) for elem in winner]) - 1
player_markers = player_input()
show_board(brd)
game_over(winner, brd, player_markers)
while True:
tic_tac_toe()
if input("Play again (y/n)\n") != "y":
break

Score function for a flashcard game in python

I am trying to add a very simple score function to an also very simple flashcard game and I can't make the game remember the value of the variable containing the score (it always resets it 0). The score is obviously relying on the honesty of the user (and that's fine) that has to press "Y" when guessing the word.
from random import *
def add_score():
pos_score = 0
score = input("Press Y if you got the correct word or N if you got it wrong!" )
if score == 'Y':
pos_score += 1
print(pos_score)
def show_flashcard():
""" Show the user a random key and ask them
to define it. Show the definition
when the user presses return.
"""
random_key = choice(list(glossary))
print('Define: ', random_key)
input('Press return to see the definition')
print(glossary[random_key])
def add_flashcard():
""" This function allows the user to add a new
word and related value to the glossary. It will
be activated when pressing the "a" button.
"""
key = input("Enter the new word: ")
value = input("Enter the definition: ")
glossary[key] = value
print("New entry added to glossary.")
# Set up the glossary
glossary = {'word1':'definition1',
'word2':'definition2',
'word3':'definition3'}
# The interactive loop
exit = False
while not exit:
user_input = input('Enter s to show a flashcard, a to add a new card. or q to quit: ')
if user_input == 'q':
exit = True
elif user_input == 's':
show_flashcard()
add_score()
elif user_input == 'a':
add_flashcard()
else:
print('You need to enter either q, a or s.')
Some notes:
I am aware that right now only the positive score is implemented in the code, but I figured it would be better to proceed step by step and have that working first.
Problem
In your def add_score(), you initialise the variable to 0 every time. Also, it is a local variable, which means you can only reference it from within your function add_score(). This means that every time you exit that function, that variable is completely deleted.
Solution
You need to make that a global variable, that is, initialise it to 0 at the start of the game, and outside your function. Then inside your add_score you simply reference to the global variable and increase it without initialising it every time:
from random import *
def add_score():
score = input("Press Y if you got the correct word or N if you got it wrong!" )
if score == 'Y':
global pos_score
pos_score += 1
print(pos_score)
# Set up the glossary
glossary = {'word1':'definition1',
'word2':'definition2',
'word3':'definition3'}
# The interactive loop
pos_score = 0 #NOTE you initialise it here as a global variable
exit = False
while not exit:
user_input = input('Enter s to show a flashcard, a to add a new card. or q to quit: ')
if user_input == 'q':
exit = True
elif user_input == 's':
show_flashcard()
add_score()
elif user_input == 'a':
add_flashcard()
else:
print('You need to enter either q, a or s.')
Note I skipped the irrelevant functions. However, usually changing the scope of variables like this is considered bad practice. What you should do is either have a class -- a bit overly complicated for this example -- or return a value to add from your add_score and add that value in the main loop. This would be the code:
from random import *
def add_score():
score = input("Press Y if you got the correct word or N if you got it wrong!" )
if score == 'Y':
#global pos_score
#pos_score += 1
#print(pos_score)
return 1
return 0
def show_flashcard():
""" Show the user a random key and ask them
to define it. Show the definition
when the user presses return.
"""
random_key = choice(list(glossary))
print('Define: ', random_key)
input('Press return to see the definition')
print(glossary[random_key])
def add_flashcard():
""" This function allows the user to add a new
word and related value to the glossary. It will
be activated when pressing the "a" button.
"""
key = input("Enter the new word: ")
value = input("Enter the definition: ")
glossary[key] = value
print("New entry added to glossary.")
# Set up the glossary
glossary = {'word1':'definition1',
'word2':'definition2',
'word3':'definition3'}
# The interactive loop
pos_score = 0 #NOTE you initialise it here as a global variable
exit = False
while not exit:
user_input = input('Enter s to show a flashcard, a to add a new card. or q to quit: ')
if user_input == 'q':
exit = True
elif user_input == 's':
show_flashcard()
pos_score += add_score()
print(pos_score)
elif user_input == 'a':
add_flashcard()
else:
print('You need to enter either q, a or s.')

Python(3.6)-How can I create a demo program that will create an object from the VotingMachine class I have created?

This is what I have so far. I have created this class:
class VotingMachine :
def __init__(self):
self._voteCount = 0
self._totalVote = 0
def DemVote(self, vote):
self._voteDemCount = self._voteDemCount + 1
self._totalDemVote = self._totalDemVote + vote
def RepVote(self, vote):
self._voteRepCount = self._voteRepCount + 1
self._totalRepVote = self._totalRepVote + 1
def getDemTally(self):
return self._totalDemVote
def getRepTally(self):
return self._totalRepVote
def clear(self):
self._voteCount = 0
self._totalVote = 0
and this is what I have so far for the demo program.
from votingmachine import VotingMachine
print("Presidential Election")
print("---------------------")
print("R -- Republican")
print("D -- Democrat")
print("X -- Stop")
userInput = input("Enter your vote (R/D/X): ")
My instructions for this are as follows-
Create a voteDemo program that will create one object from the VotingMachine class. The voteDemo program should display a menu, allow the user to enter multiple votes until an X is entered, then show the tally of the Democratic and Republican votes, and also show which candidate won the election.
Make sure to consider that the election could end in a tie.
I know I have probably missed something really simple, but I am a complete beginner at this and do not understand how to go about calling the methods to be able to display a menu, etc. I would really appreciate it if someone would take the time to explain what I need to do to finish this up.
To complete this assignment you need to know how to:
Compare strings
first = "a"
second = "b"
third = "b"
print(first == second) # prints False
print(second == third) # prints True
Use a while loop. For example:
looping = True
while looping:
userInput = input("Press X to leave the loop")
if userInput == "X":
looping = False
print("Left the while loop")
Call methods
class Animal:
def __init__(self):
print("Creating animal")
def make_sound(self, sound):
print("Making a sound...")
print(sound)
# Create an instance of the Animal class.
animal = Animal()
# Call a method. The self parameter implicitly refers to the instance, animal.
animal.make_sound("meow")
You can solve the problem by combining these tools.
Here's a simple loop to do what you want:
userInput = ''
voting_machine = VotingMachine()
while userInput != 'x':
userInput = input("Enter your vote (R/D/X): ").lower()
if userInput == 'd':
pass
elif userInput == 'r':
pass
elif userInput == 'x':
break
else:
print("Wrong input! Try again!")
print(voting_machine.getDemTally())
print(voting_machine.getRepTally())
print("Bye!")
Actually, the definition of your class, has some errors, you didn't define attributes like _voteRepCount before using them.
You can instantiate (create a instance of) a class in python with the following code: machine = VotingMachine().
You might also want to check the code in your DemVote and RepVote methods. self._voteDemCount and self._voteRepCount need to be initialized in your __init__ function and the methods do different things with vote.
Instantiate a voting machine: machine = VotingMachine().
Then run a loop, asking for a vote, feeding it to the machine, and showing the tallies in each iteration.
class VotingMachine:
def __init__(self):
self._totalVote = 0
self._voteDemCount = 0
self._voteRepCount = 0
def demVote(self):
self._voteDemCount += 1
self._totalVote += 1
def repVote(self):
self._voteRepCount += 1
self._totalVote += 1
def getDemTally(self):
return self._voteDemCount
def getRepTally(self):
return self._voteRepCount
def getTally(self):
return self._totalVote
def clear(self):
self._totalVote = 0
voteDemo
from VotingMachine import *
election = VotingMachine()
print("Presidential Election")
vote = ''
while vote != 'X':
print("---------------------")
print("R -- Republican")
print("D -- Democrat")
print("X -- Stop")
vote = input("Enter your vote (R/D/X): ")
if vote == 'X':
print("Tally votes: "+str(election.getTally()))
if election.getDemTally() > election.getRepTally():
print("Democrat WIN")
elif election.getDemTally() < election.getRepTally():
print("Republican WIN")
else:
print("Draw")
print("(D:"+str(election.getDemTally())+" , R:"+str(election.getRepTally())+")")
elif vote == 'R':
election.repVote()
elif vote == 'D':
election.demVote()
else:
print("Vote invalid!")

How to pull a variable from one function to another

def letterChoice():
playerLetter = input('Please choose X or O.').upper()
if playerLetter in ['X','O']:
print('The game will now begin.')
while playerLetter not in ['X','O']:
playerLetter = input('Choose X or O.').upper()
if playerLetter == 'X':
computerLetter = 'O'
else:
computerLetter = 'X'
turnChooser()
def turnChooser():
choice = input("Would you like to go first, second or decide by coin toss?(enter 1, 2 or c) ")
while choice not in ["1","2","c"]:
choice = input("Please enter 1, 2 or c. ")
if choice == 1:
print("G")
cur_turn = letterChoice.playerLetter()
elif choice == 2:
print("H")
else:
print("P")
moveTaker()
I can't figure out how I'm supposed to inherit playerLetter into turnChooser(), I've tried putting playerLetter into the brackets of each function but they don't pass and create an argument error and the print("G") and so on are simply there to see if the code works but whenever I enter 1 or 2 "P" is outputted.
You need to define function Attributes for playerLatter
For EX:
def foo():
foo.playerletter=input('Please choose X or O.').upper()
>>> foo()
Please choose X or O.x
>>> foo.playerLetter
'X'
Accessing from another function
def bar():
variable=foo.playerLetter
print(variable)
>>> bar()
X
>>>
You can always check what Attributes are available for a given function
>>> [i for i in dir(foo) if not i.startswith('_')]
['playerLetter']
>>>
Edit turnchooser() to turnchooser(var), then when calling the function pass the letter to the function like this:
def LetterChoice():
Code...
turnchooser(playerletter)
And,
def turnchooser(var):
Code...
The letter will be placed in a variable called var, which means your code will use the letter as var not playerletter.
Of Course you can change the names to whatever you like.
You could add as many variables to the function however they all should have something assigned to them, aka you can't call the previous function like so:
turnchooser()
Unless you assign it a default value:
def turnchooser(var = 'x')
This way whenever the function is called the value of "var" is x unless stated otherwise.
Note that if you want to pass it from one function to another, u either have to assign the letter to a variable then call the function outside the "LetterChoice" or call it in the definition of "LetterChoice"
Within the function that has the variable in it type:
global variableName
Obviously change variableName to whatever the variable is actually called. Hope this helps!
Tommy
You should try using classes: Python documentation
This should be the code:
class Game:
def __init__(self):
self.cur_turn = ''
self.choise = ''
self.playerLetter = ''
self.computerLetter = ''
def letterChoice(self):
while True:
self.playerLetter = input('Please choose X or O.').upper()
if self.playerLetter in ['X','O']:
print('The game will now begin.')
if playerLetter == 'X':
self.computerLetter = 'O'
else:
self.computerLetter = 'X'
break
else:
print ('Please enter only X or O')
def turnChooser(self):
while True:
self.choice = input("Would you like to go first, second or decide by coin toss? (enter 1, 2 or c) ")
if self.choice in ["1","2","c"]:
if self.choice == 1:
print("G")
self.cur_turn = self.playerLetter()
elif self.choice == 2:
print("H")
else:
print("P")
break
else:
print ('Please enter 1, 2 or c')
game = Game()
game.letterChoice()
game.turnChooser()
# If you want to read any of the variables in Game just write 'self.VARIABLE_NAME'

Categories