This is difficult without just laying the function out first so here we go. FYI, this is essentially a medical diagnostic program I'm making.
def patient_discussion(patient, q_count): #q_count keeps track of the number of questions asked.
response_list = ['n', 'menu']
if q_count == 0:
question = input('''What would you like to ask the patient? You can ask them for/about:
N = Their name.
Or type "main" to go back to the main screen. ''')
else:
question = ('What would you like to ask the patient? ') #This is to avoid spitting out a huge block of text. I think it's important the first time but not the rest.
if question.lower() == "n":
print("My name is "+ patient['Name'] + ". ")
q_count += 1
print()
patient_discussion(patient, q_count) #This is to loop back in case the player wants to ask additional questions.
if question.lower() == "main": #To bring the patient back to the main screen if they want.
menu(patient)
if question.lower() not in response_list: #To prevent an error.
print("What the heck are you even asking me, doc?")
print()
q_count += 1
patient_discussion(patient, q_count)
When I do this, there's a recursively loop error.
RecursionError: maximum recursion depth exceeded while calling a Python object
And I know what's happening. The original function is called as
patient_discussion(patient, 0)
And when I ask a question, the q_count goes up to 1 then 2 and so on and so forth. I just don't know why it's even looping to an incorrect answer since "n" would be in the above list.
I'd appreciate any help.
Related
I am currently taking part of a beginner Python code challenge and whilst my code runs how it should, the solution is written differently to my program.
As I am just starting out, I was wondering which way is more preferable to write the program,
The solution is:
# Prompt user if they want to proceed. Y/N?
should_proceed = input("Do you want to proceed? Y/N ")
# If they want to proceed
if should_proceed.lower() == "y":
# print out to the screen "SOLD!" to confirm purchase
# TODO: Gatjer credit card information and process it.
print("SOLD!")
# and then decrement the tickets remaining by the number of tickets purchased
tickets_remaining -= num_tickets
# Otherwise...
else:
# Thank them by name
print("Thank you anyways, {}!".format(name))
Whereas, I have put:
# Prompt user if they want to proceed. Y/N?
proceed = input("Would you like to proceed? Y/N ").upper()
# If they want to proceed
if proceed == "Y":
# print out to the screen "SOLD!" to confirm purchase
# TODO: Gatjer credit card information and process it.
print("SOLD!")
# and then decrement the tickets remaining by the number of tickets purchased
tickets_remaining = tickets_remaining - ticket_request
print(tickets_remaining)
# Otherwise...
elif proceed == "N":
# Thank them by name
print("Thank you for your time, {}".format(customer_name))
Was it incorrect to call upper() on the input?
Is there any other errors I have done?
Many thanks,
Was it incorrect to call upper() on the input?
No, this is a perfectly fine way to allow case-insensitive input. Their solution shows an alternative that works just as well.
Both ways are fine with one caveat. Because you are specifically checking for both Y and N, your way is probably better in that case since you would otherwise have to call upper() twice:
proceed = input("Would you like to proceed? Y/N ")
if proceed.upper() == "Y":
doSomething()
elif proceed.upper() == "N":
doSomethingElse()
On that enhanced checking, your code is slightly different in that it does nothing if the input is neither Y nor N (the other code treats anything that's not y as n). In that case, you're probably wise to ensure it is one of those values, with something like:
proceed = ""
while proceed != "Y" and proceed != "N":
proceed = input("Would you like to proceed (Y/N)? ").upper()
I'm working on a HW assignment where I create a fake club with entry questions. If any of the questions are answered with "no", then the person isn't allowed to join.
I've tried going back to the og lessons about lists and loops, but I can't find what I'm trying to do on there.
Here's my code so far.
# Purpose: Create a fake club that has certain requirements, ask user to
# fill out the application, and print out their answers + results.
def main():
display = input('Hi! This is your application to The Aqua Project...')
display2 = input('Read the following questions and just type y or n')
# Weird list format...
user = [input('Are you at least 18 yrs old? '),
input('Can you work with other people? '),
input('Do you like animals? '),
input('Are you okay with getting dirty sometimes? ')]
# Here's the problem, I want to print 'sorry you cant join' once...
for i in range(4):
if user[i] != 'y':
print('Sorry, but you can\'t join our club')
justToShowInCMD = input('')
i += 1
else:
print('')
print('Congratulations, you have met all of our requirements!')
print('We will send an email soon to discuss when our team')
print('will meet up to help save some animals!')
print('In the meantime, visit our website at
TheAquaProject.com')
justToShowInCMD = input('')
main()
When you put a 'n' for some questions it says you can join, but for others it says you can't join. I don't know why sometimes it says you can when you placed a no in the interview, it shouldn't.
The usual ways to do this are a for loop with a break and an else clause:
for answer in user:
if answer != 'y':
print('Sorry')
break
else:
print('Congratulations')
Or the any() function:
if any(answer != 'y' for answer in user):
print('Sorry')
else:
print('Congratulations')
If one "no" means decline, you can add break to exit the loop after print decline info. Just like:
for i in range(4):
if user[i] != 'y':
print('Sorry, but you can\'t join our club')
justToShowInCMD = input('')
# i += 1 # <<<<<<<<<<<<<<<<<< this code may be not needed here
break # <<<<<<<<<<<<<<<<<< where to add break
else:
print('')
print('Congratulations, you have met all of our requirements!')
print('We will send an email soon to discuss when our team')
print('will meet up to help save some animals!')
print('In the meantime, visit our website at
TheAquaProject.com')
justToShowInCMD = input('')
or you can use a variable to indicate whether to decline, just like:
toDecline = False
for i in range(4):
if user[i] != 'y':
toDecline = True
if toDecline:
print('Sorry, but you can\'t join our club')
justToShowInCMD = input('')
else:
print('')
print('Congratulations, you have met all of our requirements!')
print('We will send an email soon to discuss when our team')
print('will meet up to help save some animals!')
print('In the meantime, visit our website at
TheAquaProject.com')
justToShowInCMD = input('')
There are a few ways to do this:
Use a flag variable and just output at the end. (Slightly inefficient if the first response is a no)
Use a flag variable and a while loop to exit as soon as the user responds with no. (Can be slightly confusing)
Use the builtin any method. (Can be confusing, not recommended)
flag = True
for i in range(4):
if user[i] != 'y':
flag = False # User has answered no to something, set the flag to false
if flag: # User has answered yes to everything
# <do your `yes` output>
else: # User has answered no to something
# <do your `no` output>
there are some small points in your code that need to be changed:
# Purpose: Create a fake club that has certain requirements, ask user to
# fill out the application, and print out their answers + results.
def main():
display = input('Hi! This is your application to The Aqua Project...')
display2 = input('Read the following questions and just type y or n')
# Weird list format...
user = [input('Are you at least 18 yrs old? '),
input('Can you work with other people? '),
input('Do you like animals? '),
input('Are you okay with getting dirty sometimes? ')]
# you define a variable inside function main
# and assign a list to it
# this variable will not be visible outside
# you should just return it
return user
# Here's the problem, I want to print 'sorry you cant join' once...
# call your function before you test the answer
# and assign the the result of the function to a
# variable you can use in your check
user= main()
# define a flag variabe to
# see if the answers are ok according your check
ok= True
for i in range(4):
if user[i].lower()[:1] != 'y':
# you could also use your original code
# in the check. The code above is an example
# how you could make sure the user can enter
# upper/lower case letters and also "yes"
# and "y" [:1] cuts off 1 character
# if the string is non-empty, otherwise it
# returns an empty string
print('Sorry, but you can\'t join our club')
justToShowInCMD = input('')
i += 1
# memorize that some question wasn't ok
ok= False
# I guess here you might want to exit the loop?
# so use a break, otherwise the other answers
# would be checked as well and the message
# output several times per user in some cases
break
if ok:
# this code here doesn't belong in the loop body
# I guess. It should be executed after all questions
# have been checked positive (which is only known
# after the loop has been executed)
# So here we are sure the answers were yes, because
# otherwise we would have set ok to False
print('')
print('Congratulations, you have met all of our requirements!')
print('We will send an email soon to discuss when our team')
print('will meet up to help save some animals!')
print('In the meantime, visit our website at TheAquaProject.com')
justToShowInCMD = input('')
# if you call your function here, you can't check
# the result of the input() calls because
# by the time you check it it has not been entered
I would suggest storing your questions in a list and using a for loop to ask them. Store the user's response to another list and check if there is any "n" in this list. See code below:
questions = ["Are you at least 18 yrs old?", "Can you work with other people?", "Do you like animals?", "Are you okay with getting dirty sometimes?"]
answers = list()
for question in questions:
user_answer = input(f"[y/n] {question}: ").lower()
answers.append(user_answer)
if "n" in answers:
print("Sorry, you can't join our club.")
else:
print("Congrats! You are in!!")
# you can print your desired messages as well.
Assuming you are iterating 4 times (using range(4))based on the length of user, what you can simple do is the following:
if 'n' or 'no' in user:
print('Sorry, but you can\'t join our club')
justToShowInCMD = input('')
else:
print('')
print('Congratulations, you have met all of our requirements!')
print('We will send an email soon to discuss when our team')
print('will meet up to help save some animals!')
print('In the meantime, visit our website at
TheAquaProject.com')
justToShowInCMD = input('')
You can modify the if condition to cater to other forms of negative answers like 'N' or 'No'. You don't need to iterate over user.
Comments on OP main():
A key point of programming, is code use efficiency.
Don't repeatedly call functions (e.g. input and print) when not necessary.
There are several ways your problem can be solved.
The other answers focus on your original user list, complete with repeatedly calling input
Once user executes, it essentially becomes a list of y and or n values, which you then unpack with a loop to check the values.
Another problem with the user list method, is it requires all of the questions to be answered, prior to disqualification. What if there were 40 questions? I'd be annoyed.
Incidentally, a list can be unpacked as follows: for value in user:. There is no need to address the list by index with python.
Updated main() implementation:
def print_list(values: list):
"""Print the values of a list"""
for value in values:
print(value)
def main():
"""Iterate through a questionnaire"""
# Variables at the top
intro = ['Hi! This is your application to The Aqua Project...',
'Read the following questions and just type y or n']
questions = ['Are you at least 18 yrs old? ',
'Can you work with other people? ',
'Do you like animals? ',
'Are you okay with getting dirty sometimes? ']
final = ['\nCongratulations, you have met all of our requirements!',
'We will send an email soon to discuss when our team',
'will meet up to help save some animals!',
'In the meantime, visit our website at www.TheAquaProject.com']
print_list(intro)
for i, question in enumerate(questions, start=1):
response = input(question)
if response == 'n': # can be replaced with != 'y'
print("Sorry, you can't join the club!")
break
if i == len(questions):
print_list(final)
Comments on updated main():
Instead of calling print a lot, store the text in a list and then call the print_list function to do the printing.
Keep custom functions separate
Custom functions should perform one function
values: list this is a type hint, which tells what data type the values parameter of print_list should be.
Annotations
"""""": use docstrings
Documenting Python Code: A Complete Guide
Double space between functions: How to Write Beautiful Python Code With PEP 8
main(): Defining Main Functions in Python
questions is obvious, it's just the questions from user, as a list without calling input
unpack questions with a for-loop and use the built-in function: enumerate.
There are many Built-in Functions
i goes with enumerate to count.
Other languages create a dummy variable, like count = 0, then use count+=1 to track loop iteration; this is considered not pythonic. Python uses enumerate, but only if you need a count for implementing something else.
if condition checks if response is n
If the if condition evaluates as True (e.g. when response = n, n == n is True), the user gets the sorry message, break, ends the loop, and the questionnaire is complete.
There are no nicities here, the function does not check to make certain a user enters y, it only checks for n. That wasn't in the scope of the question.
The start parameter of enumerate is set to 1. If all the questions are answered, i=4 and len(questions)=4 so i == len(questions) evaluates as True and the user gets the congratulations message.
len(questions) is used instead of 4, because it's a bad idea to hardcode in values like that, because then you have to remember you've done so. What if the number of questions changes? Then your if condition is broken.
Resources:
I'm not affiliated with RealPython, but they are a great source of incredibly in depth tutorials.
Lists and Tuples in Python
Basic Data Types in Python
I'm creating a quiz for my GCSE where a person is given the musical and the first letters of the song, they then must guess the entire song. The part I'm having trouble with is that even though I get the question right, it is telling me I am wrong. I'm also using a CSV file to store the questions and answers.
I have tried changing the variable many, many times and I'm really not sure what else to do. Currently the loop is still open, but the code is not finished yet and I cannot move on until I've done this.
while fail!= True:
randomN = random.randint(0, totalQu - 1)
musical = questions[randomN][0]
title = questions[randomN][1]
title_split = title.split()
new = []
for title in title_split:
letter=title[0].upper()
new.append(letter)
ans=" ".join(new)
print(musical+",",ans)
answer = input()
if answer == title:
print("That is CORRECT")
score = score + 3
elif answer != title:
print("That is INCORRECT. Try again")
If the question is "Dear Evan Hansen, F F" then the answer is "For Forever" but if I input this it tells me I am wrong. The variable 'title' is for some reason, only the first word? For example, in this case it would be "Forever".
So I am a total beginner yet this is 100% my code and I am proud of it. Now mind you I need a little cleaning up, however it does what I want it too. My issue is this: In order to turn this in for credit, one of the things is that procedures(functions) should not contain more than 18 lines. My function gameCont() has many more. Would anyone have suggestions on how I could shorten it up? Additionally I am obviously challenged when it comes to function parameters so any help is appreciated. Please be gentle as I am BRAND NEW! :)
game1 = "When dealing with SCUBA diving there are many dangers to consider. The very first one is _1_. \
I mean if you take water into your lungs, you are NOT SCUBA diving. Another is rising to the surface too quickly which could \
result in the _2_. Now this is a funny name, as I am sure when it happens, you dont feel 'bendy'. Let's also consider Nitrogen Narcosis.\
If you dont know what that is, well when you are very deep and your body is absorbing more nitrogen than it is used to, you can get \
feeling kinda _3_ feeling as though you just drank not one, but _4_ martinis"
game1_answers = ["drowning", "bends", "drunk", "2"]
game2 = "When you first learn to dive you are taught to do dives within a no DECOmpression limit(NDL). \n This means you do not want to \
stay that deep too long or you will rack up _1_. \n If you DO stay longer than what the NDL allows, you will have an obligation to \
take your time getting to the surface allowing that _2_ gas to leave your body. If you were taking IN gas you may call it \
in-gassing, but when you are decompressing, it may be called _3_-gassing. You are taught also, how to read _4_"
game2_answers = ["deco", "nitrogen", "off", "tables"]
game3 = "Equipment used by cold water divers such as myself are as such. On my head I would wear a _1_. To help regulate the breathing\
pressure from my SCUBA tank I would use a _2_. To help me propel through the water I would place_3_ on my feet. Considering \
we cannot see underwater I need to be wearing a _4_ on my face. Diving in the tropic, many people would use wetsuits, however it's\
very cold where I dive so we wear _5_ suits."
game3_answers = ["hood", "regulator", "fins", "mask", "dry"]
def howManyTries():
gameTries = raw_input("Thanks for giving my quiz a try, how many attempts do you want? ")
return int(gameTries)
def game_choice(): #this function is used to determin which difficulty the user wants and returns the proper game and answer list
user_input = raw_input("Greetings. This is my Udacity project for fill in the blanks. Which one of my options would you like?\
easy, hard, or hardest? Please take note of capitalization ")# this will define the user_input variable to raw input placed in by user
print ("\n" * 20)# just something to clean up the screen
print "Decided to choose " + user_input + '?' " Well " + user_input + " it is"# this confirms to the user which difficulty they chose.
print ""
print ""
if user_input == "easy": #easy returns game1 and game1 answers
return game1, game1_answers
elif user_input == "hard": # hard returns game2 and game2 answers
return game2, game2_answers
elif user_input == "hardest": #hardest returns game3 and game 3 answers
return game3, game3_answers
else:
print "It seems that " + user_input + " is not a valid response" #in case the user doesnt choose or spell choice correctly
def gameCont():
blanks = 1 #this assings blank to 1 which will tell the user which blank they are guessing in below prompt
attempts = howManyTries() #this calls the howManyTries function for a user choice integer
quiz, answers = game_choice() #this returns 2 values (game# and game# answers)
while attempts > 0: #while attempts (called from function) is greater than 0 we will loop this
print quiz #prints the chosen quiz for user updated each time the loop runs with correct answer
print("\n" * 10) #clears some more screen to loook better for the user
guess = raw_input("Reading the above paragraph, What would your guess be for _" + str(blanks) + "_") #asks for guess for current blank which always starts at 1
print("\n" * 10) #clears some more screen to loook better for the user
if guess == answers[blanks - 1]: #because indexing count starts at zero, and blanks start at 1 this will check if answer is equal to blanks - 1
print "As you can see your correct choice has replaced the variable, great job!!"#this will print if the guess is correct
quiz = quiz.replace("_" + str(blanks) +"_", answers[blanks - 1]) # here is the line of code that replaces the blank with the correct guess
blanks += 1 # this adds 1 to the blank which will prompt the user to move to the NEXT blank when loop begins again
if blanks > len(answers):
print ("\n" * 10)
print "YOU DID IT!! Here is the final paragraph with all the correct answers"
print ("\n" * 2)
print quiz
break
elif guess != answers[blanks -1]: #if the answer does not match the list index
attempts = attempts - 1 #then we will subtract 1 from the attempts
print ("\n" * 10)
print "Oops that is not correct, there should be hints in the paragraph" # lets user know they were wrong
print "You have " + str(attempts) + " attempts left." # lets the user know how many attempts they have left
print ""
if attempts < 1:
print "Well it looks like you are out of choices, Try again?"
break
print "Thanks for playing"
gameCont()
All of the printing that you're doing could be done in a separate function
def game_print(newlines_before, text, newlines_after)
print ("\n" * newlines_before + text + "\n" * newlines_after)
Two suggestions:
Delegate tasks that are accomplished by your function to smaller functions. So, for example, if you had a function that needed perform task A and performing that task could be divided into tasks B, C, and D, then create helper functions and call them inside of the function that does task A.
You have long strings, maybe store them somewhere else? Create a class just for constant strings of related functions and access that when you need a particular string. It'll make it less likely that you'll make a mistake when you need to use that string in multiple locations.
class Constants:
str1 = "..."
str2 = "..."
print(Constants.str1)
you can call a function from inside another function. inside an if statement you could call a small new function that just prints some stuff. this should make it easy to get the function size down.
something like this should work:
def correct(quiz, blanks):
print "As you can see your correct choice has replaced the variable, great job!!"
quiz = quiz.replace("_" + str(blanks) +"_", answers[blanks - 1]) # here is the line of code that replaces the blank with the correct guess
blanks += 1 # this adds 1 to the blank which will prompt the user to move to the NEXT blank when loop begins again
if blanks > len(answers):
print ("\n" * 10)
print "YOU DID IT!! Here is the final paragraph with all the correct answers"
print ("\n" * 2)
print quiz`
remember that you still want to break after calling that function in order to exit your loop.
Pretty new to python/programming in general, this is my biggest project yet.
I am writing a program that will do SUVAT equations for you. (SUVAT equations are used to find the displacement, start/end velocity, acceleration and time travelled by an object with constant velocity, you may call them something different.)
I made this list:
variables = ["Displacement", "Start Velocity", "End Velocity", "Acceleration", "Time"]
which is used in the following while/for loop:
a = 0
while a==0:
for variable in variables:
# choice1 is what the user is looking to calculate
choice1 = raw_input("Welcome to Mattin's SVUVAT Simulator! Choose the value you are trying to find. You can pick from " + str(variables))
# will execute the following code when the for loop reaches an item that matches the raw_input
if choice1 == variable:
print "You chave chosen", choice1
variables.remove(variable) #Removes the chosen variable from the list, so the new list can be used later on
a = 1 # Ends the for loop by making the while loop false
# This part is so that the error message will not show when the raw_input does not match with the 4 items in the list the user has not chosen
else:
if choice1 == "Displacement":
pass
elif choice1 == "Start Velocity":
pass
elif choice1 == "End Velocity":
pass
elif choice1 == "Acceleration":
pass
# This error message will show if the input did not match any item in the list
else:
print "Sorry, I didn't understand that, try again. Make sure your spelling is correct (Case Sensitive), and that you did not inlcude the quotation marks."
Hopefully the comments I have written in the code should explain my intentions, if not, feel free to ask anything.
The problem is that when I run the code, and input choice1, the for loop activates the last line of code:
else:
print "Sorry, I didn't understand that, try again. Make sure your spelling is correct (Case Sensitive), and that you did not inlcude the quotation marks."
and then prompts me to enter the input again, and will do this as many times as it needs to get to the item on the list that I am typing.
However, I specifically coded that if what I input does not match the item on the list the for loop is currently checking, but does match one of the other items on the list, then it should pass and loop round to checking the next item.
I am probably doing something stupid, but I don't see it, so please help me figure out what I have to do to get my desired result? I assumed it was the syntax I had wrong so that is why that is the title.
Thanks for any help, I appreciate it.
Besides the problem with the indentation in your pasted code, I would rewrite it as such:
while True:
choice = raw_input('...')
if choice in variables:
print "You chave chosen", choice
# Remove the chosen member from the list
variables = [v for v in variables if v != choice]
# Break out of loop
break
# Print error messages etc.
Also remember that string comparisons are case sensitive. I.e 'Displacement' != 'displacement'.