Lets say I'm writing a program that checks if input [ one number and equality statement ] compared against a randomly generated number is true, here's my code for reference:
import random
class Checker():
def __init__(self):
self.user_num=[]
self.comp_roll()
self.input_drive()
def comp_roll(self):
self.roll=random.randint(1,6)+random.randint(1,6) #roll 2 d6
def input_drive(self):
self.user_input=input("Input a number and [in]equality to compare against 2 random d6")
user_input=self.user_input
for i in range(len(user_input)):
if user_input[i].isdigit() == True: #if user_input[i] is a num
self.user_num.append(user_input[i]) #Keep track of just number from input in list
else: #if user_input[i] is not a num
if user_input[i] == ">":
self.track_op=">"
elif user_input[i] == "<":
self.track_op="<"
elif user_input[i] == "=":
self.track_op="="
self.user_num=int("".join(self.user_num)) #turn number list into one int
self.logic()
def logic(self):
dif=self.roll-self.user_num
abs_dif=abs(dif)
if self.track_op == ">":
if dif > 0:
win=True
else:
win=False
elif self.track_op == "<":
if dif < 0:
win=True
else:
win=False
elif self.track_op == "=":
if dif == 0:
win=True
else:
win=False
print("{result}\nComputer Guessed %d\nYou Guessed %d\nDifference %d".format(result="Win! :)" if win==True else "Lose :(") % (self.roll,self.user_num,abs_dif))
test=Checker()
So as you should be able to see I'm forced to use a switch statement that individually checks the code to see if any of >, <, = exist.
I then have to save this as a string with the value of the equality sign.
for i in range(len(user_input)):
if user_input[i].isdigit() == True: #if user_input[i] is a num
self.user_num.append(user_input[i]) #Keep track of just number from input in list
else: #if user_input[i] is not a num
if user_input[i] == ">":
self.track_op=">"
elif user_input[i] == "<":
self.track_op="<"
elif user_input[i] == "=":
self.track_op="="
Which I then use in another switch statement to manually check the difference.
dif=self.roll-self.user_num
abs_dif=abs(dif)
if self.track_op == ">":
if dif > 0:
win=True
else:
win=False
elif self.track_op == "<":
if dif < 0:
win=True
else:
win=False
elif self.track_op == "=":
if dif == 0:
win=True
else:
win=False
I would much rather save the [in]equality sign as a dictionary that uses a similar concept to this:
import operator
ops = { "+": operator.add, "-": operator.sub }
I'm sure that there must be an quicker way to do this similar to the code above. I'm just not sure how to do it.
Thank you so much for the help! :)
You rarely need to use Boolean literals. Your switch first reduces to
if self.track_op == ">":
win = dif > 0
elif self.track_op == "<":
win = dif < 0
elif self.track_op == "=":
win = dif == 0
which should make it obvious you can abstract out the comparison operators.
comp_ops = {">": operator.gt, "<": operator.lt, "=": operator.eq}
if self.track_op in comp_ops:
win = comp_ops[self.trac_op](dif, 0)
Is there a reason for avoiding the builtin eval() function? If not you could just do something like this in your checker class
import random
roll=random.randint(1,6)+random.randint(1,6)
print(roll)
test_in = input("please enter your statement")
try:
test_out = eval(f"{test_in}roll")
print(test_out)
except:
print('Invalid Entry')
Results
10
please enter your statement>? 4>
False
And for a true statement
3
please enter your statement4>
True
Edit: I should add that eval() could be dangerous as it can execute arbitrary python commands. It doesn't seem like an issue in your case but I'd feel remiss if I didn't add an addendum
Related
I am writing a program were add and subtract numbers from an integer to keep score. The admin and subtracting is working but I am trying to add a feature that if you add number after the word add or subtract it changes by that number, but I can’t get that to work.
cont = True
score = 0
num = False
while cont == True:
q = input("add, subtract, or end: ")
for char in q:
n = q.isnumeric()
if n == True:
num = True
num2 = q
if num == False:
if q.lower() == "add":
score += 1
elif q.lower() == "subtract" or q.lower() == "sub":
score -= 1
elif q.lower() == "end":
cont = False
print(score)
elif num == True:
if "add" in q.lower():
score += num2
elif "subtract" in q.lower() or "sub" in q.lower():
score -= num2
elif q.lower() == "end":
cont = False
print(score)
I expect it to add one if you type add subtract one if you type sub or subtract and end the program if you type end, that works the part that I expected and doesn’t work is that it is supposed to detect if there is a number in the string using the isnumeric() function and add or subtract that number.
Your code simplifies neatly to something like:
score = 0
while True: # Infinite loop; we'll use `break` to end
print("Score:", score)
q = input("add, subtract, or end: ").lower().strip() # lower-case, remove whitespace
words = q.split() # Split entry by spaces
verb = words.pop(0) # Remove first word
if verb == "end":
break
if words and words[0].isnumeric(): # If there is a second word and it's numeric
value = int(words[0])
else: # Otherwise default to 1
value = 1
if verb == "add":
score += value
elif verb == "subtract":
score -= value
else:
print("Unknown verb", verb)
import random
guess = input("Head or Tail? ")
head_tails = ["Head", "Tail"]
def coin_flip():
random_number = [random.randint(0,1)]
for rando in random_number:
if rando == 0:
answer = head_tails[rando]
elif rando == 1:
answer = head_tails[rando]
user_guess = ""
#User_guess is always "False", even though the user(input) guessed the right outcome...
if guess == "Head" and random_number == 0:
user_guess = "True"
elif guess == "Tail" and random_number == 1:
user_guess = "True"
else:
user_guess = "False"
if user_guess == "True":
print("You are right!")
print("It was:", answer)
elif user_guess == "False":
print("You guessed wrong! You guessed:", guess)
print("It was:", answer)
coin_flip()
Why does user_guess always equal "False"?
Since random_number is list, it can not be equal to an integer - a list is not an integer. To make the if-statement work, put brackets around the integers either random_number = [0] or random_number = [1] . This will work since the number is within a list, i.e. in random_number. You can also change random_number so it is not a list and therefore remove for rando in random_number: and change it to answer = heads_tails[random_number] and keep random_number == 0. This will work since random_number is not a list, thus it can be equal to an integer.
What I am trying to do is create a while loop that always begins by gathering input. However, whenever I run it and input "hit", it seems to skip the prompt and go directly to the conditional statements under "if hit".
while current_score <= 21:
hit = input("Do you want to hit or stay? ")
if hit == 'stay' or ' Stay':
print("The dealer's hand:", dealer_hand)
if(current_score < dcurrent_score):
print("you have lost")
break
if(current_score > dcurrent_score):
print("you have won")
break
if hit == 'hit' or 'Hit':
z = randint(0, 51)
card_three = deck[z]
while card_three == card_two or card_three == card_one:
z = randint(0, 51)
card_three = deck[z]
current_hand.append(card_three)
if current_score > 21:
print("you have lost")
break
You have a problem in this line:
if hit == 'stay' or 'Stay':
and this one
if hit == 'hit' or 'Hit':
'Stay' and 'Hit' are truthy values so condition always pass. Change them to
if hit == 'stay' or hit == 'Stay':
and
if hit == 'hit' or hit == 'Hit':
Or more pythonic way:
if hit.lower() == 'stay':
'lower' method fill make string lowercase
I believe your problem would be solved if you type:
if (hit=="stay" or hit=="Stay"):
<statements>
if (hit=="hit" or hit=="Hit"):
<statements>
I suggest you go through the following article:
https://www.geeksforgeeks.org/basic-operators-python/
https://realpython.com/python-or-operator/
I am simply wondering how I can make my game of Mastermind work, more specifically how I would go about making "finish" global, how I would call these functions so that the program works correctly, and overall tips that would help enhance my code. I would also like to know how to make it so the program doesn't 'reroll' the computer-generated number every single loop. This was just a difficult problem for me and I can't seem to understand how to close it out with the correct function calls and niche aspects such as that. Thank you.
run = True
def get_guess():
while run:
guess = input("Provide four unique numbers: ")
count = 0
if len(guess) == 4:
guessdupe = guess[0] == guess[1] or guess[0] == guess[2] or guess[0] == guess[3] or guess[1] == guess[2] or guess[1] == guess[3] or guess[2] == guess[3]
else:
guessdupe = False
try:
try:
for i in range(4):
if int(guess[i]) <= 7 and int(guess[i]) >= 1 and len(guess) == 4:
count += 1
if len(guess) != 4:
print "Your guess must consist of 4 numbers!"
if guessdupe:
count -= 1
print "You can only use each number once!"
except ValueError:
print "You can only use numbers 1-7 as guesses"
except IndexError:
print "You can only use numbers 1-7 as guesses"
if count == 4:
break
return guess
def check_values(computer_list, user_list):
final_list = [''] * 4
for i in range(4):
if user_list[i] in computer_list:
if user_list[i] == computer_list[i]:
final_list[i] = "RED"
else:
final_list[i] = "WHITE"
else:
final_list[i] = "BLACK"
random.shuffle(final_list)
print final_list
return final_list
def check_win(response_list):
if response_list[0] == "RED" and response_list[1] == "RED" and response_list[2] == "RED" and response_list[3] == "RED":
print "Congratulations! You've won the game!"
global finish
finish = True
def create_comp_list():
while run:
compList = [random.randint(1, 7), random.randint(1, 7), random.randint(1, 7), random.randint(1, 7)]
listBool = compList[0] == compList[1] or compList[0] == compList[2] or compList[0] == compList[3] or compList[1] == compList[2] or compList[1] == compList[3] or compList[2] == compList[3]
if listBool:
continue
else:
return compList
def play_game():
for i in range(5):
print create_comp_list()
print get_guess()
check_win(check_values(create_comp_list(), get_guess()))
if finish:
break
play_game()```
This is my code, but it does not work with python 3.4
print ("Hello")
b = str(input("Where do you go?\n"))
def place(a):
if a == "r" or a > 0:
print("Turned right.")
elif a == "l" or a < 0:
print("Turned left.")
else:
print("Invalid")
a = int(str(input("Where do you go?\n")))
place(a)
place(b)
I want to make 'b' to be either an int or a string
Use a try except block:
b = input("Where do you go?\n")
def place(a):
try:
a = int(a)
# code for a being a number
except ValueError:
# a is a letter
The isdigit() method will tell you if a string is an integer.
a = "1"
if a.isdigit():
a = int(a)
Is this not what you're going for?
def place(a):
try:
b = int(a)
except ValueError:
b = 0
if (b != 0):
if b > 0:
print("Turned right.")
else:
print("Turned left.")
elif (type(a) is str) and ((a == 'r') | (a == 'l')):
if a == 'r':
print("Turned right.")
else:
print("Turned Left")
else:
print("Invalid")
raise TypeError("Nothing to do")