I'm doing a school project and the user will need to input some values (1, 2 or 3 and their combinations separated by comma). Ex: 2,3,1 or 2,1
I need to prevent the user from typing anything else out of the standard value.
Here's my attempt, which is working, but looks very dumb. Anyone could think somehow to improve it?
while True:
order = input("Input value: ")
try:
if order == "1" or order == "2" or order == "3" or order == "1,2" or order == "1,3" or \
order == "2,3" or order == "2,1" or order == "3,1" or order == "3,2" or order == "1,2,3" \
or order == "1,3,2" or order == "2,1,3" or order == "2,3,1" or order == "3,2,1" or order == "3,1,2":
list_order = order.split(",")
break
else:
print("\nError. Try again!\n")
continue
except:
pass
print(list_order)
Instead of waiting to .split() the order until after checking the order components are correct, do it beforehand. Then, make a set out of that, and check whether it's a subset of the correct/acceptable values. Using a set means that order doesn't matter for this check.
while True:
order = input('Input Value: ')
list_order = order.split(',')
try:
if set(list_order) <= set(['1', '2', '3']):
break
else:
print("\nError. Try again!\n")
continue
except:
pass
print(list_order)
why dont you make a list of possible inputs and check if input for user is present in that list?
inputList = []
inputList.append("1")
inputList.append("2")
inputList.append("3")
inputList.append("1,2")
inputList.append("1,3")
inputList.append("2,3")
inputList.append("2,1")
inputList.append("3,1")
inputList.append("3,2")
inputList.append("1,2,3")
inputList.append("1,3,2")
inputList.append("2,1,3")
inputList.append("2,3,1")
inputList.append("3,2,1")
inputList.append("3,1,2")
while True:
order = input("Input value: ")
try:
if order in inputList:
list_order = order.split(",")
break
else:
print("\nError. Try again!\n")
continue
except:
pass
print(list_order)
while True:
order = input("Input value: ")
try:
if "," in order:
list_order = order.split(",")
list_numbers = []
while list_order:
clipboard = list_order[0]
if clipboard != "1" or clipboard != "2" or clipboard != "3":
del list_order[0]
elif clipboard == "1" or clipboard == "2" or clipboard == "3":
list_numbers.insert(-1, clipboard)
del list_order[0]
print(list_numbers)
print(list_order)
break
else:
print("\nError. Try again!\n")
except:
pass
This isn't the best result. But is it a good example for testing every letter by letter. :) I hope I could help you, and it not, maybe you learned something new :)
# In case your needs should ever change (for example also allowing '-')
# You can put anything you want int this list.
valid_characters = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', ',']
while True:
order = input("Input value: ")
try:
# we use `set()` to get each unique character. For example:
# "1,2,33,4516,14" would just be {'1', '6', '3', '4', '2', '5', ','}
for char in set(order):
if char not in valid_characters:
# raise an exception of type ValueError
raise ValueError
# The exception gets handled here
except ValueError:
print("\nError. Try again!\n")
# And we go back to the top
continue
list_order = order.split(',')
print(list_order, end="\n\n")
Let me know if you have any questions or if some parts are not clear enough.
This code does what you want.
import re
def isValid(order):
if(re.fullmatch('[1-3]([ \t]*,[ \t]*[1-3])*', order)):
print("true")
return True
else:
return False
while True:
order = input("Input value: ")
try:
if isValid(order):
list_order = order.split(",")
break
else:
print("\nError. Try again!\n")
continue
except:
pass
print(list_order)
I created a function that uses regular expressions to check validity.
This is another answer similar to my previous answer in which you told that what if support numbers goes to 9. So here is the solution for that using itertools library.
you can change the for loop range as per you requirement
from itertools import permutations
inputList = []
for i in range(1,10)
perm = permutations(["1", "2", "3","4","5","6","7","8","9"],i)
for i in list(perm):
inputList.append(','.join(list(i)))
while True:
order = input("Input value: ")
try:
if order in inputList:
list_order = order.split(",")
break
else:
print("\nError. Try again!\n")
continue
except:
pass
print(list_order)
Related
So here is the question. I am trying to find if a particular value is part of a value list in a dictionary. when I tried using .values(), it wouldn't work. Here is the code. The part indicated does not go into the if statement.
company_dict = dict()
while True:
command = input()
if command == 'End':
break
(employer,id_worker) = command.split(' -> ')
if id_worker in company_dict.values(): # THIS
continue # PART
else:
if employer not in company_dict:
company_dict[employer] = []
company_dict[employer].append(id_worker)
And here is how I have managed to solve it, but it is extremely inefficient:
while True:
flag = 0
command = input()
if command == 'End':
break
(employer,id_worker) = command.split(' -> ')
for key,values in company_dict.items():
for i in values:
if id_worker == i and employer == key:
flag = 1
if flag == 1:
continue
else:
if employer not in company_dict:
company_dict[employer] = []
company_dict[employer].append(id_worker)
This will print 'True' if the key exists in the dictionary. It's basically the same as what you had and it should work fine, check to see if it prints 'True'
company_dict = dict()
while True:
command = input("employer -> worker_id")
if command.lower() == 'end':
break
employer, id_worker = command.split(' -> ')
if id_worker in company_dict.values():
print(True)
continue
else:
if not company_dict.get(employer, false):
company_dict[employer] = [worker_id]
You could break from the for loop if you find a match, and then use an else after the for loop to mean execute some code if the for loop reached the end without break.
while True:
command = input()
if command == 'End':
break
(employer,id_worker) = command.split(' -> ')
for key,values in company_dict.items():
if employer == key and id_worker in values:
break
else:
if employer not in company_dict:
company_dict[employer] = []
company_dict[employer].append(id_worker)
This will be more efficient than what you have, because you stop searching after the first match -- both due to the break from the explicit loop and the fact that the expression id_worker in values will stop iterating on the first match. (Here the use of in for inclusion testing also avoids using an explicit loop for the iteration over values, so may be a bit faster for that reason also.)
I keep getting an error when I run this functions. Everything goes through and then it shows this error. I have tried adding .items() to the end when I print the dictionary and still throws this error.
CLARIFICATION just realized. Not getting any type errors or anything. It prints fine but when doesn't add the second variable to the dictionary. Instead it prints this..
{'Frappe': ('small', function type_of_milk at 0x000002BE2BCD2F78>)}
def order():
ready_to_order = True
while ready_to_order != False:
ordering_q = input(
"""Do you know what you would like to order or do you need to see the menu?
[M]enu or [R]eady to order or [Q]uit: """)
if ordering_q.upper() == "Q":
sys.exit()
elif ordering_q.upper() == "M":
print(Menu())
elif ordering_q.upper() == "R":
ready_to_order = False
else:
print("Please enter valid letters only, try again.")
print(" ")
print(" ")
add_cart = True
while add_cart != False:
order1 = input("What would you like to order?")
if order1.upper() == "Done":
add_cart = False
elif order1 == 'a1':
print("Frappe added to cart")
global total_order
total_order += 3
drink_size()
type_of_milk()
order_dict['Frappe'] = (drink_sizes, type_of_milk)
add_cart = False
print(order_dict)
This line:
order_dict['Frappe'] = (drink_sizes, type_of_milk)
is adding the function type_of_milk to your dict, which is why you see function type_of_milk at 0x000002BE2BCD2F78> when you print the dict out. Maybe you meant to say type_of_milk()?
I'm learning Python and I'm trying to make shopping List
where you can add items
first it will ask you to add the items if the shopping list is empty
it will be added automatically if not it will ask you where you would like
to put the item (index)
but also I'm trying to make the program exit in certain condition like DONE
or HELP or SHOW but even that i put a condition for that but it's not working can anyone help me with this
hope I explained enough
import os
shopping_list =[]
# Function for clearing the screen
def clear_screen():
os.system("cls" if os.name == "nt" else "clear")
def show_help():
print("Enter 'Done' if you finish adding item \n Enter 'Show' to show your items \n Enter 'Help' toshow this help ")
# Function to show the items that you've entered to the list
def show_item():
clear_screen()
index = 1
for item in shopping_list:
print("{} {}.".format(index,item))
index += 1
# Function to add items to the list
def add_to_list():
while True:
new_item = input("Please enter the item that you would like to add to your shopping list ")
if shopping_list and ((new_item.upper() != "DONE") or (new_item.upper() != "HELP") or (new_item.upper() != "SHOW")):
position = input("Where you would like to add {} to the list \n press 'Enter' if you want to add to the end of the list".format(new_item))
position = abs(int(position))
shopping_list.insert(position - 1 , new_item)
show_item()
else:
if new_item.upper() == "DONE":
break
elif new_item.upper() == "SHOW":
show_item()
continue
elif new_item.upper() == "HELP":
show_help()
continue
else:
shopping_list.append(new_item)
show_item()
show_help()
add_to_list()
Welcome to stackoverflow. I think your logic statement is wrong, you need and instead of or. Right now all you need for the statement in the parentheses to be true, is that new_item.upper() is at least not one of those three words. It actually can't equate to False since two of the three are always true.
((new_item.upper() != "DONE") or (new_item.upper() != "HELP") or (new_item.upper() != "SHOW"))
If you have for example done the first statement is False ,but the other two are True, adding up to True in or-Statements.
>>> new_item = 'done'
>>> print((new_item.upper() != "DONE") or (new_item.upper() != "HELP") or (new_item.upper() != "SHOW"))
True
i'm trying to allow the user to change the value for a dictionary, my dictionary is d as follows:
d = {'gary:' : 'B','john:': 'C',}
Whenever I type in 'gary:'(gary with a semicolon) for the nameedit input, the why variable will always result in true but regardless, it will read the value as none and never reach the second input for the letter grade(inpu)
nameedit = str(input("Which student do you wish to edit the grade of?"))
why = print(nameedit in d)
if why == None:
print("That student doesn't exist")
else:
inpu = str(input("Enter new letter grade: A,B,C,D,F,"))
d[nameedit] = inpu
print(d)
I also tried some variations on this such as if nameedit == True: and an else with the same problem, the print statement will yield True but it will just continue to the else statement. I also tried a elif nameedit in d:
why = print(nameedit in d)
if nameedit in d == True:
inpu = str(input("Enter new letter grade: A,B,C,D,F,"))
d[nameedit] = inpu
print(d)
else:
print("That student doesn't exist")
, but with no avail. Is it impossible to pick up the value the print statement is reading? My ultimate goal is to simply check if the name is in the dictionary, if it is, continue, if it isn't, stop
python v 3.5
Use:
why = nameedit in d
if why:
inpu = str(input("Enter new letter grade: A,B,C,D,F,"))
d[nameedit] = inpu
print(d)
else:
print('Does not exists')
print() just puts output to the screen; it does not return what it is printing. If you want to assign why to the result of nameedit in d and print it; do it on separate lines:
why = nameedit in d
print(why)
Also, if ... is seeing if ... is True. Using if ... == True is seeing if ... == True == True. That is redundant. Just do this:
why = nameedit in d
print(why)
if why:
inpu = input("Enter new letter grade: A,B,C,D,F,")
d[nameedit] = inpu
print(d)
else:
print("That student doesn't exist")
I also removed your conversion of input(...) to a string. It already returns a string, so the conversion is redundant.
nameedit in d returns True or False, never None. And wrapping in print (which always returns None) is just nonsensical.
Remove the print wrapping, and change the test to if not why: or just move the test into the condition itself:
nameedit = input("Which student do you wish to edit the grade of?")
if nameedit not in d:
print("That student doesn't exist")
else:
d[nameedit] = input("Enter new letter grade: A,B,C,D,F,")
print(d)
I removed unnecessary str wrapping (input already returns str in Py3), and unnecessary intermediate locals.
Use just like:
if why in d:
or
if why not in d:
You don't need use two strings for this. Also, you can get value with get:
d = {'gary:' : 'B','john:': 'C',}
name = str(input("Which student do you wish to edit the grade of?\n"))
value = d.get(name, None)
if not value:
print("That student doesn't exist: {0}: [1}".format(name, value))
else:
value = str(input("Enter new letter grade: A,B,C,D,F \n"))
d[name] = value.upper()
print(d)
I Have a list, and every time I enter "N" in my program I want the list to print the contents of the next index.
categories = ["Produce", "Meat", "Dairy" ,"Misc"]
...
elif item == "N":
for d in categories[:1]:
d = categories[0]
d += 1
print(d)
I understand that the above code is trying to add an integer to a string and throwing the error. What I haven't been able to figure out is how to increment the index.
I have looked at a few other posts concerning similar problems but it the solutions aren't clicking for me out of context.
Sample output of what it should look like
Add Item to list
Produce
>>Tomatoes
>>Grapes
Meat
>>Hamburger
Dairy
>>
Entire program
def add_item():
exit_list = ["F", "Finished"]
lists = []
start = input("Would you like to add an item to the list? Y/N")
print("Add Item to list")
categories = ["Produce", "Meat", "dairy","snacks/boxed goods", "Cans", "Misc"]
print(categories[0])
while start in ('y', 'Y'):
item = input(">>")
if item in exit_list:
break
elif item == "N":
for d in categories[:1]:
i = 0
i +=1
d = categories[i]
print(d)
elif item:
lists.append(item)
else:
print("ok")
print(lists)
return lists
add_item()
This code will keep track of an index and increment it each time it's used:
i = 0
categories = ["hey", "1", "2" ,"3"]
...
elif item == "N":
print(categories[i])
i += 1
And note that this code will eventually go out of bounds. If you want to wrap around you can do e.g. % len(categories) on i.
Most of the time it is possible, if not better, to avoid using index in Python. One way in your case would be to use a generator on your list. The following code will quit when the user enters q, print the next item when the user enters n, and do nothing if the input is something else.
categories = ["hey", "1", "2" ,"3"]
user_input = None
# Transform your list into an iterator
categories = iter(categories)
# While the user doesn't want to quit
while user_input != "q":
# The user's input is transformed to lower case
user_input = input("What do you want to do ? ").lower()
if user_input == "n":
try:
# We print the next value on the iterator i.e. the next
# value in your list
print(next(categories))
except StopIteration:
# Raised when the iterator reached the end i.e. when we
# have printed all the values in the list
print("You've printed all the list!")
break
One possible output is:
What do you want to do ? hello # Nothing happens here
What do you want to do ? n
hey
What do you want to do ? n
1
What do you want to do ? n
2
What do you want to do ? n
3
What do you want to do ? n
You've printed all the list!
Note that this example is using Python3+
def add_item():
exit_list = ["F", "Finished"]
lists = []
start = input("Would you like to add an item to the list? Y/N")
print("Add Item to list")
categories = ["Produce", "Meat", "dairy","snacks/boxed goods", "Cans", "Misc"]
print(categories[0])
i=0
while start in ('y', 'Y'):
item = input(">>")
if item in exit_list:
break
elif item == "N":
i +=1
print(categories[i])
elif item:
lists.append(item)
else:
print("ok")
print(lists)
return lists
add_item()