Python program does not behave as intended - python

I'm writing my first short programs with Python. This program should stop after the third wrong guess. The program works as expected with the first question, and stops itself after three wrong guesses.
However, I cannot understand why, with the second question, after the third wrong guess, the first question is repeated.
easy_text = '''Hello __1__!' In __2__ this is particularly easy; all you
have to do is type in: __3__ "Hello __1__!" Of course, that isn't a very
useful thing to do. However, it is an example of how to output to the user
using the __3__ command, and produces a program which does something, so it
is useful in that capacity..'''
def split_string():
global easy_text_splitted
easy_text_splitted = easy_text.split(" ")
return None
def level1():
print """You will get 3 guesses per problem
The current paragraph reads as such:"""
print easy_text
return first_question(3)
def first_question(guesses):
while guesses > 0:
split_string()
first_answer = raw_input("What should be substituted in for __1__?")
if first_answer.lower() == "world":
easy_text_splitted[1] = first_answer
easy_text_splitted[19] = first_answer
new_easy_text = " ".join(easy_text_splitted)
print new_easy_text
second_question(3)
else:
guesses -= 1
print "That's not the answer I expected. You have " +
str(guesses) + " guess(es) left"
return first_question(guesses)
def second_question(guesses):
while guesses > 0:
split_string()
second_answer = raw_input("What should be substituted in for 2?")
if second_answer.lower() == "python":
easy_text_splitted[4] = second_answer
new_easy_text = " ".join(easy_text_splitted)
print new_easy_text
else:
guesses -= 1
print "That's not the answer I expected. You have \n " +
str(guesses) + " guess(es) left"
return second_question(guesses)
def level_selection(index):
level = raw_input("Choose the desired level of difficulty: easy, \n
medium, or hard ")
if level.lower() == "easy":
return level1()
if level.lower() == "medium":
return level2
if level.lower() == "hard":
return level3
else:
print "Error"
index -= 1
if index > 0:
return level_selection(index)
return "Bye!"
print level_selection(3)
level2 = "You selected medium"
level3 = "You selected hard"

Whatever the value of guesses was in first_question when second_question was called, it is the same when it returns, so the loop continues, and repeats the first question.
Using a debugger will help you follow how this works.

Related

How to fix the logic of "Guess the Movie" Game i have written in Python

So, I was doing an online course for python, and there was a test sample code for the "Guess The Movie", game. However, I tried to write it myself following almost the same logic but there seems to be an error where multiple letters are being unlocked rather than only one.
for Example:
ROB , your turn
Your letter:o
o * l
As you can see instead of showing that only the letter 'o' is unlocked, the last letter 'l' is also unlocked even though i have not entered it previously.the movie here is called 'Soul'.
and upon entering the letter 'S' it shows:
Press 1 to guess the movie or 2 to unlock another character 2
Your letter:S
S o u l
The movie is completely unlocked.If you can find the mistake in my code, please give me a solution.
My Code:
import random
Films=["Deadpool","Avengers Endgame","Drishyam","Hera Pheri","Munna Bhai MBBS","Justice League","The Dark Knight","Cars","Titanic","Haseena Man Jayegi","Uri Surgical Strike","Guardians of the Galaxy","Interstellar","Inception","The Great Gatsby","John Wick","Spiderman Homecoming","Bajirao Mastani","Nobody","Life of Pi","Krish","Golmaal","Housefull","Zindagi Na Milegi Dobara","3 idiots","Dangal","Badshah","The Shawshank Redemption","Frozen","Soul","Despicable Me","Minions","Crossroads"]
def create_question(Movie):
n=len(Movie)
letters=list(Movie)
temp=[]
for i in range(n):
if letters[i]== " ":
temp.append(" ")
else:
temp.append("*")
Q =" ".join(str(x) for x in temp)
return Q
def is_present(letter,Movie):
c=Movie.count(letter)
if c==0:
return False
else:
return True
def unlock(Q,picked_Movie,letter):
ref=list(picked_Movie)
Q_list=list(Q)
temp=[]
n=len(picked_Movie)
for i in range(n):
if ref[i]==" " or ref[i]==letter:
temp.append(ref[i])
else:
if Q_list[i]=="*":
temp.append("*")
else:
temp.append(ref[i])
Q_new =" ".join(str(x) for x in temp)
return Q_new
def game():
pA=input("Player 1 Name:")
pB=input("Player 2 Name:")
pp1=0
pp2=0
turn=0
willing=True
while willing:
if turn%2==0:
print(pA,",your turn")
picked_Movie=random.choice(Films)
Q=create_question(picked_Movie)
print(Q)
modified_Q=Q
not_said=True
while not_said:
letter=input("Your letter:")
if(is_present(letter,picked_Movie)):
modified_Q = unlock(modified_Q,picked_Movie,letter)
print(modified_Q)
d=int(input("Press 1 to guess the movie or 2 to unlock another character"))
if d==1:
ans=input("Answer:")
if ans==picked_Movie:
print("Yay! Correct answer.")
pp1=pp1+1
print(pA,"'s Score=",pp1)
not_said=False
else:
print("Wrong Answer, Try again...")
else:
print(letter,'not found')
c=int(input("press 1 to continue or 0 to exit:"))
if c==0:
print(pA,",Your Score is",pp1)
print(pB,",Your Score is",pp2)
print("Thank you for playing, have a nice day!!!")
willing=False
else:
print(pB,",your turn")
picked_Movie=random.choice(Films)
Q=create_question(picked_Movie)
print(Q)
modified_Q=Q
not_said=True
while not_said:
letter=input("Your letter:")
if(is_present(letter,picked_Movie)):
modified_Q = unlock(modified_Q,picked_Movie,letter)
print(modified_Q)
d=int(input("Press 1 to guess the movie or 2 to unlock another character:"))
if d==1:
ans=input("Answer:")
if ans==picked_Movie:
print("Yay! Correct answer.")
pp2=pp2+1
print(pB,"'s Score=",pp2)
not_said=False
else:
print("Wrong Answer, Try again...")
else:
print(letter,'not found')
c=int(input("press 1 to continue or 0 to exit:"))
if c==0:
print(pA,",Your Score is",pp1)
print(pB,",Your Score is",pp2)
print("Thank you for playing, have a nice day!!!")
willing=False
turn=turn+1
game()
I just changed unlock() method as below (changes are mentioned as comment):
def unlock(Q,picked_Movie,letter):
ref=list(picked_Movie)
Q_list=list(Q)
temp=[]
n=len(picked_Movie)
for i in range(n):
if ref[i]==" " or ref[i]==letter:
temp.append(ref[i])
else:
if Q_list[i]=="*" or Q_list[i] == " ": #Added 1 more condition Q_list[i] == " "
temp.append("*")
else:
temp.append(ref[i])
Q_new ="".join(str(x) for x in temp) #Replaced " " to ""
return Q_new
After a few times I run your code, tested it, I found the problem:
Inside unlock function, you did a mistake:
for i in range(n):
if ref[i]==" " or ref[i]==letter:
temp.append(ref[i])
else:
if Q_list[i]=="*":
temp.append("*")
else:
temp.append(ref[i])
You only checked if the Q_list[i] has *. But what if it has " " in it? Then you will get another letter from ref[i] for no reason!
The only thing you need to do is to modify the if statement:
for i in range(n):
if ref[i]==" " or ref[i]==letter:
temp.append(ref[i])
else:
if Q_list[i]=="*" or Q_list[i] == " ": # <-- FIX HERE
temp.append("*")
else:
temp.append(ref[i])
EDIT:
I saw that in some cases my code still doesn't work, and this is why:
If the movie name had " " in it, then the
Q_list will be bigger then ref which will give us unexpected results.
You can fix it easily, removing all the " " between the *.
Everywhere you have:
" ".join(str(x) for x in temp)
this in your code (twice actually), changes it to:
"".join(str(x) for x in temp)

cant seem to get this procedure to print outut in bash

So when I run this on sublime ctrl-b I get the following output:
2
this is a example string with a _x_
ok so you have 3 left
What is your guess?
However when I run this in git-bash it simply runs, no errors, no output, no request for user input. I am new at this, and this is just a small part of a school quiz I am doing. Any suggestions?
string1 = "this is a example string with a _x_"
sample_list = [1, 2, 3]
def main():
print (sample_list[1])
print (string1)
chances = 3
while chances > 0:
print ("ok so you have " + str(chances) + " left")
answer = input("What is your guess?")
if answer == sample_list[0]:
print ("Great, here is your new string!")
print (string1.replace('_x_', str(sample_list[1])))
elif answer != sample_list[1]:
print ("Aw Schucks")
chances -= 1
print ("Out of chances")
main()

Adding or subtracting a variable from a running total based on a condition

I'm making a simple trivia game. What I have below prompts the user and displays a question in an interactive way.
I want to add in a "score" feature. Whenever I try to initialize a "count" at 0 or something similar within my Question class, and increment by the value stored in value, count stays at 0. I'm having trouble here. Ideally I want to print the score after the user answers each question. Adding self.value to count if correct, and subtracting otherwise.
import random
class Question(object):
def __init__(self, question, answer, value):
self.question = question
self.answer = answer
self.value = value
def ask(self):
print (self.question + "?")
count = 0
response = input().strip()
if response in self.answer:
x = random.randint(0,3)
print (positives[x])
print ("Answer is" + " " + self.answer)
else:
y = random.randint(0,3)
print (negatives[y])
print ("Answer is" + " " + self.answer)
question_answer_value_tuples = [('This author made a University of Virginia law professor the protagonist of his 2002 novel "The Summons"',
'(John) Grisham']
#there are a few hundred of these. This is an example that I read into Question. List of tuples I made from a jeopardy dataset.
positives = ["Correct!", "Nice Job", "Smooth", "Smarty"]
negatives = ["Wrong!", "Think Again", "Incorrect", "So Sorry" ]
questions = []
for (q,a,v) in question_answer_value_tuples:
questions.append(Question(q,a,v))
print ("Press any key for a new question, or 'quit' to quit. Enjoy!")
for question in questions:
print ("Continue?")
choice = input()
if choice in ["quit", "no", "exit", "escape", "leave"]:
break
question.ask()
I want to add something like
count = 0
if response in self.answer:
count += self.value
else:
count -= self.value
print (count)
I think I'm having trouble with local/global variables.
Everytime you call "ask" you are resetting count to 0. Also count is a local variable since it is only defined inside ask(). You need to make count a member of the class and initialize it to 0. Then you can use it like the other class variables. See code below.
def __init__(self, question, answer, value):
self.question = question
self.answer = answer
self.value = value
self.count=0
def ask(self):
print (self.question + "?")
response = input().strip()
if response in self.answer:
x = random.randint(0,3)
print (positives[x])
print ("Answer is" + " " + self.answer)
self.count += self.value
... etc
But I am not happy with your logic of including your score inside your question class - because the score relates to numerous questions so it would need to be either globally defined in your class or outside of the class so when you call your method ask it should return whether the answer was true or false or the value, like this
def ask(self):
print (self.question + "?")
count = 0
response = input().strip()
if response in self.answer:
x = random.randint(0,3)
print (positives[x])
print ("Answer is" + " " + self.answer)
return self.value
else:
y = random.randint(0,3)
return 0
then you do the following;
score=0
for question in questions:
print ("Continue?")
choice = input()
if choice in ["quit", "no", "exit", "escape", "leave"]:
break
score+=question.ask()

Nested If Expression with user validation - repeating the prompt for user input

Thank you #Idor I am making some progress but I am not 100% there yet. Right now my code looks as following:
def easy_game(easy_text, parts_of_speech1):
replaced = []
easy_text = easy_text.split()
i = 0
for word in easy_text:
replacement = word_in_pos_easy(word, parts_of_speech1)
if replacement != None:
user_input = raw_input("Type in: " + replacement + " ")
word = word.replace(replacement, user_input)
while word != solutions[i]:
print "Sorry, you are wrong"
user_input = raw_input("Type in: " + replacement + " ")
print i
i = i + 1
print i
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
print
#time.sleep(1)
print "Ok, lets see your results. Does it make sense?"
print
#time.sleep(1)
return replaced
print
#time.sleep(1)
print easy_game(easy_text, parts_of_speech1)
You can see I added the while loop. I also added an index and for troubleshooting I added print i to see what the program is doing. It still confuses me a bit or doesn't work as I would expect it. But being a newbie to programming my expectations are probably wrong. Here's what's happening:
When you enter the correct answer the program continues to question 2 and also increases i by 1
This works from beginning to end if you enter everything correctly
When you enter the wrong answer you are prompted to enter it again. Good!
However the user then gets stuck in this very question although i has been increased to the right value.
I don't really understand why the user would be stuck at this point when i has been increased, i.e. we would check at the right position in the list for the correct answer.
This is the full code of the game. I can successfully run it on my Mac but see the above behavior. Any thoughts on this by any chance? thanks in advance!
parts_of_speech1 = ["Word1", "Word2", "Word3", "Word4"]
# The following is the text for the easy text..
easy_text = "Python is a Word1 language that provides constructs intended to enable clear programs on both small and large scale. Python implementation was started in December Word2 by Guido von Rossum. The most simple Word3 in Python is Word4 and normally used at the beginning to tell Python to write 'Hello World' on the screen."
solutions = ["programming", "1989", "function", "print"]
# Checks if a word in parts_of_speech is a substring of the word passed in.
def word_in_pos_easy(word, parts_of_speech1):
for pos in parts_of_speech1:
if pos in word:
return pos
return None
# Plays a full game of mad_libs. A player is prompted to replace words in the easy text,
# which appear in parts_of_speech with their own words.
def easy_game(easy_text, parts_of_speech1):
replaced = []
easy_text = easy_text.split()
i = 0
for word in easy_text:
replacement = word_in_pos_easy(word, parts_of_speech1)
if replacement != None:
user_input = raw_input("Type in: " + replacement + " ")
word = word.replace(replacement, user_input)
while word != solutions[i]:
print "Sorry, you are wrong"
user_input = raw_input("Type in: " + replacement + " ")
print i
i = i + 1
print i
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
print
#time.sleep(1)
print "Ok, lets see your results. Does it make sense?"
print
#time.sleep(1)
return replaced
print
#time.sleep(1)
print easy_game(easy_text, parts_of_speech1)
I am building out a quiz based on raw_input using several different list operations. I also want to validate the user input against a list before moving on to the next question in the quiz.
The function currently looks like this:
def play_game(ml_string, parts_of_speech):
replaced = []
ml_string = ml_string.split()
for word in ml_string:
replacement = word_in_pos(word, parts_of_speech)
if replacement != None:
user_input = raw_input("Type in a: " + replacement + " ")
word = word.replace(replacement, user_input)
if word != solution_list1[0]:
print "Sorry, you are wrong. Try again!"
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
return replaced
In Line 9 I am checking against the List containing the solution words. Whereas the validation itself works the function just continues to the next question but I need it to repeat the question until getting the correct answer. I tried to reposition the different lines but simply can't get my head around it at this point in time. Where or how do I need to place the validation of the user input correctly to prompt the user for the same question again?
It seems to me that what you are looking for is a while loop.
Instead of:
if word != solution_list1[0]:
print "Sorry, you are wrong. Try again!"
Try:
while word != solution_list1[0]:
print "Sorry, you are wrong. Try again!"
user_input = raw_input("Type in a: " + replacement + " ") # ask the user again
word = word.replace(replacement, user_input)
This way the user will have to answer the question again (raw_input) until he gets it right.

Problems transferring information from one part of a function to another

While working on my program I have run into a problem where the information stored in Menu option 1 is not being transferred to Menu option 2. As you can see it is correctly stored when in menu one. When it returns to go to menu option 2 its like it never went to option 1.
update #1:
some suggestions I've had is to understand scope? from what I can tell the program is not passing the data along to its parent program even though I've typed out return in each of the definitions.
#Must be able to store at least 4 grades
#Each class can have up to 6 tests and 8 hw's
#Weighted 40%*testavg 40% hw average attendance is 20%
#User must be able to input a minimum grade warning
#after each test the your program must calculate the students average and issue warning if necessary
##Define the Modules##
import math
def menu (a): #2nd thing to happen
menuend = 'a'
while menuend not in 'e':
menuend = raw_input("Type anything other then 'e' to continue:\n")
print "What would you like to do ?"
menudo = 0
print "1 - Enter Courses\n2 - Select Course to Edit\n3 - Save File\n4 - Load File\n5 - Exit\n"
menudo = input("Enter Selection:")
if (menudo == 1):
menuchck = 0
menuchck = raw_input("\nYou have entered #1 (y/n)?:\n")
if menuchck in ["Yes","yes","y","Y"]:
x = m1()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 2):
menuchck1 = 0
menuchck1 = raw_input("\nYou have entered #2 (y/n)?:\n")
if menuchck1 in ["Yes","yes","y","Y"]:
x = m2()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 3):
print "Entered 3"
elif (menudo == 4):
print "Entered 4"
else:
print "Anything Else Entered"
def course(): #3rd thing to happen
b = {}
while True:
while True:
print "\n",name,", please enter your courses below ('e' to end):"
coursename = raw_input("Course Name:")
if (coursename == 'e'):
break
will = None
while will not in ('y','n'):
will = raw_input('Ok for this name : %s ? (y/n)' % coursename)
if will=='y':
b[coursename] = {}
print "\n",name,", current course load:\n",b
coursechck = None
while coursechck not in ('y','n'):
coursechck = raw_input("Are your courses correct (y/n)")
if coursechck =='y':
return b
else:
b = {}
print
##Menu Options##
def m1():
a = course()
return a
def m2():
print "Excellent",name,"lets see what courses your enrolled in\n"
print x
return x
###User Input Section###
name = raw_input("Enter Students Name:\n")
a = {}
menu(a)
raw_input("This is the end, my only friend the end")
In your if-elif blocks in the do==1 case, you write m1(), but for the last case, you write x=m1(). You should have the latter everywhere (by typing m1() you only run the function, but do not store the returned x anywhere).
By the way, you can avoid this if-elif confusion using if chck in ["Yes","yes","Y","y"]:

Categories