Skipped If Statement/unstripped input data in Python - python

I'm updating a crack the code game I made in Python so that you can play a single-player game against the computer. For some reason, the interpreter either doesn't use the data stripped from the input used to determine player count or skips the if statement that uses the stripped data from the input. Either way, after you input the player number it goes straight to the guessing code with an empty list of correct code characters.
My code for the player count determining and code creation is:
plyrs = 0
correctanswer = []
print('Welcome!')
plyrs = str(input('How many players are there? (minimum 1, maximum 2) '))
if plyrs == 2:
print("I'm gonna ask you for some alphanumerical (number or letter characters to make a code for the other player to guess.")
input('Press enter when you are ready to enter in the code!') #Like all of my games, it has a wait.
i = 0
while i < 4:
correctanswer.append(input('What would you like digit ' + str(i + 1) + " to be? "))
i = i + 1
print("Ok, you've got your code!")
i = 0
while i < 19: #Generates seperator to prevent cheating
print('')
i = i + 0.1
print("Now, it's the other player's turn to guess!")
elif plyrs == 1:
import random
characters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0']
i = 0
while i < 4:
correctanswer.append(characters[randint(0,36)])
i = i + 1
print('Time for you to guess!')
print('')
No other skipping if statement questions apply to this so please help.

plyrs is a string, and you're comparing it to an int. "2" == 2 will always be false. Same with plyrs == 1, this will be false throughout.

Related

Mathematic questions in python

Looking on for some guidance on how to write a python code
that executes the following:
The program will ask for math problems to solve.
The program will asks for the number of problems.
And asks for how many attempts for each problem.
For example:
Enter amount of programs: 4
Enter amount of attempts: 5
what is: 4x3 =?
Your answer: 16
and so goes on to another attempt if wrong if correct moves onto another problem, just like before and exits when attempts or problems are finished.
I have this code but I want to it only do multiplication ONLY and would like to know how to integrate how to put additional code to limit how many time one can solve the question and how many questions it asks
import random
def display_separator():
print("-" * 24)
def get_user_input():
user_input = int(input("Enter your choice: "))
while user_input > 5 or user_input <= 0:
print("Invalid menu option.")
user_input = int(input("Please try again: "))
else:
return user_input
def get_user_solution(problem):
print("Enter your answer")
print(problem, end="")
result = int(input(" = "))
return result
def check_solution(user_solution, solution, count):
if user_solution == solution:
count = count + 1
print("Correct.")
return count
else:
print("Incorrect.")
return count
def menu_option(index, count):
number_one = random.randrange(1, 21)
number_two = random.randrange(1, 21)
problem = str(number_one) + " + " + str(number_two)
solution = number_one + number_two
user_solution = get_user_solution(problem)
count = check_solution(user_solution, solution, count)
def display_result(total, correct):
if total > 0:
result = correct / total
percentage = round((result * 100), 2)
if total == 0:
percentage = 0
print("You answered", total, "questions with", correct, "correct.")
print("Your score is ", percentage, "%. Thank you.", sep = "")
def main():
display_separator()
option = get_user_input()
total = 0
correct = 0
while option != 5:
total = total + 1
correct = menu_option(option, correct)
option = get_user_input()
print("Exit the quiz.")
display_separator()
display_result(total, correct)
main()
As far as making sure you're only allowing multiplication problems, the following function should work.
def valid_equation(user_input):
valid = True
for char in user_input:
if not(char.isnumeric() or char == "*"):
valid = False
return valid
Then after each user_input you can run this function and it will return True if the only things in the users string are numbers and the * sign and False otherwise. Then you just need to check the return value with a if statement that tells the user that their input is invalid if it returns False. You can add more "or" operations to the if statement if you want to allow other things. Like if you want to allow spaces (or char == " ").
As far as limiting the number of times a user can try to answer, and limiting the number of questions asked, you just need to store the values the user enters when you ask them these numbers. From there you can do nested while loops for the main game.
i = 0
user_failed = False
while ((i < number_of_questions) and (user_failed == False)):
j = 0
while ((j < number_of_attempts) and (user_correct == False)):
#Insert question asking code here
#In this case if the user is correct it would make user_correct = True.
j += 1
if j == number_of_attempts:
user_failed = True
i += 1
So in this situation, the outer while loop will iterate until all of the questions have been asked, or the user has failed the game. The inner loop will iterate until the user has used up all of their attempts for the question, or the user has passed the question. If the loop exits because the user used up all of their attempts, the for loop will trigger making the user lose and causing the outer loop to stop executing. If it does not it will add one to i, saying that another question has been asked, and continue.
These are just some ideas on how to solve the kinds of problems you're asking about. I'll leave the decision on how exactly to implement something like this into your code, or if you decide to change parts of your code to better facilitate systems like this up to you. Hope this helps and have a great one!

what is causing reference before assignment errors in below code?

I'm getting this error with refrenced before assignment and im not sure how to fix it.
I havent tried anything at the moment. It would be appreciated if this could be answered. (im just trying to fill up more words so it can be posted)
this is the error code i am getting:
number = int(number)
UnboundLocalError: local variable 'number' referenced before assignment
And this is the rest of my code
import random
import sys
again = True
while True:
myName = input('Hello, Enter your name to get started')
if myName.isdigit():
print('ERROR,Your Name is not a number, please try again')
print('')
continue
break
myName = str(myName.capitalize())
print('')
print('Hi {}, This is Guessing Game, a game where you have a certain amount of attempts to guess a randomly generated number. Each level has a different amount of attempts and a higher range of number. After each guess, press enter and the program will determine if your guess is correct or incorrect.' .format (myName))
print('--------------------------------------------------------------------------------')
while True:
level = input('{}, Please select a level between 1 and 3. Level 1 being the easiest and 3 being the hardest')
if not level.isdigit():
print('Please enter a number between 1 and 3. Do not enter a number in word form')
continue
break
def guessNumber(): # Tells the program where to restart if the user wants to play again
guessesTaken = 0
List = []
if level == 1:
number = random.randint (1, 16)
print('You chose Level 1, Guess a number a between 1 and 16, you have 6 guesses.')
allowedGuesses = 6
boundary = 16
if level == 2: # The code for level 2
number = random.randint (1,32)
print('You chose Level 2, Guess a number between 1 and 32, You have 8 guesses.')
allowedGuesses = 8
boundary = 32
if level == 3:
number = random.randint (1, 40)
print('You chose Level 3, Guess a number between 1 and 40, you have 10 guesses.')
allowedGuesses = 10
boundary = 40
if level == 4:
number = random.randint (1, 50)
print('You chose Level 4, Guess a number between 1 and 50, you have 10 guesses.')
allowedGuesses = 10
boundary = 50
if level == 5:
number = random.randint (1, 60)
print('You chose Level 5, Guess a number between 1 and 60, you have 10 guesses.')
allowedGuesses = 10
boundary = 60
guess = input()
guess = int(guess)
while guessesTaken < allowedGuesses:
guessesTaken = guessesTaken + 1
guessesLeft = allowedGuesses - guessesTaken
if guess < number:
List.append(guess)
print('Your guess is too low, You must guess a higher number, you have {} guesses remaining. You have guessed the numbers {}, Take another guess' .format (guessesLeft, List))
if guess > number:
List.append(guess)
print('Your guess is too high, You must guess a lower number, you have {} guesses remaining. You have guessed the numbers {}, Take another guess' .format (guessesLeft, List))
if guess > boundary:
List.append(guess)
print('You must input a number between 1 and 16. You have {} guesses remaining. You have guessed the numbers {}, Take another guess' .format (guessesLeft, List))
if guess == number:
List.append(guess)
print('Good Job {}!, You guessed my number in {} guesses. You guessed the numbers {}.' .format (myName, guessesTaken, List))
print('Your high score for your previous game was {}' .format(guessesTaken))
else:
number = int(number)
print('')
print('--------------------------------------------------------------------------------')
print('Sorry {}, Your gueses were incorrect, The number I was thinking of was {}. You guessed the numbers {}.' .format(myName, number, List))
guessNumber()
print('')
print('It is recommended to pick a harder level if you chose to progress')
print('')
while True:
again = input('If you want to play again press 1, if you want to stop playing press 2')
if not again.isdigit():
print('ERROR: Please enter a number that is 1 or 2. Do not enter the number in word form')
continue
break
if again == 1:
level + 1
guessNumber()
if again == 2:
print('Thanks for playing Guessing Game :)')
sys.exit(0)
In your code you are getting level as input and checking that if level is in between 1 to 5.
else you are trying number = int(number)
but you should write number = int(level).
Since level is a string rather than a number, none of the conditions like
if level == 1:
will succeed. So none of the assignments like number = random.randint (1, 16) ever execute, and number is never assigned.
Since if level == 5: doesn't succeed, it goes into the else: block, which starts with
number = int(number)
Since none of the other number assignments took place, this tries to use int(number) before the variable has been assigned, which doesn't work.
I'm not sure why you even have this assignment there. When number is assigned, it's always set to an integer, so there's no need to use int(number).
You need to use
level = int(level)`
after you confirm that it contains digits. And you need to do similarly with again.
There are a number of other problems with your code. For instance, the code that asks for the user's guess and checks it is inside the if level == 5: block, it should run in all the levels.
When you have a series of mutually exclusive tests, you should use elif for each successive test. If you just use if for each of them, and then use else: at the end, that else: will only apply to the last test, so it will be executed even if one of the early tests also succeeded.

How to strip letters off a string with numbers, so that it can be changed to int and sorted

I am making a dice rolling game where the scores and players have to be stored in an array, and then printed out in order as a scoreboard. I can do all of this but sorting the scoreboard.
I have worked out that I need to strip the letters from the string (player1 37 to just 37). The current code that I'm using is delchars = Player1.join(c for c in map(chr, range(256)) if not c.isalnum()) but it doesn't seem to be working, anyone know what to do.
#code for entering Player1
let= True
while let == True:
delay_print("player 1 enter your username\n")
Player1 = input()
if len(Player1) > 20 or len(Player1) < 3:
print("That is too long or too short, please try again")
else:
let = False
#code for entering Player2
tel = True
while tel == True:
delay_print("player 2 enter your username\n")
Player2 = input()
if len(Player2) > 20 or len(Player2) < 3:
print("That is too long, or too short, please try again")
else:
tel = False
my desired outcome is to be able to print out a scoreboard, in order.
Current code for this scoreboard is
print("first place is ", scoreboard[0] ,
"\nsecond place is ", scoreboard[1],
"\nthird place is " ,scoreboard[2],
"\nfourth place is " ,scoreboard[3],
"\nfifth place is " ,scoreboard[4])
As others have mentioned, you are probably trying to do this in a very weird way. To answer your question:
myString = "player1 37"
score = int(myString.split(" ").pop())
What happens here: It splits the string into a list, dividing at the space. Pop takes the last element of list, and int() converts it to an integer because having a score as a string is a really bad idea in the first place.
A way to create a sorted scoreboard for your list. I don't see why you should concatenate your player names and scores though, those should be seperate variables.
n=0
scoreboard = ["player1 37","player3 45","player2 75", "player32 43"]
def myFunc(e):
return int(e.split(" ")[1])
scoreboard = sorted(scoreboard, key=myFunc, reverse=True)
print("SCOREBOARD:")
for players in scoreboard:
print("{0}: {1}".format(n+1,scoreboard[n]))
n+=1
Instead of
delchars = Player1.join(c for c in map(chr, range(256)) if not c.isalnum())
use
delchars = "".join([c for c in Player1 if not c.isalnum()])

Python : Hang Man game

I am making a hang man game. I am trying to cycle through a word and have all the repeats in the letter be appended to my list. For example the word "hello": if the user types in "l" I want all the l's to be added to my list. Right now it is only finding one "l" and if the user types an "l" again it finds the second "l".
I also want the user not to be able to type in another letter if they previously already typed it in.
I have two lists one for right guesses and wrong guesses that store every guess. For example if a user types in "h" in "hello"
"h" is a right guess so it appends to [h] but if they type in "h" again it adds it to the list so it says ["h","h"]. The wrong box works the same way but for words that are wrong. If they type in "z" for the word "hello" it says ["z"] in the wrong box.
Here is my code:
import random
user_input = ""
turns = 5
print("Welcome to Advanced Hang Man!")
print("Use your brain to unscramble the word without seeing its order!")
words = ["hello","goolge","czar","gnat","relationship","victor","patric","gir","foo","cheese"]
# Picks a random word from the list and prints the length of it
random_word = (random.choice(words))
random_word_legnth = (len(random_word))
print("Hint! The length of the word is",random_word_legnth)
hold_random_word = [i for i in random_word]
while turns != 0 and set(right_guess) != set(hold_random_word):
user_input = input("Please type your guess one letter at a time:")
right_guess = []
wrong_guess = []
#Calculating every input
if len(user_input) == 1 and user_input.isalpha():
for i in user_input:
if i in hold_random_word:
right_guess.append(i)
else:
wrong_guess.append(i)
print("Correct guess", ''.join(right_guess))
print("Wrong guess", ''.join(wrong_guess))
I'm not sure what your direct question is, but thinking about a hangman game you want to take the users guess and parse the entire word or phrase they are guessing to see if their guess matches anywhere in the word. I made a hang man game below that will function as expected (minus any error handling) Let me know if any parts confuse you, and i can explain
import random
wordcomp = []
wordguess = []
#this is a word bank for all puzzles, they are randomly chosen
word_bank = ['guess this phrase', 'Lagrange', 'foo', 'another phrase to guess']
# This loop stores each letter in a list, and generates a blank list with correct spaces and blanks for user
rand_word = random.randrange(4)
for i in word_bank[rand_word]:
wordcomp.append(i)
if i == ' ':
wordguess.append(' ')
else:
wordguess.append('__')
print('I am thinking of a word,' , wordguess , ' it has ', len(wordguess), ' characters total, GOOD LUCK \n')
wordlist = wordcomp
count = 0
placeletter = 0
wrongguess = []
guesscount = 0
while wordlist != wordguess:
guess = input('please input a lower case letter within the english alphabet!') ##Check that input is one character, and lower case
guesscount = guesscount + 1
# This for loop scans through to see if the letter that was guessed is in the actual puzzle, and places in the correct spot!!
for t in wordcomp:
if t == guess:
wordguess[placeletter] = guess
placeletter = placeletter + 1
# This check tells them they already guessed that letter... then makes fun of them
if guess in wordguess:
pass
else:
wrongguess.append(guess)
while wrongguess.count(guess) > 1:
wrongguess.remove(guess)
print('you guessed the letter ' , guess , ' already, are you person that suffers short term memory loss...')
print('The word I am thinking of: ' , wordguess)
print('The letters you have already guess are: ', wrongguess)
placeletter = 0
# This tells them they finished the puzzle and the number of guesses it took, if its over 26, it calls them stupid for obvious reasons...
if guesscount >= 26:
print('you are an idiot if it took you more than 26 guesses..... now take a minute, sit silently, and think about why you are idiot if it took over 26 guesses... for hangman... where you guess the letters of the alphabet... YOU GET IT, stupid')
elif guesscount < 26:
print('Congrats you solved the puzzle, w00t!!')
if len(user_input) == 1 and user_input.isalpha():
for i in user_input:
if i in hold_random_word and i not in right_guess:
right_guess.append(i)
elif i not in hold_random_word or i not in wrong_guess:
wrong_guess.append(i)
elif i in hold_random_word:
# here user types something that is already typed and is a right_guess
pass
else:
# Types something wrong, that was already typed
pass
print("Correct guess", ''.join(right_guess))
print("Wrong guess", ''.join(wrong_guess))
It is not clear how you are taking inputs, but I think this code can be further optimized. Give it a shot.
Edit 1:
import random
user_input = ""
turns = 5
print("Welcome to Advanced Hang Man!")
print("Use your brain to unscramble the word without seeing its order!")
words = ["hello","goolge","czar","gnat","relationship","victor","patric","gir","foo","cheese"]
random_word = (random.choice(words))
random_word_legnth = (len(random_word))
print("Hint! The length of the word is",random_word_legnth)
hold_random_word = [i for i in random_word]
# This condition can lead to issues in situations like this - abc and aabbcc [sorry couldn't quickly come up with a good actual example :)]
while turns != 0 and set(right_guess) != set(hold_random_word):
user_input = input("Please type your guess one letter at a time:").strip()
right_guess = []
wrong_guess = []
#Calculating every input
if len(user_input) == 1 and user_input.isalpha():
# user_input is 1 letter so for i in user_input will execute only once
# Use the if structure as defined above
if user_input in hold_random_word:
right_guess.append(i)
else:
# this is missing
turns -= 1
wrong_guess.append(i)
print("Correct guess", ''.join(right_guess))
print("Wrong guess", ''.join(wrong_guess))
elif len(user_input) > 1:
print("Please type only one letter at a time")
elif not user_input.isalpha():
print("Please enter only valid English letters")
else:
# handle this however you want :)
pass

Checking through a variable to see if it doesn't contains anymore strings

def main():
#word = input("Word to guess for player 2:")
word = ['h','e','l','l','o']
word2 = "hello"
#make a list of _ the same length as the word
display =[]
for i in range (0,len(word)):
display.append("_")
chances = int(input("Number of chances to guess word:"))
if len(word)== 11:
print ("Your word is too long. It has to be 10 charecters or less")
else:
word = word
if chances < len(word):
answer = input("Your word is {0} letters long , are you sure you don't want more chances? Yes or no?". format (len(word)))
if answer == "no":
chances= int(input("Number of chances:"))
else:
chances = chances
("Ok then lets continue with the game")
print ("Player 2, you have {0} chances to guess the word.". format (chances))
won = False
underscore = False
while chances > 0 and won == False and underscore == False:
guess = input("Enter your guess: ")
gC=False
for i in range (0,len(word)):
if guess == word[i]:
gC=True
display[i]=guess
if not gC:
chances = chances - 1
display2 = ""
for i in display:
display2 = display2 + i + " "
For some reason the code doesn't work when I state my while loop as the game continues to go on until the user runs out of guess'. Does anybody have any suggestions as to how I can fix this?
You never set won to True when the user wins the game by guessing all the letters.
This is not an answer to your original question, instead more of a code-review, but maybe you'll find it useful.
word = list('hello') # replaces manual splitting of string into letters
display = [ '_' ] * len(word) # replaces build-up using for-loop
chances = input("Number ... ") # already returns int if the user enters an int
# but will evaluate any valid python expression the
# user enters; this is a security risk as what
# ever is done this way will be done using your
# permissions
chances = int(raw_input("Number ...")) # probably what you wanted
...
else:
word = word # does nothing. remove this line and the "else:" above
chances -= 1 # replaces 'chances = chances - 1' and does the same
display2 = ' '.join(display) # replaces the for-loop to build display2
Furthermore I suggest to use better names. Variables like display2 or gC aren't very helpful in this context. In professional programming you always have to keep in mind that you are writing your code (also or even mainly) for the next developer who has to maintain it. So make it readable and understandable. Choose names like displayString or guessedCorrectly instead.

Categories

Resources