How do you keep track of a global variable in python - python

I want to keep track of the variable TOTAL_TRI. TOTAL_TRI contains the number of correctly answered questions from the game. I need to save that value and pass it to the function statistics when statistics is called. Essentially, the player will play the game py_game, TOTAL_TRI will hold the number of questions they got right, and when the player calls the function statistics, it will display the number of questions they got right? I've been toying with this for a while with no significant progress. Any ideas?
P.S.
The other games in the menu are not yet implemented, but they'll do the same play-save correct number of questions-and let the player call to statistics kind of thing.
import random
from random import choice
from random import randint
#py_game------------------------------------------------------------------------
def py_game():
for k in range (1,3):
print('\nPractice Problem', k, 'of 2')
min_pyramid_size = 3
max_pyramid_size = 5
total_chars = 0
num_rows = random.randint(min_pyramid_size, max_pyramid_size)
for i in range(num_rows):
x = ''.join(str(random.choice('*%')) for j in range(2*i+1))
print(' ' * (num_rows - i) + x)
total_chars = total_chars + x.count('%')
try:
user_answer = int(input('Enter the number of % characters' + \
' in the pyramid: '))
except:
user_answer = print()
if user_answer == total_chars:
print('You are correct!')
else:
print("Sorry that's not the correct answer")
points = 0
for k in range (1,11):
print('\nProblem', k, 'of 10')
min_pyramid_size = 3
max_pyramid_size = 5
total_chars = 0
num_rows = random.randint(min_pyramid_size, max_pyramid_size)
for i in range(num_rows):
x = ''.join(str(random.choice('*%')) for j in range(2*i+1))
print(' ' * (num_rows - i) + x)
total_chars = total_chars + x.count('%')
try:
user_answer = int(input('Enter the number of % characters' + \
' in the pyramid: '))
except:
user_answer = print()
if user_answer == total_chars:
print('You are correct!')
points +=1
else:
print("Sorry that's not the correct answer")
TOTAL_TRI = points
#------------------------------------------------------------------------------
def statistics(points):
print('\nPyramid Game---------------------------')
incorrect = 10 - (points)
print ('You answered', points, 'questions correctly')
print ('You answered', incorrect, 'questions incorrectly')
#Main Menu--------------------------------------------------------------------------
def main_menu():
calculation_game = print("Enter 1 for the game 'Calculation'")
bin_reader = print("Enter 2 for the game 'Binary Reader'")
trifacto_game = print("Enter 3 for the game 'Trifacto'")
statistics = print("Enter 4 to view your statistics")
display_data = print("Enter 5 to display data")
save_game = print("Enter 5 to save your progress")
user_input = int(input('Make your selection: '))
if user_input == 1:
calculation()
if user_input == 2:
binary_reader()
if user_input == 3:
py_game()
if user_input == 4:
statistics(TOTAL_TRI)
if user_input == 5:
save_game()
if user_input != 1 or 2 or 3 or 4 or 5:
print('invalid input')
print('\n')
main_menu()
main_menu()

Using globals is code smell just waiting to happen. Pass your variable as an argument to your function. That's all.

Related

How to combine guesses/credits

How do I combine my guesses and credits in my python guessing game? for example, if it took me 6 guesses with the first attempt then when I press y to do the game again and it took me 10 guesses how can I get those two to combine for 16 total guesses, same thing with credits (sorry if its a bad explanation) Heres what I have so far:
import random
# this function is for the welcome part of my code or the part where I give instructions on how to play
def game_intro():
print(" ---- G U E S S I N G G A M E ----")
print("\n L E T S P L A Y ")
print("""\nThe adjective of this game is to solve guess a 3 digit combination,
and it is your job to guess numbers 100-999 to find that combination!!""")
print("Credits")
print("1-4 guesses: up to 60 credits")
print("5-10 guesses: 10 credits")
print("if guesses more than 10 no credits")
num_of_guess = 0 # stores how many guess I have made
total_games = 1 # stores how many games I played
done = False # set done to False
credit = 0
def check_range_main():
global num_of_guess, credit # global for getting stuff outside functions
i = random.randint(100, 999) # generate number at random
num_of_guess = 0
while not done:
try: # anything other than a number between 100, 999 gets an error
user_input = int(input("\nEnter a guess between 100-999: "))
num_of_guess += 1
if user_input == i:
print('you got it right in ', str(num_of_guess), 'tries')
print(creditScore())
new_game_plus()
elif user_input < i: # if player guess lower than I tell player
print("To low")
elif user_input > i: # if player guess higher than tell players
print("to high")
elif user_input not in range(100, 999):
print("Invalid. Enter a number between 100-999")
num_of_guess += 1
except ValueError:
print("Invalid. Enter a number between 100-999")
def new_game_plus():
global done, num_of_guess
new_game = input("Do you want to start a new game? press y for yes n for no: ")
if new_game == "y":
check_range_main()
else:
done = True
def statistics(new_game): # statistics for games after players finish
global total_games, num_of_guess
if new_game == "n":
print()
total_games += 1
num_of_guess += num_of_guess
print("P O S T G A M E R E P O R T")
print()
print(f"total {total_games} games played.")
print('total guesses', num_of_guess)
print("your average guess per game is", num_of_guess / total_games)
def creditScore():
global credit, done
credit = num_of_guess
if 1 <= num_of_guess <= 4:
print("game credits", 60 / credit)
elif 5 <= num_of_guess <= 10:
print("game credits", 10)
else:
print("no credits")
#print("total credits", )
# def functions matches() that computes and returns the number of matching digits in a guess, you may assume that the
# combination and the guess are unique three-digit numbers.
# def play_one_game():
# global done
# i = random.randint(100, 999)
# while not done:
# try:
# user_input = int(input("\nEnter a guess between 100-999: "))
# if user_input == i:
# print("Nice Job")
# done = True
#
# elif user_input > i:
# print("input to high")
#
# elif user_input < i:
# print("input to low")
#
# elif user_input not in range(100, 999):
# print("invalid input a number in range of 100,999")
#
# except ValueError:
# print("invalid. input a number between 100,999")
# this is where all the different functions go
def main():
game_intro()
check_range_main()
new_game_plus()
statistics("n")
creditScore()
# play_one_game()
if __name__ == '__main__':
main()
Put out the num_of_guess = 0 from inside the check_range_main()
...
num_of_guess = 0 # stores how many guess I have made
total_games = 1 # stores how many games I played
done = False # set done to False
credit = 0
num_of_guess = 0
def check_range_main():
global num_of_guess, credit # global for getting stuff outside functions
i = random.randint(100, 999) # generate number at random
while not done:

How do I stop redefining a variable after every loop of a function?

I am relatively new to Python, but I tried making random number generator guessing game where you just guess the number and if it's right you win and if you lose the attempt counter decreases, like this:
import random
a = random.randint (1, 20)
c = input('Select difficulty (1, 2, 3, 4) : ')
d = int(c)
def main():
if d == 1:
tries = e = 15
elif d == 2:
tries = e = 10
elif d == 3:
tries = e = 5
elif d == 4:
tries = e = 3
else:
tries = e = 1
for tries in range(tries, -1, -1):
tries -= 1
b = int(input('Pick a number from 1-20 : '))
if a == b:
print('Congratulations!')
print('# of tries : ', e - tries)
exit()
elif tries == 0:
print('No more attempts left, game over')
exit()
else:
print('Incorrect')
print('Attempts left : ', tries)
restart = input("Play again? (y/n)")
if restart == "y":
main()
else:
exit()
main()
So this program doesn't make sense unless you guess correctly on the first try because the attempt counter always stays the same. I think it's because everytime it goes back to the main() it redefines 'tries' as 15, 10, etc. The problem is if I put the 'if d == 1' section before def main() then it will say that 'tries' was referenced before assignment. There's probably a simple solution that I'm not seeing here and it's going way over my head, so hopefully what I'm asking makes sense. Feedback on the code irrelevant to the issue also appreciated.
Thanks.
The other answers will work just fine, but as a side note, you're calling main() inside main() which creates a recursive function. Unless you have a particular reason to do this, it should be avoided. Every previous attempt at the game will be held in memory until the user opts not to retry, and if you go far enough you'll run into a RecursionError. Try wrapping the whole program in a while loop, something like this:
import random
def main():
retry = True
while retry:
answer = random.randint(1, 20)
tries = 5 # Insert your own logic for num of tries
while tries > 0:
guess = int(input('Pick a number between 1 and 20: '))
if guess == answer:
print('Correct!')
break
else:
print('Incorrect')
tries -= 1
retry = input("Play again? (y/n)") == 'y'
main()
It's a little confusing to me why you're doing tries = e = num
A much cleaner way to do it would be to have a while loop that runs while the number of tries hasn't run out. You could set that number of tries to a variable based on the selected difficulty
One way to do it could be like this:
import random
# set number of tries based on difficulty chosen first, then all this
number = random.randint(1,50)
number_of_guesses = 0
while number_of_guesses < tries:
guess = input("Take a guess ")
guess = int(guess)
number_of_guesses = number_of_guesses + 1;
guesses_left = tries - number_of_guesses;
if guess < number:
print("Your guess is too low! You have " + str(guesses_left) + " guesses left")
if guess > number:
print("Your guess is too high! You have " + str(guesses_left) + " guesses left")
if guess == number:
break
if guess == number:
print("Good job! You guessed the number in " + str(number_of_guesses) + " tries :)")
if guess != number:
print("Sorry. The number I was thinking of was " + str(number) + " :)")
I changed the for loop to a while loop, removed the "tries = e = 15" and moved the "tries -= 1"
import random
a = random.randint (1, 20)
c = input('Select difficulty (1, 2, 3, 4) : ')
d = int(c)
def main():
if d == 1:
tries = 15
elif d == 2:
tries = 10
elif d == 3:
tries = 5
elif d == 4:
tries = 3
else:
tries = 1
while tries > 0:
b = int(input('Pick a number from 1-20 : '))
if a == b:
print('Congratulations!')
print('# of tries : ', tries)
exit()
else:
print('Incorrect')
tries -= 1
print('Attempts left : ', tries)
restart = input("Play again? (y/n)")
if restart == "y":
main()
else:
exit()
main()

Outer Loop of nest won't trigger

This is some of my homework but i am really stuck and can't find any advice online.
def main():
endProgram = 'n'
print()
while endProgram == 'n':
total = 0
totalPlastic = 0
totalMetal= 0
totalGlass = 0
endCount = 'n'
while endCount == 'n':
print()
print('Enter 1 for Plastic')
print('Enter 2 for Metal')
print('Enter 3 for Glass')
option = int(input('Enter now: '))
if option == 1:
totalPlastic = getPlastic(totalPlastic)
elif option == 2:
totalMetal = getMetal(totalMetal)
elif option == 3:
totalGlass = getGlass(totalGlass)
else:
print('You have entered an invalid input')
return main()
endCount = input('Do you want to calculate the total? (y/n): ')
print()
total = calcTotal(totalPlastic, totalMetal, totalGlass)
printNum(total)
break
endProgram = input('Do you want to end the program? (y/n): ')
def getPlastic(totalPlastic):
plasticCount = int(input('Enter the number of Plastic bottles you have: '))
totalPlastic = totalPlastic + plasticCount * .03
return totalPlastic
def getMetal(totalMetal):
metalCount = int(input('Enter the number of Metal cans you have: '))
totalMetal = totalMetal + metalCount * .05
return totalMetal
def getGlass(totalGlass):
glassCount = int(input('Enter the number of Glass bottles you have: '))
totalGlass = (totalGlass + glassCount * .10)
return totalGlass
def calcTotal(totalPlastic, totalMetal, totalGlass):
total = totalPlastic + totalMetal + totalGlass
return total
def printNum(total):
print('Your total recyclable value is $', total)
main()
My problem is I run the code and it works fine for 99% of it. The program will ask any type and amount of bottle, and it totals it correctly too, the issue is that the outer loop never gets asked. After it prints the total it just goes right back to asking what type of bottle you have instead of asking you whether or not you want to end the program. Any help is appreciated thanks.
Remove the break just before Do you want to end the program? (y/n)
print()
total = calcTotal(totalPlastic, totalMetal, totalGlass)
printNum(total)
break
Here you are using break and the loop gets out and does not go forward.
break is used in while loop endProgram == 'n' and it breaks and never goes forwards.
One more thing it is a bad habbit of making defining first. Always define main after the other functions and do not just call main().
Use this -
if(__name__ == '__main__'):
main()
The break statement was exiting your script, therefore your line endProgram = input('Do you want to end the program? (y/n): ') was unreachable, that is why it was never "asked".
Also, fixed some of your indentation, give it a go.
def main():
endProgram = 'n'
print()
while endProgram == 'n':
total = 0
totalPlastic = 0
totalMetal = 0
totalGlass = 0
endCount = 'n'
while endCount == 'n':
print()
print('Enter 1 for Plastic')
print('Enter 2 for Metal')
print('Enter 3 for Glass')
option = int(input('Enter now: '))
if option == 1:
totalPlastic = getPlastic(totalPlastic)
elif option == 2:
totalMetal = getMetal(totalMetal)
elif option == 3:
totalGlass = getGlass(totalGlass)
else:
print('You have entered an invalid input')
return main()
endCount = input('Do you want to calculate the total? (y/n): ')
print()
total = calcTotal(totalPlastic, totalMetal, totalGlass)
printNum(total)
endProgram = input('Do you want to end the program? (y/n): ')
def getPlastic(totalPlastic):
plasticCount = int(input('Enter the number of Plastic bottles you have: '))
totalPlastic = totalPlastic + plasticCount * .03
return totalPlastic
def getMetal(totalMetal):
metalCount = int(input('Enter the number of Metal cans you have: '))
totalMetal = totalMetal + metalCount * .05
return totalMetal
def getGlass(totalGlass):
glassCount = int(input('Enter the number of Glass bottles you have: '))
totalGlass = (totalGlass + glassCount * .10)
return totalGlass
def calcTotal(totalPlastic, totalMetal, totalGlass):
total = totalPlastic + totalMetal + totalGlass
return total
def printNum(total):
print('Your total recyclable value is $', total)
main()

Loop in a loop python [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
is there a way to add a second loop to a code. So the question says to create a quiz which I've done however, for the last hour I've being trying to add a second loop so the quiz does it three times:
import random
score = 0
questions = 0
loop = 0
classnumber = ("1", "2", "3")
name = input("Enter Your Username: ")
print("Hello, " + name + ". Welcome to the Arithmetic Quiz")
classno = input("What class are you in?")
while classno not in classnumber:
print(
"Enter a valid class. The classes you could be in are 1, 2 or 3.")
classno = input("What class are you in?")
while questions < 10:
for i in range(10):
number1 = random.randint(1, 10)
number2 = random.randint(1, 10)
op = random.choice("*-+")
multiply = number1*number2
subtract = number1-number2
addition = number1+number2
if op == "-":
print("Please enter your answer.")
questions += 1
print(" Question", questions, "/10")
uinput = input(str(number1)+" - "+str(number2)+"=")
if uinput == str(subtract):
score += 1
print("Correct, your score is: ", score,)
else:
print("Incorrect, the answer is: " + str(subtract))
score += 0
if op == "+":
print("Please enter your answer.")
questions += 1
print(" Question", questions, "/10")
uinput = input(str(number1)+" + "+str(number2)+"=")
if uinput == str(addition):
score += 1
print(" Correct, your score is: ", score,)
else:
print(" Incorrect, the answer is: " + str(addition))
score += 0
if op == "*":
print("Please enter your answer.")
questions += 1
print(" Question", questions, "/10")
uinput = input(str(number1)+" * "+str(number2)+"=")
if uinput == str(multiply):
score += 1
print(" Correct, your score is: ", score,)
else:
print(" Incorrect, the answer is: " + str(multiply))
score += 0
First, please consider using functions in your code. Functions make everything neater and functions help make code reusable.
Second, there are a lot of areas where the code is superfluous. It is performing unnecessary checks in spots and several sections of the code could be rearranged to reduce the overall length and increase readability.
Nonetheless, here's a revised version of your code with some of those suggestions implemented:
import random
def RunQuiz():
name = input("Enter Your Username: ")
print("Hello, " + name + ". Welcome to the Arithmetic Quiz")
score = 0
questions = 0
loop = 0
classnumber = ("1", "2", "3")
classno = input("What class are you in?")
while classno not in classnumber:
print("Enter a valid class. The classes you could be in are 1, 2 or 3.")
classno = input("What class are you in?\n>>> ")
# End while input
# Run the 10 question quiz
for questions in range(1,11):
number1 = random.randint(1, 10)
number2 = random.randint(1, 10)
op = random.choice("*-+")
multiply = number1*number2
subtract = number1-number2
addition = number1+number2
print("Please enter your answer.")
print(" Question" + str(questions) "/10")
if( op == "-"):
# Subtraction
uinput = input(str(number1)+" - "+str(number2)+"=")
# Make it an int for proper comparison
uinput = int(uinput)
if uinput == subtract:
score += 1
print("Correct, your score is: %d" %(score,))
else:
print("Incorrect, the answer is: " + str(subtract))
score += 0
elif( op == "+"):
# Addition
uinput = input(str(number1)+" + "+str(number2)+"=")
uinput = int(uinput)
if uinput == addition:
score += 1
print(" Correct, your score is: %d" % (score,))
else:
print(" Incorrect, the answer is: " + str(addition))
score += 0
elif( op == "*" ):
# Multiplication
uinput = input(str(number1)+" * "+str(number2)+"=")
uinput = int(uinput)
if uinput == multiply:
score += 1
print(" Correct, your score is: %d" % (score,))
else:
print(" Incorrect, the answer is: " + str(multiply))
score += 0
# End if( op )
# End For 10 questions
print("\nFinal Score: %d/10" % (score,))
# End RunQuiz()
def main():
# Run the quiz 10 times
for RunCount in range(3):
print("Running quiz #%d\n" % (RunCount,))
RunQuiz()
# End For
# End main
# Call main on script execution
main()
Obviously you can rearrange the code to suit your needs. (For example, I did not know if you want the name & class number to be entered every time).
If you want the whole thing to run 3 times then put for i in xrange(3): above the first lines of the quiz then indent the rest of the code to the loop. If that is what you actually want. Good luck!

Python - Returning variable from function trouble

I'm currently learning Python and am creating a maths quiz.
I have created a function that loops, first creating a random maths sum, asks for the answer and then compares the input to the actual answer; if a question is wrong the player loses a point - vice versa. At the end a score is calculated, this is what I'm trying to return at the end of the function and print in the main.py file where I receive a NameError 'score' is not defined.
I have racked my head on trying to figure this out. Any help / suggestions would be greatly appreciated!
#generateQuestion.py
`def generate(lives, maxNum):
import random
score= 0
questionNumber = 1
while questionNumber <=10:
try:
ops = ['+', '-', '*', '/']
num1 = random.randint(0,(maxNum))
num2 = random.randint(0,10)
operation = random.choice(ops)
question = (str(num1) + operation + str(num2))
print ('Question', questionNumber)
print (question)
maths = eval(str(num1) + operation + str(num2))
answer=float(input("What is the answer? "))
except ValueError:
print ('Please enter a number.')
continue
if answer == maths:
print ('Correct')
score = score + 1
questionNumber = questionNumber + 1
print ('Score:', score)
print ('Lives:', lives)
print('\n')
continue
elif lives == 1:
print ('You died!')
print('\n')
break
else:
print ('Wrong answer. The answer was actually', maths)
lives = lives - 1
questionNumber = questionNumber + 1
print ('Score:', score)
print ('Lives:', lives)
print('\n')
continue
if questionNumber == 0:
print ('All done!')
return score
`
My main file
#main.py
import random
from generateQuestion import generate
#Welcome message and name input.
print ('Welcome, yes! This is maths!')
name = input("What is your name: ")
print("Hello there",name,"!" )
print('\n')
#difficulty prompt
while True:
#if input is not 1, 2 or 3, re-prompts.
try:
difficulty = int (input(' Enter difficulty (1. Easy, 2. Medium, 3. Hard): '))
except ValueError:
print ('Please enter a number between 1 to 3.')
continue
if difficulty < 4:
break
else:
print ('Between 1-3 please.')
#if correct number is inputted (1, 2 or 3).
if difficulty == 1:
print ('You chose Easy')
lives = int(3)
maxNum = int(10)
if difficulty == 2:
print ('You chose Medium')
lives = int(2)
maxNum = int(25)
if difficulty == 3:
print ('You chose Hard')
lives = int(1)
maxNum = int(50)
print ('You have a life count of', lives)
print('\n')
#generateQuestion
print ('Please answer: ')
generate(lives, maxNum)
print (score)
#not printing^^
'
I have tried a different method just using the function files (without the main) and have narrowed it down to the problem being the returning of the score variable, this code is:
def generate(lives, maxNum):
import random
questionNumber = 1
score= 0
lives= 0
maxNum= 10
#evalualates question to find answer (maths = answer)
while questionNumber <=10:
try:
ops = ['+', '-', '*', '/']
num1 = random.randint(0,(maxNum))
num2 = random.randint(0,10)
operation = random.choice(ops)
question = (str(num1) + operation + str(num2))
print ('Question', questionNumber)
print (question)
maths = eval(str(num1) + operation + str(num2))
answer=float(input("What is the answer? "))
except ValueError:
print ('Please enter a number.')
continue
if answer == maths:
print ('Correct')
score = score + 1
questionNumber = questionNumber + 1
print ('Score:', score)
print ('Lives:', lives)
print('\n')
continue
elif lives == 1:
print ('You died!')
print('\n')
break
else:
print ('Wrong answer. The answer was actually', maths)
lives = lives - 1
questionNumber = questionNumber + 1
print ('Score:', score)
print ('Lives:', lives)
print('\n')
continue
if questionNumber == 0:
return score
def scoreCount():
generate(score)
print (score)
scoreCount()
I think the problem is with these last lines in main:
print ('Please answer: ')
generate(lives, maxNum)
print ('score')
You are not receiving the returned value. It should be changed to:
print ('Please answer: ')
score = generate(lives, maxNum) #not generate(lives, maxNum)
print (score) # not print('score')
This will work.
The way it works is not:
def a():
score = 3
return score
def b():
a()
print(score)
(And print('score') will simply print the word 'score'.)
It works like this:
def a():
score = 3
return score
def b():
print(a())

Categories

Resources