Python score system - python

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)

Related

Making Mastermind in Python

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()```

Python array loop not looping/validator issues

I'm not exactly sure what I did, but when testing my code it either crashes immediately or gets stuck in a loop. If the first input is a value error (string) and the next is a number it loops as long as the pattern is kept. But if first user entry is int then program crashes. Please any help would be appreciated.
def main():
courseArray = []
keepGoing = "y"
while keepGoing == "y":
courseArray = getValidateCourseScore()
total = getTotal(courseArray)
average = total/len(courseArray)
print('The lowest score is: ', min(courseArray))
print('The highest score is: ', max(courseArray))
print('the average is: ', average)
keepGoing = validateRunAgain(input(input("Do you want to run this program again? (Y/n)")))
def getValidateCourseScore():
courseArray = []
counter = 1
while counter < 6:
try:
courseArray.append(int(input("Enter the number of points received for course: ")))
valScore(courseArray)
except ValueError:
print("Please enter a valid score between 0-100")
courseArray.append(int(input("Enter a number between 1 and 100: ")))
counter += 1
return courseArray
def valScore(courseArray):
score = int(courseArray)
if score < 0:
print("Please enter a valid score between 0-100")
courseArray.append(int(input("Enter a number between 1 and 100: ")))
elif score > 100:
print("Please enter a valid score between 0-100")
courseArray.append(int(input("Enter a number between 1 and 100: ")))
else:
return courseArray
def validateRunAgain(userInput):
if userInput == "n" or userInput == "N":
print("Thanks for using my program")
return "n"
elif userInput == "y" or userInput == "Y":
return "y"
else:
print("Please enter y or n")
validateRunAgain(input("Do you want to run this program again? (Y/n)"))
return getValidateCourseScore()
def getTotal(valueList):
total = 0
for num in valueList:
total += num
return total
main()
There are too many inputs from the user, so I have cut down on them and changed it.
Here are the sections of your code which I have changed :
Here valScore() I presume validates the input score so, I also gave the index of element to be validated. If it is not valid we remove it from the array and raise ValueError, since it raises error our counter is not updated.
keepGoing = validateRunAgain()
def getValidateCourseScore():
courseArray = []
counter = 1
while counter < 6:
try:
courseArray.append(int(input("Enter the number of points received for course: ")))
valScore(courseArray, counter - 1)
counter += 1
except ValueError:
print("Please enter a valid score between 0-100")
continue
return courseArray
def valScore(courseArray, counter):
score = courseArray[counter]
if score < 0 or score > 100:
courseArray.pop()
raise ValueError
def validateRunAgain():
while True:
userInput = input("Do you want to run this program again? (Y/n)")
if userInput == 'y' or userInput == 'Y':
return 'y'
elif userInput == 'n' or userInput == 'N':
print('thank you for using my program')
return 'n'
else:
print('Enter Y or N')

Trouble ending a multi if statement to catch all

I am currently attempting to write my first program/app in Python by creating a tool for my partner to use when we play a card game. I have just started to pick up learning to program seriously, so it maybe a rookie mistake I have missed, but I can't seem to catch "anything else" via input to divert the user a response.
Here is my code:
def counting_up ():
round_total = 0
while True :
global game_level
cards = input("Enter Card: \n")
if cards.upper() == "A" or cards == "2" :
round_total += 20
if cards == "3" :
round_total += 3
if cards == "4":
round_total += 4
if cards == "5" :
round_total += 5
if cards == "6" :
round_total += 6
if cards == "7" :
round_total += 7
if cards == "8" :
round_total += 8
if cards == "9" :
round_total += 9
if cards == "10" or cards.upper() == "J" or cards.upper() == "Q" or cards.upper() == "K" :
round_total += 10
if cards == "0" :
game_level += 1
if cards.upper() == "END" :
game_state = 1
break
else :
print (f"{cards}, is not a valid value, please enter a valid value!")
print ("Your score this round was " + str(round_total))
return round_total
When testing it doesn't seem to go through the prior logic checks before it comes to the conclusion that its an invalid value. NOTE this entire function was working as intended and does if i remove the else: statement at the end. Is there anything in python similar to a case statement in java that would work?
Thanks in advance
With multiple if statements at the same level, python will check each conditional statement. If you want it to ignore subsequent statements when a prior one has been satisfied, use elif:
def counting_up(game_state, game_level, round_total=0):
"""Request and add input card face value to score repeatedly till end."""
while True:
cards = input("Enter Card: \n")
if cards.upper() == "END":
game_state = 1; break
elif cards == "0":
game_level += 1
elif cards.upper() in ("A", "2"):
round_total += 20
elif cards.isnumeric():
round_total += int(cards)
elif cards.upper() in ("J","Q","K"):
round_total += 10
else:
print(f"{cards}, is not a valid value, please enter a valid value!")
print(f"Your score this round was {round_total}.")
return round_total
Only the first 'if' should be an 'if' the rest of the 'if' statements should be replaced by 'elif' (else if) statements.
"else" always checks the most recent "if" and then evaluates. So if you only enter "END" without having the break statement, the program won't go to the else statement. So anything you enter, other than "END", prints the result along with the result of the else statement.
Hence use "elif" for the statements other than the first "if" statement so that it checks the condition. If satisfied, prints the result else it moves on to the next statement
You can use dict
def counting_up ():
round_total = 0
while True :
global game_level
cards = input("Enter Card: \n")
card_dict = {'A':20,'2':20,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'10':10,'J':10,'Q':10,'K':10}
if cards.upper() in card_dict.keys():
round_total += card_dict[cards.upper()]
elif cards == "0" :
game_level += 1
elif cards.upper() == "END" :
game_state = 1
break
else :
print (f"{cards}, is not a valid value, please enter a valid value!")
print("Your score this round was " + str(round_total))
return round_total

Use inequality from user input string

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

Changing variable in a function

from random import randint
count = 0
Validation = False
def generateNumber():
Number = randint(1, 10)
return Number
def checkNumber(Guess):
Number = generateNumber()
if int(Guess) == Number and count < 1:
return "First time right! Genius?"
Validation = True
elif int(Guess) == Number and count == 2:
return "Correct. Second time, nice!"
Validation = True
elif int(Guess) == Number and count < 4:
return "Correct. Good job."
Validation = True
elif int(Guess) == Number and count > 3:
return "Correct. Took you long enough."
Validation = True
else:
return "Wrong! Try again "
while Validation == False:
Guess = input("Please guess a number between 1 to 10: ")
print (checkNumber(Guess))
count += 1
else:
TryAgain = input("Would you like to try again? y/n \n")
So the problem is, that when the user guesses the right number. Validation should be turned to True. So the while loop will stop looping. But the variable validation doesn't turn True when the player guesses the right number.
Global variables in Python are a bit tricky, it is not enough to declare a variable at the top of the file.
Also, keep you return the value before you set the Validation value, causing the function to terminate before setting this variable
Last issue is the while logic, see correction for using raw_input instead of input and else indentation
Read only access to global variables work as expected, yet when changing their value in a function requires one extra step, you should declare the global variable as global. In your case:
def generateNumber():
Number = randint(1, 10)
return Number
def checkNumber(Guess):
global Validation #<-- this instructs Python to use the global variable
Number = generateNumber()
if int(Guess) == Number and count < 1:
Validation = True
return "First time right! Genius?"
elif int(Guess) == Number and count == 2:
Validation = True
return "Correct. Second time, nice!"
elif int(Guess) == Number and count < 4:
Validation = True
return "Correct. Good job."
elif int(Guess) == Number and count > 3:
Validation = True
return "Correct. Took you long enough."
else:
return "Wrong! Try again "
while Validation == False:
Guess = input("Please guess a number between 1 to 10: ")
print (checkNumber(Guess))
count += 1
if (Validation):
if (raw_input("Would you like to try again? y/n \n") == "y"):
count = 0
Validation = False
else:
break
You need to set Validation to True before you return from the method, like this:
if int(Guess) == Number and count < 1:
Validation = True
return "First time right! Genius?"
Do this for all if-statements.
I spot two (and a half) problems in your code:
As pointed out by Ishay Peled, you need to make Validation global
Your "return" statements are located before you change the value of "Validation"
"while" has no "else"
Here's the updated code:
from random import randint
count = 0
Validation = False
def generateNumber():
Number = randint(1, 10)
return Number
def checkNumber(Guess):
global Validation
Number = generateNumber()
if int(Guess) == Number and count < 1:
Validation = True
return "First time right! Genius?"
elif int(Guess) == Number and count == 2:
Validation = True
return "Correct. Second time, nice!"
elif int(Guess) == Number and count < 4:
Validation = True
return "Correct. Good job."
elif int(Guess) == Number and count > 3:
Validation = True
return "Correct. Took you long enough."
else:
return "Wrong! Try again "
while Validation == False:
Guess = input("Please guess a number between 1 to 10: ")
print (checkNumber(Guess))
print "validation: %s" % str(Validation)
count += 1
TryAgain = input("Would you like to try again? y/n \n")
Besides the global variable issue, you need to make another set of fixes. All your assignments to Validation = True appear after the "return" statements. The Validation = True will never execute! It will exit the function before executing those. Set 'Validation = True' before you 'return'. You still need to have the global declaration as Ishay stated.

Categories

Resources