I am brand new to coding and working my way through an intro class via Zybooks. This challenge activity is asking me to add one point to user_score for every letter that is a match and break the loop when there is a mismatch. Simon_pattern and user_pattern are both input. This is the code I have so far:
user_score = 0
simon_pattern = input()
user_pattern = input()
for character in simon_pattern:
for input in user_pattern:
if input == character:
user_score += 1
continue
if input != character:
break
print('User score:', user_score)
The code works, but the returned value is wrong. Given simon_pattern ='RRGBRYYBGY'and user_pattern = 'RRGBBRYBGY' the output should be User Score: 4, but my User Score is coming out as 3.
I'm not quite sure what part of my code needs fixing and unfortunately zybooks does not give you any hints. Thanks in advance for the help of this awesome community!!
Hi and welcome to coding! A few notes: Notice how the input() function is used to gather input from the user? Because of this, it is considered a keyword and it is bad practice to name your variables input, because it will overwrite the reference to the function.
Now considering your problem. Instead of a nested loop I would use a single for lop and check the characters at each index within both strings. If they match, add a point. Otherwise, break the loop. You also want to stop the loop if it goes beyond the number of characters in either pattern. One trick for that is to find the minimum length between both patterns. The min function is useful for this.
user_score = 0
simon_pattern = input()
user_pattern = input()
length = min(len(simon_pattern), len(user_pattern))
for i in range(length):
if user_pattern[i] == simon_pattern[i]:
user_score += 1
else:
break
print('User score:', user_score)
This should work :
user_score = 0
simon_pattern = input()
user_pattern = input()
for simon_character, user_character in zip(simon_pattern, user_pattern):
if simon_character == user_character:
user_score += 1
else:
break
print('User score:', user_score)
Be careful not to redefine the Python keywords such as input or print for example. The rest of your program could be modified if you need to reuse these functions
Related
Hi :) I am making a quiz using python, i would like a user to answer 3 questions, and with each correct or incorrect answer, a user_score variable will get update.
What goes wrong is that when question 1 is answer and user moves to question 2, the user_score variable gets reset.
the while loop i use to process the user answers is below:
def check_submitted_answers(answer):
perfect_answers = ['Mohammad','Abraham','Jesus']
all_answers = ['Mohammad','Moses','Jesus','Solomon','Abraham']
user_score = 0
while True:
if answer not in all_answers:
print('Error: Please select one of the choices above')
answer = input('Your answer is: ').capitalize()
else:
if answer in perfect_answers:
print('Correct answer!!You got +1 point')
user_score = user_score + 1
perfect_answers.remove(answer)
break
else:
print('Wrong answer.. You gained 0 points')
user_score = user_score + 0
break
else:
return answer
Whenever a new question comes in , the user_score variable is set to 0 again, i want the old value to be stored instead. thank you =)
yes, as GodWin pointed out, user_score lives only inside the function. Since you never return it, you will never access it from outside. I recommend sth like:
user_score = 0
def check_submitted_answers(answer):
global user_score
perfect_answers = ['Mohammad','Abraham','Jesus']
all_answers = ['Mohammad','Moses','Jesus','Solomon','Abraham']
while True:
if answer not in all_answers:
print('Error: Please select one of the choices above')
answer = input('Your answer is: ').capitalize()
else:
if answer in perfect_answers:
print('Correct answer!!You got +1 point')
user_score = user_score + 1
perfect_answers.remove(answer)
break
else:
print('Wrong answer.. You gained 0 points')
break
else:
return answer
check_submitted_answers("Jesus")
print(user_score) #prints 1
and I suspect you might wanna give some more details next time, because I am also a bit confused, like quamrana is. Hope this helped you tho ;). Let me know if this fixed your problem :D
'''
Program that reads first user string input as simon pattern
then reads second user string input as user pattern.
Each character existing in the two strings is compared left to right.
For each equal character the user score is increased by 1.
The loop terminates and outputs user score upon reaching the first
character that doesn't match.
'''
user_score = 0
simon_pattern = input() #input for initial string
user_pattern = input() #best attempt at copying simon_pattern
for i in user_pattern:
for j in simon_pattern:
if i == j:
user_score += 1 #adds 1 to user_score for each equal
#character in the same index for both strings
else:
break #if two characters do not match then end the loop
print('User score:', user_score)
For some reason the output is not what I would expect when I run this program though there are no syntax errors that I can find. Am I using for loops or break in a way that is producing an inaccurate result?
For example if I input: 'RRGBRYYBGY' 'RRGBBRYBGY' the output is 'User score: 6' when the fifth character in each string clearly doesn't match and the output should be 'User score: 4'.
Thanks for any help in advance!!
Your case needs to iterate through simon_pattern and user_pattern side by side, not nestedly. What you need is zip():
user_score = 0
simon_pattern = input() #input for initial string
user_pattern = input() #best attempt at copying simon_pattern
for i,j in zip(user_pattern,simon_pattern):
if i == j:
user_score += 1 #adds 1 to user_score for each equal
#character in the same index for both strings
else:
break #if two characters do not match then end the loop
print('User score:', user_score)
There is already an answer but i will explain The problem with your approach is how your nested loop works, if there are 2 strings "ABCD" and "ABDC"
You are basically taking A from first string match it with A in second string, then you take B in first string match with A in second string; so basically all comparison for characters in first string happen with first character of second string.
Hope this helps :)
Here's another way that doesn't use zip() (requested in the comments):
user_score = 0
simon_pattern = input() #input for initial string
user_pattern = input() #best attempt at copying simon_pattern
letters = min(len(simon_pattern),len(user_pattern))-1 # Maximum amount of letters to iterate through
for index in range(letters):
if simon_pattern[index] == user_pattern[index]:
user_score += 1 #adds 1 to user_score for each equal
#character in the same index for both strings
else:
break #if two characters do not match then end the loop
print('User score:', user_score)
using the break statement just gets you out of the nested loop (j). To solve this problem, you can either use a function with a return statement:
def get_user_score():
user_score = 0
simon_pattern = input() #input for initial string
user_pattern = input() #best attempt at copying simon_pattern
for i in user_pattern:
for j in simon_pattern:
if i == j:
user_score += 1 #adds 1 to user_score for each equal
#character in the same index for both strings
else:
return return user_score #if two characters do not match then end the function
return user_score
print('User score:', get_user_score())
or throw an exception:
try:
for i in user_pattern:
for j in simon_pattern:
if i == j:
user_score += 1 #adds 1 to user_score for each equal
#character in the same index for both strings
else:
raise RuntimeError() #if two characters do not match then end the loop
except RuntimeError:
pass
print('User score:', user_score)
In my program it's supposed to ask the user a question and give them 3 chances to guess the correct answer. But my "while" loop seems to give the user a 4th chance to answer the question and bypassing the "max_attempts" variable.
print('Quiz program!\n')
answer = input('What is the capital of Wisconsin? ')
attempt = 1
max_attempts = 4
while answer != 'Madison':
attempt += 1
print('You got it wrong, please try again.\n')
answer = input('What is the capital of Wisconsin? ')
if attempt == max_attempts:
print('You used the maximum number of attempts, sorry. The correct answer is "Madison"')
break
else:
print(f"Correct! Thanks for playing. It took you {attempt} attempt(s).")
All the above answers are correct, just adding a slightly different variant.
print('Quiz program!\n')
attempt = 1
max_attempts = 4
while attempt < max_attempts:
attempt += 1
answer = input('What is the capital of Wisconsin? ')
if answer == 'Madison':
print("Correct!")
break
else:
print('You got it wrong, please try again.\n')
print("Thanks for playing. It took you %s attempt(s)." %(attempt-1))
You have max_attempts = 4 - change that to 3.
You should check if the counter attempt attempt is equal to max_attempts at the beginning of the loop, before you increment the counter again, and you should set max_attempt to 3 instead:
print('Quiz program!\n')
answer = input('What is the capital of Wisconsin? ')
attempt = 1
max_attempts = 3
while answer != 'Madison':
if attempt == max_attempts:
print('You used the maximum number of attempts, sorry. The correct answer is "Madison"')
break
attempt += 1
print('You got it wrong, please try again.\n')
answer = input('What is the capital of Wisconsin? ')
else:
print(f"Correct! Thanks for playing. It took you {attempt} attempt(s).")
The problem is with your condition. It should be
attempt < max_attempts:
I also tried implementing it in a more readable way
def main():
introduction()
attempt=1
while attemptValid(attempt) and answerIsWrong(askQuestion(), attempt):
attempt += 1
def attemptValid(attempt):
max_attempts=4
if attempt < max_attempts:
return 1
print('You used the maximum number of attempts, sorry. The correct answer is "Madison"')
return 0
def answerIsWrong(answer, attempt):
if answer != 'Madison':
return 1
print(f"Correct! Thanks for playing. It took you {attempt} attempt(s).")
return 0
def introduction():
print('Quiz program!\n')
def askQuestion():
return input('What is the capital of Wisconsin? ')
main()
Surely, by adjusting the variable max_attempts to 2, 3, 4, 5 you will eventually find the right number to give you the correct behaviour. But I believe it is more important to know how to think of this issue. I would suggest to think in terms of loop invariants: Make up a condition that is always true in the loop and enforce it while you write the loop. In this case, let's make the value of attempt and the number of time of input() calls equal, and see if your loop is right:
print('Quiz program!\n')
answer = input('What is the capital of Wisconsin? ')
attempt = 1
max_attempts = 4
So your attempt set to 1 after input(). This part is OK, and satisfied the invariant (even it is before the loop). Then the loop:
while answer != 'Madison':
attempt += 1
print('You got it wrong, please try again.\n')
answer = input('What is the capital of Wisconsin? ')
if attempt == max_attempts:
print('You used the maximum number of attempts, sorry. The correct answer is "Madison"')
break
You increment attempt, then print, then call input(). I will put the attempt line right after input() call to be consistent with the code above but either case, at right before the if statement, we still have value of attempt equals to number of times we called input(). That is why you have this behaviour.
Now on how to change your code: you now knows what is "invariant" in the loop. You have to decide (1) when to do the check of attempt == max_attempts and (2) what is the right value of max_attempts to check. Other people's answer already gave you the solution.
This question already has an answer here:
Python "if" statement not working
(1 answer)
Closed 4 years ago.
I'm learning Python for fun at the moment, and it went all well until now. I'm trying to extend the "Guess the Word"-Game, for example being able to let the Player choose a Word by himself (when 2 People play, 1 chooses the Word, the other guesses) I bet that my Mistake is obvious to me as soon as you point it out, but I'm gonna ask anyway. Well, here is the Code. I put in the entire Program, even tough only the top part should matter. I just put in the rest because it isn't much and maybe you guys can understand it better then.
print("Do you wish to set the Word yourself, or let the program choose?")
user_input = input("1 for own Input - 0 for Program-Input")
if user_input == 1:
Keyword = input("Type in the Word you want to use!")
else:
Keyword = "castle"
word = list(Keyword)
length = len(word)
right = list ("_" * length)
used_letters = list()
finished = False
while finished == False:
guess = input("Guess a Letter!")
if guess not in Keyword:
print("This letter is not in the word. Sorry...")
for letter in word:
if letter == guess:
index = word.index(guess)
right[index] = guess
word[index] = "_"
if guess in used_letters[0:100]:
print("You already used that letter before!")
else:
used_letters.append(guess)
list.sort(used_letters)
print(right)
print("Used letters:")
print(used_letters)
if list(Keyword) == right:
print("You win!")
finished = True
input('Press ENTER to exit')
My problem is, I wanna add the Function to be able to choose if you want to set a Word yourself, or use the word the Program has, defined as "Keyword". But no matter what I input, it always starts with "Guess a Letter" instead of skipping down to where the program sets the Keyword. Thank you in advance for your answers! :)
There's 2 issues with your code.
You put the entire block of code into the else statement. This means that if the if user_input == 1: block ever executed, you would only ask your user for a word and then the program would end because the else statement would be skipped.
You are using if user_input == 1: as your check and this will never be true because user inputs are always read in as strings. A string 1 will never equal the integer 1. This is why your program always skips to the else statement. You need to do if int(user_input) == 1:
Whenever you collect a user's input using the input function, it is a string, not int. this means you will have to either parse the value into an int or evaluate it with a string.
option 1: parsing to int:
user_input = int(input("1 for own Input - 0 for Program-Input"))
option 2: evaluating with string:
if user_input == "1":
input returns a string not a integer so it can never be equal to 1 instead it will be equal to "1".
Plus the code for the user guessing only runs when the program chooses the word so it needs to be unindented.
As a side note your code currently registered capital letters as being different from lower case, you can fix this by putting a .lower() after each input which will turn all capital letters into lowercase.
print("Do you wish to set the Word yourself, or let the program choose?: ")
user_input = input("1 for own Input - 0 for Program-Input")
if user_input == "1":
Keyword = input("Type in the Word you want to use: ").lower()
else:
Keyword = "castle"
word = list(Keyword)
length = len(word)
right = list ("_" * length)
used_letters = list()
finished = False
while finished == False:
guess = input("Guess a Letter: ").lower()
if guess not in Keyword:
print("This letter is not in the word. Sorry...")
for letter in word:
if letter == guess:
index = word.index(guess)
right[index] = guess
word[index] = "_"
if guess in used_letters[0:100]:
print("You already used that letter before!")
else:
used_letters.append(guess)
list.sort(used_letters)
print(right)
print("Used letters:")
print(used_letters)
if list(Keyword) == right:
print("You win!")
finished = True
input('Press ENTER to exit')
I'm new to python 3 and I feel like I am learning in the worst way possible. Everything is through an online text-book called zybooks. I've been trying to understand for loops, and for the program I am supposed to write I have to use for loops.
here are the instructions: "Simon Says" is a memory game where "Simon" outputs a sequence of 10 characters (R, G, B, Y) and the user must repeat the sequence. Create a for loop that compares the two strings. For each match, add one point to user_score. Upon a mismatch, end the game. Ex: The following patterns yield a user_score of 4:
simonPattern: R, R, G, B, R, Y, Y, B, G, Y
userPattern: R, R, G, B, B, R, Y, B, G, Y
to start I am given this:
user_score = 0
simon_pattern = 'RRGBRYYBGY'
user_pattern = 'RRGBBRYBGY'
print('User score:', user_score)
I have passed the first "test" with this code:
user_score = 0
simon_pattern = 'RRGBRYYBGY'
user_pattern = 'RRGBBRYBGY'
for simon_pattern in str(simon_pattern):
for user_pattern in str(user_pattern):
if str(simon_pattern) == str(user_pattern):
user_score += 1
continue
if str(simon_pattern) != str(user_pattern):
break
print('User score:', user_score)
the problem is when it goes to do the second test my output is still User score: 4 instead of User score: 7 (the strings for simon_pattern and user_pattern change for the second test.)
I know I need to compare each element in the string to each other one at a time and add +1, and as soon as two elements don't match my loop needs to stop. I have tried:
user_score = 0
simon_pattern = 'RRGBRYYBGY'
user_pattern = 'RRGBBRYBGY'
for s in simon_pattern:
for u in user_pattern:
if simon_pattern [0] == user_pattern [0]:
user_score += 1
if simon_pattern [0] != user_pattern [0]:
break
if simon_pattern [1] == user_pattern [1]:
user_score += 1
if simon_pattern [1] != user_pattern [1]:
break
(and then I continue the above loops until I get to [9] and print the user_score, but that doesn't work, either.)
I've tried comparing len(simon_pattern) to len(user_pattern) but that just throws back an error telling me that it can't perform that function because I have strings and not integers.
I'm wondering if someone can tell me what I'm doing wrong or point me in the right direction. Because at this point I don't know what I'm doing wrong and why. I'm sorry this is really long, but I wanted to explain as thoroughly as I could. Thank you for your help.
You'd have a much easier time using an index :
user_score = 0
simon_pattern = 'RRGBRYYBGY'
user_pattern = 'RRGBBRYBGY'
for i in range(len(simon_pattern)):
if user_pattern[i] == simon_pattern[i]:
user_score += 1
The issue with your second attempt code (for s in simon_pattern ...) is that you were comparing every s in simon_pattern to every u in user_pattern). You need to correlate these (usually with an index) so that you only compare the first to the first, second to the second etc.
Using index to iterate through each loop you need some number that increases as you go through each iteration. you can just use user_score since it is already assigned to 0, and going to increase after each iteration by 1. You will probably say "but it is going to be increased only if there is a match!" (this is right)! but if there is mismatch you are going to break out of the loop anyways, and end the game so this it's a perfect.
user_score = 0
simon_pattern = input()
user_pattern = input()
for i in simon_pattern:
if user_pattern[user_score] == simon_pattern[user_score]:
user_score += 1
else:
break
print('User score:', user_score)
user_score = 0
simon_pattern = input()
user_pattern = input()
for i in range(len(simon_pattern)): # loop for each letter in simon_pattern
if user_pattern[i] == simon_pattern[i]: # if user matches simon
user_score += 1 # add 1 to the user_score
else: # otherwise exit the game
break
print('User score:', user_score) #output final score
If you need to do it with continues and breaks like I had to, it would be something like this:
user_score = 0
simon_pattern = input()
user_pattern = input()
for i in range(len(simon_pattern)):
if user_pattern[i] == simon_pattern[i]:
user_score += 1
continue
else:
break
print('User score:', user_score)
user_score = 0
simon_pattern = input()
user_pattern = input()
x = 0
for n in simon_pattern:
if n == user_pattern[x]:
x += 1
user_score += 1
else:
break
print(f'User score: {user_score}')
the "most useful" answer above is missing the break which will cause the tests to fail. Use the code below to pass all the tests. As many people suggested, using an index is your best bet and gives you the cleanest code as well.
user_score = 0
simon_pattern = input()
user_pattern = input()
for i in range(len(simon_pattern)):
if user_pattern[i] == simon_pattern[i]:
user_score += 1
else:
break
print('User score:', user_score)