This question already has answers here:
How do I get a result (output) from a function? How can I use the result later?
(4 answers)
Closed 5 months ago.
I am trying to use two variables (i, and q) across three functions. I want to test whether i and q are valid after each input . If they are then they will be added to list and the while loop continues. If they are not valid Then the function will stop and all input will be taken and presented. I have tried to make both i and q global variables but it does not seem to work as it is saying that "i" is not defined. How do I check the i and q variables in separate functions?
Any help would be really appreciated as I am only new and thought this should work.
I didn't know what to add so I have put down the three functions in full below:
Updated:
def add_item():
code_inputed = []
quan_inputed = []
VC()
VQ()
vc_result = VC(I)
vq_result = VQ(q)
while True:
if i != "END":
if vc_result == True and vq_result == True:
code_inputed.append(int(i))
quan_inputed.append(int(q))
elif vc_result == True and vq_result == False:
print("Invalid Quanity")
break
elif vc_result == False and vq_result == True:
print ("Invalid code")
break
else:
print("Invalid inputs")
break
return code_inputed,quan_inputed
def VC():
i = input("enter code: ")
minimum = 0
maxiumum = 39
if i == "END":
return False
elif int(i) > minimum and int(i) <= maximum:
True
else:
False
def VQ():
q = input("enter quantity: ")
minimum = 0
maxiumum = 49
if int(q) > minimum and int(q):
True
else:
False
Thank you for any help
Please read this W3Schools - Python global variables for a better understanding of how global variables work.
I think the problem with your code is, you should initialize your variables i and q first, before the add_item() function, and then get them from the global scope using the global keyword in the add_item function too.
i = 0
def add_item():
global i
Plus, you want to recheck your add_item() conditions,
while True:
i = input("enter code: ")
return i
if i != "END":
q = input("enter quantity: ")
return q # your code stops at this return
VC()
VQ()
if VC == True and VQ == True:
code_inputed.append(int(i))
quan_inputed.append(int(q))
elif VC == True and VQ == False:
print("Invalid Quanity")
break
elif VC == False and VQ == True:
print ("Invalid code")
break
else:
print("Invalid inputs")
break
P.S. you actually don't have to use global variables in this context, you can just pass the values as functions arguments.
Looks like you need some help here. First of all the global keyword is for functions where you are setting the global variable. Also, forget about globals. Pass i and q to the functions directly. Then set those calls equal to variables and check those variables.
vc_result = VC(i)
vq_result = VQ(q)
if vc_result == True and vq_result == True:
...
Plus, return immediately exits the function so no processing will continue. Those should be removed. I recommend reviewing tutorials on python functions to fill in your knowledge.
I'm trying to check if any of the students are on probation and if they are, display which student please assist with the error code, the code is meant to check if anyone has violated probation, it also displays an error code, the except is normally key error, but when I was trying to figure out the problem i changed it to keyboard interrupt
if students[Student].is_on_probation:
KeyError: 0
students = {}
try:
while True:
from Student import Student
students['1'] = Student("Jim", "Business", 3.1, False)
viewing = False
viewingchange = input("Would you like to view something: ").lower()
if viewingchange == "y":
viewing = True
elif viewingchange == "yes":
viewing = True
else:
viewing = False
add = input("Would you like to add someone: ")
if add.lower() == "yes" or "y":
adder = str(input("Who would you like to add: "))
major = str(input("What is their major: "))
gpa = float(input("GPA: "))
is_on_probation = bool(input("is on probation: "))
students[str(len(students)+1)] = Student(adder, major, gpa, is_on_probation)
def checking():
if viewing:
checker = input("Would you like to view all students or student a/s: ")
if checker.lower() == "a":
print(students)
checkfor = input("Check for: ")
if checkfor.lower() == "probation":
for Student in range(len(students)):
print("works")
if students[Student].is_on_probation:
print("yeppp")
else:
pass
checkerdouble = False
elif checker.lower() == "s":
searchquery2 = input("And which attribute would you like to search: ")
test = input("Student ID: ")
dude = students[test]
if searchquery2.lower() == "Name".lower():
print(dude.name)
elif searchquery2.lower() == "Major".lower():
print(dude.major)
elif searchquery2.lower() == "GPA".lower():
print(dude.gpa)
elif searchquery2.lower() == "is on probation" or "iop" or "probation".lower():
print(dude.is_on_probation)
checkerdouble = True
checking()
except KeyboardInterrupt:
print("Error code: " + "45345593M3940249525")
Your students dictionary uses string representations of numbers that start at str(1). So the loop should do the same. I think it would be better to just use int keys.
for student_id in map(str, range(1, len(students)):
if students[student_id].is_on_probation:
print(student_id)
This would work but it relies on the dictionary keys being dense. I would prefer to do:
for student_id in sorted(students, key=int):
if students[student_id].is_on_probation:
print(student_id)
Some might object to the indexing, as one can do:
for student_id, student in sorted(students.items(), key=lambda v: int(v[0])):
if student.is_on_probation:
print(student_id)
I am trying to exclude and remove some dictionaries from a list. I have searched for awhile through the site and haven't found anything specific to this. The list of dictionaries was created from a txt file located: http://s000.tinyupload.com/?file_id=48953557772434487729
I'm trying to sort out and exclude the things I don't need. I thought my syntax was right, but apparently not.
I only included necessary code to cut down on the clutter. I am having problems at the action_genre point and excluding and deleting the dictionaries there. When prompted enter "s" and then "a" to access those two menus.
def load_movies():
global movies_list
movies_list= []
file_ref = open("movies.txt", 'r')
line = file_ref.readline()
for line in file_ref:
line = line.strip()
current = {}
if line == '':
break
movie_data = line.split("\t")
current["title"] = movie_data[0]
current["year"] = movie_data[1]
current["length"] = movie_data[2]
current["rating"] = movie_data[3]
current["action"] = int(movie_data[4][0]) == 1
current["animation"] = int(movie_data[4][1]) == 1
current["comedy"] = int(movie_data[4][2]) == 1
current["drama"] = int(movie_data[4][3]) == 1
current["documentary"] = int(movie_data[4][4]) == 1
current["romance"] = int(movie_data[4][5]) == 1
movies_list.append(current)
del current
file_ref.close()
def menu():
movie_selector =("Movie Selector - Please enter an option below:\nL - List all movies\nY - List all movies by year\n"
"T - Search by title\nS - Search by genre, rating, and maximum length\nQ - Quit the program\nOption:")
movie_selector_input = input(movie_selector).upper()
if movie_selector_input == "L":
list_movies()
if movie_selector_input == "Y":
list_by_year()
if movie_selector_input == "T":
search_by_title()
if movie_selector_input == "S":
search()
if movie_selector_input == "Q":
print("Thanks for using my program! Goodbye.")
exit()
else:
print("Invalid input")
print("Please try again")
print()
return menu()
def search():
genre_input = input("Please make a selection from the following genres.\n(Action(A), Animation(N), Comedy(C), "
"Drama(D), Documentary(O), or Romance(R)):").lower()
if genre_input == 'a':
action_genre()
elif genre_input == 'n':
animation_genre()
elif genre_input == 'c':
comedy_genre()
elif genre_input == 'd:':
drama_genre()
elif genre_input == 'o':
documentary_genre()
elif genre_input == 'r':
romance_genre()
else:
print("Invalid genre")
print()
menu()
#this is where I can't get the syntax to work
def action_genre():
for current in movies_list:
if current["action"] == "False":
del current
break
for i in movies_list:#using this to test output
print(i)
load_movies()
menu()
I'm narrowing down the list by excluding things that don't fit the parameters. In the action_genre function, I'm trying to delete all the dictionaries that don't equal current["action"] == True. I've tried using "True" and "False" as strings, as well as the bools True and False for comparisons, and still an error. Unfortunately, I have to use the Boolean logic per my professors directions.
His e.g.:
Professor's example. Apparently since I'm new I can't embed images. :/
I'm in programming 101, so thank you for your patience as I learn this, and thank you in advance for the help.
Okay, so the issue runs a bit deeper than the if condition being incorrect. In get_action() you effictively do not modify the actual movies_list object, but rather the local variable current, as proven by this simple test:
def action_genre():
for current in movies_list:
print(current)
if not current["action"]:
del current
print(current)
The second print(current) will result in an UnboundLocalError saying that current does not exist anymore, while in movies_list the entry it just deleted continues to exist. But in general, using del in loops indeed causes problems because that's how iterables and del itself behave. I encourage you to read up more on this on other sources or SO if you wish, like here.
Using the answer from the provided link above, we can use list comprehension to filter the movies:
def action_genre():
filtered_movies_list = [movie for movie in movies_list if movie['action']]
print(filtered_movies_list)
This creates a new list (so it does not modify movies_list), which includes all dictionary entries where item['action'] == True.
I hope this helps.
You are trying to compare a string with a boolean. Look at the following:
a= 1==1
print a
True
print type(a)
<class 'bool'> # a is a boolean
b='True' #assign string 'True' to b
print type(b)
<class 'str'>
print a==b #compare boolean True to string 'True'
False
b = True # assign boolean True to b
print a==b #compare boolean True to boolean True
True
so you need if current["action"] == False instead of if current["action"] == "False"
Is there any short way to achieve what the APT (Advanced Package Tool) command line interface does in Python?
I mean, when the package manager prompts a yes/no question followed by [Yes/no], the script accepts YES/Y/yes/y or Enter (defaults to Yes as hinted by the capital letter).
The only thing I find in the official docs is input and raw_input...
I know it's not that hard to emulate, but it's annoying to rewrite :|
As you mentioned, the easiest way is to use raw_input() (or simply input() for Python 3). There is no built-in way to do this. From Recipe 577058:
import sys
def query_yes_no(question, default="yes"):
"""Ask a yes/no question via raw_input() and return their answer.
"question" is a string that is presented to the user.
"default" is the presumed answer if the user just hits <Enter>.
It must be "yes" (the default), "no" or None (meaning
an answer is required of the user).
The "answer" return value is True for "yes" or False for "no".
"""
valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False}
if default is None:
prompt = " [y/n] "
elif default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError("invalid default answer: '%s'" % default)
while True:
sys.stdout.write(question + prompt)
choice = input().lower()
if default is not None and choice == "":
return valid[default]
elif choice in valid:
return valid[choice]
else:
sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n")
(For Python 2, use raw_input instead of input.)
Usage example:
>>> query_yes_no("Is cabbage yummier than cauliflower?")
Is cabbage yummier than cauliflower? [Y/n] oops
Please respond with 'yes' or 'no' (or 'y' or 'n').
Is cabbage yummier than cauliflower? [Y/n] [ENTER]
>>> True
>>> query_yes_no("Is cabbage yummier than cauliflower?", None)
Is cabbage yummier than cauliflower? [y/n] [ENTER]
Please respond with 'yes' or 'no' (or 'y' or 'n').
Is cabbage yummier than cauliflower? [y/n] y
>>> True
I'd do it this way:
# raw_input returns the empty string for "enter"
yes = {'yes','y', 'ye', ''}
no = {'no','n'}
choice = raw_input().lower()
if choice in yes:
return True
elif choice in no:
return False
else:
sys.stdout.write("Please respond with 'yes' or 'no'")
You can use click's confirm method.
import click
if click.confirm('Do you want to continue?', default=True):
print('Do something')
This will print:
$ Do you want to continue? [Y/n]:
Should work for Python 2/3 on Linux, Mac or Windows.
Docs: http://click.pocoo.org/5/prompts/#confirmation-prompts
There is a function strtobool in Python's standard library: http://docs.python.org/2/distutils/apiref.html?highlight=distutils.util#distutils.util.strtobool
You can use it to check user's input and transform it to True or False value.
A very simple (but not very sophisticated) way of doing this for a single choice would be:
msg = 'Shall I?'
shall = input("%s (y/N) " % msg).lower() == 'y'
You could also write a simple (slightly improved) function around this:
def yn_choice(message, default='y'):
choices = 'Y/n' if default.lower() in ('y', 'yes') else 'y/N'
choice = input("%s (%s) " % (message, choices))
values = ('y', 'yes', '') if choices == 'Y/n' else ('y', 'yes')
return choice.strip().lower() in values
Note: On Python 2, use raw_input instead of input.
As mentioned by Alexander Artemenko, here's a simple solution using strtobool().
from distutils.util import strtobool
def user_yes_no_query(question):
sys.stdout.write('%s [y/n]\n' % question)
while True:
try:
return strtobool(raw_input().lower())
except ValueError:
sys.stdout.write('Please respond with \'y\' or \'n\'.\n')
Usage
>>> user_yes_no_query('Do you like cheese?')
Do you like cheese? [y/n]
Only on tuesdays
Please respond with 'y' or 'n'.
ok
Please respond with 'y' or 'n'.
y
>>> True
I know this has been answered a bunch of ways and this may not answer OP's specific question (with the list of criteria) but this is what I did for the most common use case and it's far simpler than the other responses:
answer = input('Please indicate approval: [y/n]')
if not answer or answer[0].lower() != 'y':
print('You did not indicate approval')
exit(1)
You can also use prompter.
Shamelessly taken from the README:
#pip install prompter
from prompter import yesno
>>> yesno('Really?')
Really? [Y/n]
True
>>> yesno('Really?')
Really? [Y/n] no
False
>>> yesno('Really?', default='no')
Really? [y/N]
True
I modified fmark's answer to by python 2/3 compatible more pythonic.
See ipython's utility module if you are interested in something with more error handling
# PY2/3 compatibility
from __future__ import print_function
# You could use the six package for this
try:
input_ = raw_input
except NameError:
input_ = input
def query_yes_no(question, default=True):
"""Ask a yes/no question via standard input and return the answer.
If invalid input is given, the user will be asked until
they acutally give valid input.
Args:
question(str):
A question that is presented to the user.
default(bool|None):
The default value when enter is pressed with no value.
When None, there is no default value and the query
will loop.
Returns:
A bool indicating whether user has entered yes or no.
Side Effects:
Blocks program execution until valid input(y/n) is given.
"""
yes_list = ["yes", "y"]
no_list = ["no", "n"]
default_dict = { # default => prompt default string
None: "[y/n]",
True: "[Y/n]",
False: "[y/N]",
}
default_str = default_dict[default]
prompt_str = "%s %s " % (question, default_str)
while True:
choice = input_(prompt_str).lower()
if not choice and default is not None:
return default
if choice in yes_list:
return True
if choice in no_list:
return False
notification_str = "Please respond with 'y' or 'n'"
print(notification_str)
For Python 3, I'm using this function:
def user_prompt(question: str) -> bool:
""" Prompt the yes/no-*question* to the user. """
from distutils.util import strtobool
while True:
user_input = input(question + " [y/n]: ")
try:
return bool(strtobool(user_input))
except ValueError:
print("Please use y/n or yes/no.\n")
The strtobool() function converts a string into a bool. If the string cant be parsed it will raise a ValueError.
In Python 3 raw_input() has been renamed to input().
As Geoff said, strtobool actually returns 0 or 1, therefore the result has to be cast to bool.
This is the implementation of strtobool, if you want special words to be recognized as true, you can copy the code and add your own cases.
def strtobool (val):
"""Convert a string representation of truth to true (1) or false (0).
True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if
'val' is anything else.
"""
val = val.lower()
if val in ('y', 'yes', 't', 'true', 'on', '1'):
return 1
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return 0
else:
raise ValueError("invalid truth value %r" % (val,))
on 2.7, is this too non-pythonic?
if raw_input('your prompt').lower()[0]=='y':
your code here
else:
alternate code here
it captures any variation of Yes at least.
Doing the same with python 3.x, where raw_input() doesn't exist:
def ask(question, default = None):
hasDefault = default is not None
prompt = (question
+ " [" + ["y", "Y"][hasDefault and default] + "/"
+ ["n", "N"][hasDefault and not default] + "] ")
while True:
sys.stdout.write(prompt)
choice = input().strip().lower()
if choice == '':
if default is not None:
return default
else:
if "yes".startswith(choice):
return True
if "no".startswith(choice):
return False
sys.stdout.write("Please respond with 'yes' or 'no' "
"(or 'y' or 'n').\n")
You could try something like the code below to be able to work with choices from the variable 'accepted' show here:
print( 'accepted: {}'.format(accepted) )
# accepted: {'yes': ['', 'Yes', 'yes', 'YES', 'y', 'Y'], 'no': ['No', 'no', 'NO', 'n', 'N']}
Here is the code ..
#!/usr/bin/python3
def makeChoi(yeh, neh):
accept = {}
# for w in words:
accept['yes'] = [ '', yeh, yeh.lower(), yeh.upper(), yeh.lower()[0], yeh.upper()[0] ]
accept['no'] = [ neh, neh.lower(), neh.upper(), neh.lower()[0], neh.upper()[0] ]
return accept
accepted = makeChoi('Yes', 'No')
def doYeh():
print('Yeh! Let\'s do it.')
def doNeh():
print('Neh! Let\'s not do it.')
choi = None
while not choi:
choi = input( 'Please choose: Y/n? ' )
if choi in accepted['yes']:
choi = True
doYeh()
elif choi in accepted['no']:
choi = True
doNeh()
else:
print('Your choice was "{}". Please use an accepted input value ..'.format(choi))
print( accepted )
choi = None
As a programming noob, I found a bunch of the above answers overly complex, especially if the goal is to have a simple function that you can pass various yes/no questions to, forcing the user to select yes or no. After scouring this page and several others, and borrowing all of the various good ideas, I ended up with the following:
def yes_no(question_to_be_answered):
while True:
choice = input(question_to_be_answered).lower()
if choice[:1] == 'y':
return True
elif choice[:1] == 'n':
return False
else:
print("Please respond with 'Yes' or 'No'\n")
#See it in Practice below
musical_taste = yes_no('Do you like Pine Coladas?')
if musical_taste == True:
print('and getting caught in the rain')
elif musical_taste == False:
print('You clearly have no taste in music')
This is what I use:
import sys
# cs = case sensitive
# ys = whatever you want to be "yes" - string or tuple of strings
# prompt('promptString') == 1: # only y
# prompt('promptString',cs = 0) == 1: # y or Y
# prompt('promptString','Yes') == 1: # only Yes
# prompt('promptString',('y','yes')) == 1: # only y or yes
# prompt('promptString',('Y','Yes')) == 1: # only Y or Yes
# prompt('promptString',('y','yes'),0) == 1: # Yes, YES, yes, y, Y etc.
def prompt(ps,ys='y',cs=1):
sys.stdout.write(ps)
ii = raw_input()
if cs == 0:
ii = ii.lower()
if type(ys) == tuple:
for accept in ys:
if cs == 0:
accept = accept.lower()
if ii == accept:
return True
else:
if ii == ys:
return True
return False
def question(question, answers):
acceptable = False
while not acceptable:
print(question + "specify '%s' or '%s'") % answers
answer = raw_input()
if answer.lower() == answers[0].lower() or answers[0].lower():
print('Answer == %s') % answer
acceptable = True
return answer
raining = question("Is it raining today?", ("Y", "N"))
This is how I'd do it.
Output
Is it raining today? Specify 'Y' or 'N'
> Y
answer = 'Y'
Here's my take on it, I simply wanted to abort if the user did not affirm the action.
import distutils
if unsafe_case:
print('Proceed with potentially unsafe thing? [y/n]')
while True:
try:
verify = distutils.util.strtobool(raw_input())
if not verify:
raise SystemExit # Abort on user reject
break
except ValueError as err:
print('Please enter \'yes\' or \'no\'')
# Try again
print('Continuing ...')
do_unsafe_thing()
How about this:
def yes(prompt = 'Please enter Yes/No: '):
while True:
try:
i = raw_input(prompt)
except KeyboardInterrupt:
return False
if i.lower() in ('yes','y'): return True
elif i.lower() in ('no','n'): return False
Since the answer is expected yes or no, in the examples below, the first solution is to repeat the question using the function while, and the second solution is to use recursion - is the process of defining something in terms of itself.
def yes_or_no(question):
while "the answer is invalid":
reply = str(input(question+' (y/n): ')).lower().strip()
if reply[:1] == 'y':
return True
if reply[:1] == 'n':
return False
yes_or_no("Do you know who Novak Djokovic is?")
second solution:
def yes_or_no(question):
"""Simple Yes/No Function."""
prompt = f'{question} ? (y/n): '
answer = input(prompt).strip().lower()
if answer not in ['y', 'n']:
print(f'{answer} is invalid, please try again...')
return yes_or_no(question)
if answer == 'y':
return True
return False
def main():
"""Run main function."""
answer = yes_or_no("Do you know who Novak Djokovic is?")
print(f'you answer was: {answer}')
if __name__ == '__main__':
main()
One-liner with Python 3.8 and above:
while res:= input("When correct, press enter to continue...").lower() not in {'y','yes','Y','YES',''}: pass
Python x.x
res = True
while res:
res = input("Please confirm with y/yes...").lower(); res = res not in {'y','yes','Y','YES',''}
What I used to do is...
question = 'Will the apple fall?'
print(question)
answer = int(input("Pls enter the answer: "
if answer == "y",
print('Well done')
print(answer)