Boolean value outside the function doesn't get changed - python

I'm learning Python and can't get my bool to change from "True" to "False" in my replay function. I've scoured StackOverflow, but can't find an answer.
I've tried canPlay = False and canPlay = not canPlay. But that's not working.
Any suggestions?
import random
from random import randint
# welcome message
print("Welcome to the number guessing game!")
# get the random seed
seedValue = input("Enter random seed: ")
random.seed(seedValue)
canPlay = True
def play():
randomNumber = randint(1, 100)
numberOfGuesses = 1
guessValue = ""
while guessValue != randomNumber:
# prompt the user for a guess
guessValue = int(input("\nPlease enter a guess: "))
# provide higher/lower hint
if guessValue == randomNumber:
print(f"Congratulations. You guessed it!\nIt took you {numberOfGuesses} guesses.")
elif guessValue > randomNumber:
print("Lower")
else:
print("Higher")
# increment the count
numberOfGuesses += 1
def replay():
playAgain = input("\nWould you like to play again (yes/no)? ")
if playAgain == "no":
canPlay = False # not changing values
canPlay = not canPlay # this doesn't work either
print("Thank you. Goodbye.")
while canPlay == True:
play()
replay()

with a global keyword inside the reply() function, you can change the value of the canPlay variable in the global namespace which is then needed in the condition of while statement while canPlay == True::
def replay():
global canPlay # <------------------ Here
playAgain = input("\nWould you like to play again (yes/no)? ")
if playAgain == "no":
canPlay = False # not changing values
canPlay = not canPlay # this doesn't work either
print("Thank you. Goodbye.")
If you do not insert that line, canPlay would be a local variable for reply() function, so it can't change global variables or be accessed by other statements outside the reply function.

Related

How do I break out of my while loop without using the most popular functions?(sys.exit,break,etc.)

I am making a program that generates a random number and asks you to guess the number out of the range 1-100. Once you put in a number, it will generate a response based on the number. In this case, it is Too high, Too low, Correct, or Quit too soon if the input is 0, which ends the program(simplified, but basically the same thing).
It counts the number of attempts based on how many times you had to do the input function, and it uses a while loop to keep asking for the number until you get it correct. The problem that I am facing is that I have to make it break out of the while loop once the guess is either equal to the random number or 0. This normally isn't an issue, because you could use sys.exit() or some other function, but according to the instructions I can't use break, quit, exit, sys.exit, or continue. The problem is most of the solutions I've found for breaking the while loop implement break, sys.exit, or something similar and I can't use those. I used sys.exit() as a placeholder, though, so that it would run the rest of the code, but now I need to figure out a way to break the loop without using it. This is my code:
import random
import sys
def main():
global attempts
attempts = 0
guess(attempts)
keep_playing(attempts)
def guess(attempts):
number = random.randint(1,100)
guess = int(input("Enter a number between 1 and 100, or 0 to quit: "))
while guess != 0:
if guess != number:
if guess < number:
print("Too low, try again")
attempts += 1
guess = int(input("Enter a number between 1 and 100, or 0 to quit: "))
elif guess > number:
print("Too high, try again")
attempts += 1
guess = int(input("Enter a number between 1 and 100, or 0 to quit: "))
else:
print()
print("Congratulations! You guessed the right number!")
print("There were", attempts,"attempts")
print()
#Ask if they want to play again
sys.exit()#<---- using sys.exit as a placeholder currently
else:
print()
print("You quit too early")
print("The number was ",number,sep='')
#Ask if they want to play again
sys.exit()#<----- using sys.exit as a placeholder currently
def keep_playing(attempts):
keep_playing = 'y'
if keep_playing == 'y' or keep_playing == 'n':
if keep_playing == 'y':
guess(attempts)
keep_playing = input("Another game (y to continue)? ")
elif keep_playing == 'n':
print()
print("You quit too early")
print("Number of attempts", attempts)
main()
If anyone has any suggestions or solutions for how to fix this, please let me know.
Try to implement this solution to your code:
is_playing = True
while is_playing:
if guess == 0:
is_playing = False
your code...
else:
if guess == number:
is_playing = False
your code...
else:
your code...
Does not use any break etc. and It does breaks out of your loop as the loop will continue only while is_playing is True. This way you will break out of the loop when the guess is 0 (your simple exit way) or when the number is guessed correctly. Hope that helps.
I am not a fan of global variables but here it's your code with my solution implemented:
import random
def main() -> None:
attempts = 0
global is_playing
is_playing = True
while is_playing:
guess(attempts)
keep_playing()
def guess(attempts: int) -> None:
number = random.randint(1,100)
print(number)
is_guessing = True
while is_guessing:
attempts += 1
guess = int(input("Enter a number between 1 and 100, or 0 to quit: "))
if guess == 0:
is_guessing = False
print("\nYou quit too early.")
print("The number was ", number,sep='')
else:
if guess == number:
is_guessing = False
print("\nCongratulations! You guessed the right number!")
print("There were", attempts, "attempts")
else:
if guess < number:
print("Too low, try again.")
elif guess > number:
print("Too high, try again.")
def keep_playing() -> None:
keep_playing = input('Do you want to play again? Y/N ')
if keep_playing.lower() == 'n':
global is_playing
is_playing = False
main()
TIP:
instead
"There were", attempts, "attempts"
do: f'There were {attempts} attempts.'

Python HangMan game using functions

So I'm trying to make a little hangman game in Python. I've managed it already, but I've seen lots of other people using functions to achieve this. Here's my code without using function:
from hangman_words import word_list
import random
def select_word():
return random.choice(word_list)
hidden_word = select_word()
char_lines = "_" * len(hidden_word)
guessed_letters = []
Lives = 8
game_start = input("Would you like to play HangMan? (Y/N)\n")
if game_start.upper() == "Y":
prompt_user = True
elif game_start.upper() == "N":
print("*Sad Python Noises*")
prompt_user = False
else:
print("You to say 'Yes'(Y) or 'No'(N)")
while (Lives > 0 and prompt_user == True):
user_input = input("Choose a letter!\n\n")
user_input = user_input.upper()
if user_input.upper() in guessed_letters:
print("\nYou have already guessed that letter. Choose something else!")
elif hidden_word.count(user_input) > 0:
for i, L in enumerate(hidden_word):
if L == user_input:
char_lines = char_lines[:i] + hidden_word[i] + char_lines[i+1:]
print("\nCorrect!")
print(char_lines)
else:
guessed_letters.append(user_input)
print("\nNope, that letter isn't in the word. Try again!")
Lives -= 1
if char_lines == hidden_word:
print("Well done! You won the game!")
print(f"You had {Lives} lives remaining and your incorrect guesses were:")
print(guessed_letters)
exit()
print(f"Lives remaining: {Lives}")
print(f"Incorrect guessed letters: {guessed_letters}")
print(char_lines)
if (Lives == 0 and prompt_user == True):
print("You have ran out of lives and lost the game!.....you suck")
if prompt_user == False:
print("Please play with me")
My current code for the version using functions is like this:
from hangman_words import word_list
import random
def select_word():
global blanks
selected_word = random.choice(word_list)
blanks = "_" * len(selected_word)
return selected_word, blanks
def game_setup():
global lives
global guessed_letters
global hidden_word
lives = 20
guessed_letters = []
hidden_word = select_word()
return lives, guessed_letters, hidden_word
def play_option():
game_start = (input("Would you like to play HangMan? (Y/N)\n")).upper()
if game_start == "Y":
global prompt_user
prompt_user = True
game_setup()
return prompt_user
elif game_start == "N":
print("*Sad Python Noises*")
exit()
else:
print("You need to say 'Yes'(Y) or 'No'(N)")
def user_input_check(user_input):
if type(user_input) != str: # [Want to check if unput is of tpye Str]
print("Please input letter values!")
elif user_input != 1:
print("Please only input single letters! (e.g. F)")
else:
pass
def game_board(user_input, hidden_word, guessed_letters, blanks, lives):
if user_input in guessed_letters:
print("You have already guessed that letter. Choose something else!")
elif hidden_word.count(user_input) > 0:
for i, L in enumerate(hidden_word):
if L == user_input:
blanks = blanks[:i] + hidden_word[i] + blanks[i+1:]
print("Correct!")
print(blanks)
else:
guessed_letters.append(user_input)
print("Nope, that letter isn't in the word. Try again!")
lives -= 1
print(f"Lives remaining: {lives}")
print(f"Incorrect guessed letters: {guessed_letters}")
print(blanks)
return
def win_check(blanks, hidden_word, lives, guessed_letters):
if blanks == hidden_word:
print("Well done! You won the game!")
print(f"You had {lives} lives remaining and your incorrect guesses were:")
print(guessed_letters)
exit()
def lives_check(lives, prompt_user):
if (lives == 0 and prompt_user == True):
print("You have ran out of lives and lost the game!.....you suck")
exit()
play_option()
while (lives > 0 and prompt_user == True):
user_input = (input("Choose a letter!\n\n")).upper()
user_input_check(user_input)
game_board(user_input, hidden_word, guessed_letters, blanks, lives)
win_check(blanks, hidden_word, lives, guessed_letters)
lives_check(lives, prompt_user)
I think I should be using classes instead of functions really, but I'd like to get it work with functions first, then try adapting it to work with classes. If I'm using functions, how does return actually work? Does returning variable names put those variables within the global name-space? Or does return only work when you assign the returned value to a global name-space variable? Like this:
def add_one(a):
return a + 1
b = add_one(3) # b = 4
You're correct, return works by setting the function to be equal to whatever you return it as.

Variable declared but error of not defined shows up in python

In a nutshell:
At the end of my program, there is a need to compare two integers whose results are inside the function itself. When I execute, I get undefined variable error.
Actually:
I am creating a hand cricket python script which we usually play as a duo. At last both the scores of the opponents are compared and the greatest wins.
The operation with the variables are inside of a function, but when called outside the function, undefined variable error shows up. Help please?
import random
while True:
pc_b_or_b = 0 #PC probability
#User Bowling module
def Bowl():
bat_PC = 0
User_bowl = 0
scoreofpc = 0
ScorePC = 0
while True:
bat_PC = random.randrange(1,11) #Random int gen
User_bowl = int(input("Your turn to bowl: ")) #int from user
if User_bowl<1 or User_bowl>10: #Fool proofing user must not keep less than 1 or gr8 than 10
print("Wrong number")
continue
if User_bowl == bat_PC: # Check if user == pc and out
print()
print("PC Out!")
print("PC Score:",scoreofpc)
break
else: #Continuation
print("Escape for PC. PC kept",bat_PC)
scoreofpc += bat_PC
print("Score:",scoreofpc)
ScorePC = scoreofpc
#User batting module
def User_Batting():
a = 0
score = 0
ManScore = 0
while True:
b = random.randrange(1,11) #Same as above but User is batting and pc randome int gen
a = int(input("Your turn to bat: ")) #But here if user int == pc then out for user
if a<1 or a>10:
print("Wrong number")
continue
if a==b:
print()
print("Out")
print("Score:",score)
break
else:
print("Escape! PC =",b)
score +=a
print("Score:",score)
ManScore = score
Actually Some more code comes here I've reduced to just these as said by StackOverflow
Main problem here, variable not defined, all other modules working perfectly
ScorePC1 = ScorePC
ManScore2 = ManScore
if ScorePC1 > ManScore2:
print("PC won the match by scoring",Score_of_PC)
elif ScorePC1 < ManScore2:
print("You won the match by scoring",User_Score)
else:
print("Your Score and PC score matched!")
quitter = input("Do you wanna Quit? Y/N? ")
if quitter == "yes" or quitter == "y" or quitter == "Y":
print("Thank You for playing!")
print("Script created by ***Techno-Sachin***")
quit()
elif quitter == "n" or quitter == "no" or quitter == "N":
print("Playing again..")
continue
else:
print("It's a wrong input. Try again")
Expectaion:
At last it is expected to print the statements inside if ScorePC1 and ManScore2 comparisons.
Error:
The output is Big, but cut out to focus on the problem itself>
PC Out! PC Score: 38 Traceback (most recent call last): File
"C:\Users\E.sachin\Documents\HTML5\Python Scripts\Hand_cricket20.py",
line 164, in
ScorePC1 = ScorePC NameError: name 'ScorePC' is not defined
Try replacing this - ScorePC1 = ScorePC with global ScorePC1 then use it as normal by referencing it's name ScorePC anywhere.
using global keyword before a varible name makes the variables's scope global and therefore enables the access to it from outside or inside a function.
also put the same inside the function definition like
def Bowl():
global ScorePC1
use it for both of your variables ScorePC1 and ManScore
You should always return values from your function. In this case you could return scoreofpc and score from the two functions. Your code would look like this:
def bowl():
#your code
return scoreofpc
def user_batting():
#your code
return score
Score1 = bowl()
Manscore = user_batting()
Alternatively, you could use Global Variables. But they are not advisable, infact, they're evil.
The variable ScorePC is declared inside the function Bowl() , by doing so the scope of the variable is within the Bowl() meaning it cannot be accessed from outside of the function. If you want to access it outside of the function declare it outside, which is not a good design. The better design is to return the value from the function like #irfanuddin answer.
I did some modifications also.
import random
def Bowl():
global ScorePC
bat_PC = 0
User_bowl = 0
scoreofpc = 0
ScorePC = 0
while True:
bat_PC = random.randrange(1,11) #Random int gen
User_bowl = int(input("Your turn to bowl: ")) #int from user
if User_bowl<1 or User_bowl>10: #Fool proofing user must not keep
less than 1 or gr8 than 10
print("Wrong number")
continue
if User_bowl == bat_PC: # Check if user == pc and out
print()
print("PC Out!")
print("PC Score:",scoreofpc)
break
else: #Continuation
print("Escape for PC. PC kept",bat_PC)
scoreofpc += bat_PC
print("Score:",scoreofpc)
ScorePC = scoreofpc
#User batting module
def User_Batting():
a = 0
score = 0
ManScore = 0
while True:
b = random.randrange(1,11) #Same as above but User is batting
and pc randome int gen
a = int(input("Your turn to bat: ")) #But here if user int == pc then out
for user
if a<1 or a>10:
print("Wrong number")
continue
if a==b:
print()
print("Out")
print("Score:",score)
break
else:
print("Escape! PC =",b)
score +=a
print("Score:",score)
ManScore = score
# Main probem here, variable not defined
# All other modules wotking perfectly
ScorePC1 = ScorePC
ManScore2 = ManScore
if ScorePC1 > ManScore2:
print("PC won the match by scoring",ScorePC1)
elif ScorePC1 < ManScore2:
print("You won the match by scoring", ManScore2)
else:
print("Your Score and PC score matched!")
quitter = input("Do you wanna Quit? Y/N? ")
if quitter == "yes" or quitter == "y" or quitter == "Y":
print("Thank You for playing!")
print("Script created by ***Techno-Sachin***")
exit()
elif quitter == "n" or quitter == "no" or quitter == "N":
print("Playing again..")
play()
else:
print("It's a wrong input. Try again")
def play():
Bowl()
User_Batting()
play()
If the reduced code is inside the main function,then the problem is that ScorePcvariable is not defined because it is a local variable inside the Bowl() function because you initialized it there.You cant access its name in the main() function.
To fix this you can either return it from Bowl() to the ScorePc or set it to be global as Himanshu said.
def Bowl():
#code..
return ScorePc
def main():
ScorePc=Bowl()#this will store the returned value to ScorePc
or
def Bowl():
global ScorePc
You should probably read more about this to understand better how it works.
Here are some links:
geeksforgeeks
python documentation
You have defined ScorePC and ManScore inside functions which turns out they are only usable inside that function unless you do one of the two things.
You can make the variable a function attribute.
Example:
def Bowl():
Bowl.ScorePC = 0
def User_Batting():
User_Batting.ManScore = 0
You can make the variable global.
Example:
def Bowl():
global ScorePC
ScorePC = 0
def User_Batting():
global ManScore
ManScore = 0
If you want to use them in other files. You have to import the file there where you want to use.
Here you will find some good examples:
Using global variables between files?
This can be done by using global keyword in the function. See below for your reference
def Bowl():
global ScorePc
....
def User_Batting():
global ManScore
....
But, I would suggest returning the value from the function. if your function is carrying multiple values, then do return as an array.

how to get game to restart when user types 'yes'?

how do I make it restart when the user types "yes"
import random
answer=(random.randint (1,100))
play_again="yes"
tries=(0)``
guess=int(input("I'm thinking of a number between 1 and 100 "))
tries+=1
while play_again=="yes":
if (guess<answer):
guess=int(input("its higher than "+str(guess)+" "))
tries+=1
elif (guess>answer):
guess=int(input("it's lower than "+str(guess)+" "))
tries+=1
elif (guess==answer):
print("well done! You guessed the number in "+str(tries)+" guesses!")
play_again=input("would you like to play again?")
how do I make the game restart after the user wins when they type "yes"?
use two loops. one outer with play_again == "yes" and one inner with guess != answer.
while play_again == "yes":
# get input
while guess != answer:
# if lower:
# get guess
# if higher
# get guess
# get play_again
You can do this , create a function !
import random
import sys
def main():
# your code here
while True:
play_again = input("play again? :") # For python 2 raw_input()
if play_again == "yes":
main()
else:
sys.exit()
Something like this !
I hope this helps you!!
With a function that calls itself
def main():
# your code goes here
if input('Play again?') == 'yes':
main()

Python NameError, variable 'not defined'

the error it returns is:
NameError: name 'lives' is not defined
I know the code isn't as efficient as possible, this is one of my first projects, however whatever i try to do this error pops up, I've tried making a global for it but that didn't help. I would really appreciate some help with this, thanks!
import random
import time
def main():
global guess,rand_num
win = False
rand_num = 45
lives = 10
while lives > 0 and win == False:
guess = int(input("Guess a number!"))
compare()
print("Well done!")
time.sleep(3)
def compare():
global lives,win
if guess == rand_num:
print("You guessed correct!")
win = True
elif guess > rand_num:
print ("Guess lower!")
lives = lives - 1
else:
print ("Guess higher!")
lives = lives - 1
def repeat():
replay = input("would you like to play again? Y/N")
if replay == "Y":
print("enjoy!")
main()
elif replay == "N":
"Goodbye then, hope you enjoyed!"
time.sleep(3)
os._exit
else:
print("please enter Y or N")
repeat()
main()
repeat()
EDIT: putting global lives inside main() returns the error:
UnboundLocalError: local variable 'lives' referenced before assignment
You need to define the variable "lives" outside of the function main, then any function where you want to reference that global variable you say "global lives." When you are in a function and assign a value to a variable, it assumes it is in the local scope. using "global lives" tells that function to look to the global scope as the reference of lives.
import random
import time
lives = 10
win = False
guess = 0
rand_num = 45
def main():
global guess, rand_num, lives, win
win = False
rand_num = 45
lives = 10
while lives > 0 and win == False:
guess = int(input("Guess a number!"))
compare()
print("Well done!")
time.sleep(3)
def compare():
global guess, rand_num, lives, win
if guess == rand_num:
print("You guessed correct!")
win = True
elif guess > rand_num:
print ("Guess lower!")
lives = lives - 1
else:
print ("Guess higher!")
lives = lives - 1
def repeat():
replay = input("would you like to play again? Y/N")
if replay == "Y":
print("enjoy!")
main()
elif replay == "N":
"Goodbye then, hope you enjoyed!"
time.sleep(3)
os._exit
else:
print("please enter Y or N")
repeat()
main()
repeat()
You didn't declare lives to be global inside main(), so it is local to that function.
def main():
global guess, rand_num, lives
...
When you declare it inside function they are only available in that function scope, so declare global variables outside functions and code will work fine.
import random
import time
guess = None
random_num = None
lives = 3
win = False
def main():
global guess,rand_num
win = False
rand_num = 45
lives = 10
while lives > 0 and win == False:
guess = int(input("Guess a number!"))
compare()
print("Well done!")
time.sleep(3)
def compare():
global lives,win
if guess == rand_num:
print("You guessed correct!")
win = True
elif guess > rand_num:
print ("Guess lower!")
lives = lives - 1
else:
print ("Guess higher!")
lives = lives - 1
def repeat():
replay = input("would you like to play again? Y/N")
if replay == "Y":
print("enjoy!")
main()
elif replay == "N":
"Goodbye then, hope you enjoyed!"
time.sleep(3)
os._exit
else:
print("please enter Y or N")
repeat()
main()
repeat()
And now this works fine. For more info about gloval vs local variables you can read: http://www.python-course.eu/global_vs_local_variables.php

Categories