I am trying to make a python program that allows the user to order a salad by chosing ingredients they would like:
Here are some quick translations:
Tillbehörslista: List of food items (tomatoes, eggs, broccoli, pasta, etc)
-Svar: Answer
Beställning: Order
VäljaTillbehör(): ChooseFoodItems():
For my function that is supposed to allow the user to write in what they would like, I made an error handling function that makes sure that whatever is typed in is in the actual list of food items. However regardless of what I type in in the ChooseFoodItems function the error handling only jumps to the if block. So even if the answer is illegal the error handling function can't seem to differentiate it. Please help.
try:
if hurMangaLika(svar,tillbehörsLista,beställning)==True:
svar=input("")
elif hurMangaLika(svar,tillbehörsLista,beställning)==False:
svar=input("")
except:
print("error")
return beställning`
for i in range(len(tillbehörsLista)):
for svar in tillbehörsLista:
if svar==tillbehörsLista[i]:
print("här")
beställning.append(svar)
return True
#eller gör return true osen säg whiel true appendsndk
#beställning.append(svar)
elif svar!=tillbehörsLista[i]:
print("Fel")
return False`
I tried to make a function that would allow me to make sure that only proper ansewrs would be registred and added to the actual order. However as I mentioned before that didn't work.
Related
I am trying to add together two user inputs for numbers and show the results of the two added together.
This is what my code currently looks like:
number1= eval(input("total price of cleaning for your house size:"))
number2= eval(input("Price for the cleaning type:"))
def addition(a,b):
addition =a-b
return addition
print("You owe:",addition(int(number1),int(number2)))
both user inputs are based on earlier calculations within my code.
I had submitted a code almost identical to this, and it had performed correctly, so I am not sure why this one is not.
In the "assistant" it shows "str" is not callable, and redefining the name "addition" from the outer scope.
I have tried multiple different ways to make this code work and have not been able to have it run successfully to where it calculates and displays the cost.
eval return int try this :
number1= eval(input("total price of cleaning for your house size:"))
number2= eval(input("Price for the cleaning type:"))
def addition(a,b):
addition =a-b
return addition
print("You owe:",addition(number1,number2))
I suspect you don't want to use eval, just:
number1= input("total price of cleaning for your house size:")
number2= input("Price for the cleaning type:")
def addition(a,b):
addition =a-b
return addition
print("You owe:",addition(int(number1),int(number2)))
input will present a prompt and read the value entered by the user into a string. eval will parse the expression the user enters and will try to execute it as a python script; the return value will be the results of evaluating the text as a python script. So, for example, x = 1; eval("x+1") will return 2.
I assume you just want to read an integer value, so:
number = int(input("Price for the cleaning type:"))
I'm making a text-based game, which is based largely in if-, elif- and else-statements. However, I also use while loops for different "areas" within the game. (Play_loop, Main_loop, Shop_loop, Fish_loop, etc.).
Lately I've implemented admin commands which I use in-game to change things on the go, and I want these to be available in every loop. I also have some general commands which I want to be available (help, leave, quit, logout, go to another area, check inventory, etc.).
The issue I'm facing is knowing that duplicated code should be avoided, but i'm wondering if this is necessary in this situation. I've already made many functions to make each command code pretty short, about 2-15 lines in general.
Should I add the code blocks into functions that do the same thing, and then just repeat the function, or should I just keep it as is? Or maybe I should do something else that I havent even thought about?
Example code:
elif command == '/user info':
if user.admin:
print(f'User-list: {users}')
who = input('Name of user: ').strip()
who_user = admin_load_user(who, users)
if who_user:
print(who_user.info())
print(who_user.display_inv())
else:
print(DNEError)
else:
print(PError)
elif command == '/add coins':
who = input('Who gets coins? ').strip()
amount = int(input('How much? ').strip())
admin_add_coins(who, amount, users)
save_users(users)
Code that is repeated should typically be put into functions, so that you have better overview and control over what they are doing. There you can also easily give them default arguments and expand on the code without bloating the main function of your program.
Here is a concise argument for using functions. It's written for C but applies to python as well.
Then, as Jason Chia pointed out, you should consider thinking about building your game into classes, as they solve some of the problems you mentioned and generally are an important control instrument for bigger programs where you need to coordinate different states (e.g. changing something in a room based on the player's actions).
This tutorial could help with that.
Does that about answer your question?
You should use decorator style to do it nice to read and write.
get inspiration here:
def requires_admin(f):
def wrapper(f):
#wraps(f)
def wrapped(*args, **kwargs):
#if not admin:
#return render_template('error.html')
return f(*args, **kwargs)
return wrapped
return wrapper
#app.route('/admin/action')
#requires_admin
def AdminAction():
whatyouwant()
I am trying to create a machine learning program. So far, I have stored each of the 'learned' meanings in a text file in a list of all things that are attribute to that meaning. The text file is read by a python file that generates class objects that attribute the data in the text file to them. Then, in a master python file, the main prompt is where I am having trouble.
else:
try:
for obj in gc.get_objects():
try:
if isinstance(obj, LearnedClasses.learned):
if str(user.lower()) in obj.keys:
exec(obj.exstring)
chat()
break
except:
raise Exception
except Exception:
user = user.split()
for x in user:
learnlist.append(x)
learnch = random.choice(learnlist)
learnp = input("What does '{}' mean?".format(learnch))
learn(learnch, learnp)
chat()
This code is what follows the basic 'built-in' responses that I made. This is what happens after it can not find any keywords in the built-in section. I am using GC to collect all of the class objects that were generated from the text file. Then, if the prompt matches any keywords with any of its 'learned' keywords, I intend for it to respond with the responses set for that class. However, I can not get it to move on to the if ALL ELSE fails part, which starts at except Exception. How could I arrange this so that it can do what I described? Thank you.
It's a bit hard to follow this code; a couple of suggestions for improvement:
raise Exception has a typo: it should be raise Exception()
There's not much point having an except block which just raises an exception with no additional information; omit it?
The garbage collector is not a good place to store information that you will, in fact, need later; can you change the code so that the learned classes are stored in a list in a variable, which is returned or passed around somehow?
As a general rule, you should never touch the garbage collector unless you're running out of memory, and then only to figure out how to help it discard things.
As others have suggested in the comments, rather than try/except, use something like a flag variable to keep track of whether you've already answered, or the for/break/else construct:
for lc in learned_class_list:
if str(user.lower()) in lc.keys:
exec(lc.exstring)
chat()
break
else:
user = user.split()
for x in user:
learnlist.append(x)
learnch = random.choice(learnlist)
learnp = input("What does '{}' mean?".format(learnch))
learn(learnch, learnp)
I'm trying to write a text game with what I've learned so far, but I ran into a problem.
When I input 1, it's fine, but when I input 2, it gives me the following error:
Traceback (most recent call last):
File "ex36.py", line 39, in <module>
start()
File "ex36.py", line 27, in start
if choice == 1 or "closer" in choice:
TypeError: argument of type 'int' is not iterable
I realize that the function idf(): is totally unnecessary as I can just treat the input 2 as a string without converting it into an integer. This fixes the program. However, I would like to know why this error occurs when I try to change the input into a string, and why it only works for 1 and not 2.
I'm sorry for this stupid question; I'm very new to programming and trying to teach myself python. Thanks for the support, everyone.
Update 1:
I think I see the problem now, as pointed out by two answerers below. The problem happens when the program tries to check "closer", which is a string, in choice, which is an integer.
I would like the if statements to accept both integers and strings. How would I do this? Any advice to modify my program?
from sys import exit
print("""Welcome to my text game! You may input numbers (e.g. 1, 2, 3) to
navigate or type in your choice.""", "\n")
def bad_news(reason):
print(reason)
exit(0)
#IDs if str or int
def idf(check):
if check.isdigit() == True:
converted = int(check)
return converted
else:
return check
def start():
print("You're walking home down a dark road, in a dark and gloomy night.")
print("There's someone going the same way as you.")
print("'It's quite dark and dangerous,' you think. 'Better do something.'")
print("Will you: 1. Follow him/her closer? or 2. Keep distance?")
choice1 = input("> ")
choice = idf(choice1)
if choice == 1 or "closer" in choice:
bad_news("""The person gets spooked and you got cops called on you.
Now you have a restraining order. Great!""")
elif choice == 2 or "distance" in choice:
alley()
else:
print("The input is invalid; please try again.")
start()
def alley():
print("Now in alley.")
start()
Your idf converts any digit strings into numbers and then you try to check if a string is in the integer.
Your best option is to just always return strings from idf (or remove this function altogether) and check if choice == "1"
Your main problem is this line:
if choice == 1 or "closer" in choice:
If choice is not 1 you cannot check "closer" in choice without potential errors, because choice can still be an integer (e.g. the number 2) and an integer is not iterable.
It is best to keep the program simple and also to keep the return type from the input() function, i.e. the string. The string method is_digit() already exists and you can also apply it directly to the return value. In my opinion, there is no need to write another function that checks this. Then the function can also return two different data types. This complicates the code unnecessarily.
The string method is_digit() already does all the magic that is essential to your problem. It allows you to check if a user has entered a number or a text. You only need to explicitly convert the potential number to an integer (int(choice)) if you want to save the number as an integer.
Since you have several cases that you need to handle differently, you will also need to write some if-statements. So you could simply do something like this, for example:
if not choice.isdigit():
if "closer" in choice:
# do something
elif "whatever" in choice:
# do something
elif choice == "1":
# do something
elif choice == "2":
# do something
...
You can save one indentation by using the logical and-operator, but this is more a matter of taste, e.g.:
if not choice.isdigit() and "closer" in choice:
...
If you just want to react to certain return values, you can even do it without the is_digit() function, at all. But you mentioned in the question that you still want to distinguish between numbers and text (at least that's how I understood it). Because then you always get a string back and this string is always iterable. The error from above would simply not occur.
Most of it you have already figured out yourself, but the answer should also have added value for other readers. Therefore I have revised the answer again and hopefully clarified the problem better.
def travel():
travel.s=0
travel.frate=[]
travel.tr=[]
def accomodation():
print"""specialises
1.place 1
a.hotel 1
b.hotel 2
Hotel1:ac/non ac rooms
Ac.for ac...
Noac.for non ac...."""
hd=[5000,6000]
hg=[4000,7000]
TAc=[1000]
Nac=[400]
ch5=input("Enter your choice")
fav=raw_input("ENter hotel choice")
mode=raw_input("Enter ac/no ac")
if(ch5==1):
for i in hd:
frate=hd[i]+TAc
else:
frate=hd[i]+Nac
if(ch5==2):
for i in range(0,2,1):
frate=hg[i]+TAc
else:
frate=hg[i]+Nac
accomodation()
travel()
When i run the program , i get the error as List Index out of range.but in hd and hg list,there are only two elements, so index number will be from 0 right?? Is there anything i should import?? I even gave statements like this:
travel.frate=travel.hg[i]+TAc
but it still doesn't come.Thank you for your effort.
the indentation is proper now,but the output is still not coming.
The specific issue you are encountering is caused by these lines here:
if(ch5==1):
for i in hd:
frate=hd[i]+TAc
hd[i] looks at hd[5000] and hd[6000] which will throw an IndexError.
But if you fix that, you're going to run into another error, because
frate=hd[i]+TAc
tries to add a list TAc to an integer hd[i], which is an unsupported operation. You probably need frate=hd[i]+TAc[0], or even better, make TAc a number rather than a list. This issue occurs elsewhere in your code as well.
Finally, while not causing explicit issues in your code right now, there are two other problems:
ch5=input("Enter your choice") is dangerous since input tells Python to run whatever code snippet the user enters. In this case, much safer to do ch5=int(raw_input("Enter your choice"))
for i in range(0,2,1): is really for i in range(2): - only use the starting index and jump parameters if you need to change them from their default, namely 0 and 1.
There are other issues like variable scope (you're expecting travel.frate to be modified from within accommodation, but that's not happening) and defining variables in functions like travel.frate (not invalid syntax, but definitely strange) but those are probably better addressed outside of this question.