I'm writing a simple program to help generate orders for a game I'm a member of. It falls into the catergory of programmes I don't actually need. But now I've started I want it to work. It all pretty much runs smoothly but I can't figure out how to stop a type-error ocurring about half way through. Here's the code;
status = 1
print "[b][u]magic[/u][/b]"
while status == 1:
print " "
print "would you like to:"
print " "
print "1) add another spell"
print "2) end"
print " "
choice = input("Choose your option: ")
print " "
if choice == 1:
name = raw_input("What is the spell called?")
level = raw_input("What level of the spell are you trying to research?")
print "What tier is the spell: "
print " "
print "1) low"
print "2) mid"
print "3) high"
print " "
tier = input("Choose your option: ")
if tier == 1:
materials = 1 + (level * 1)
rp = 10 + (level * 5)
elif tier == 2:
materials = 2 + (level * 1.5)
rp = 10 + (level * 15)
elif tier == 3:
materials = 5 + (level * 2)
rp = 60 + (level * 40)
print "research ", name, "to level ", level, "--- material cost = ",
materials, "and research point cost =", rp
elif choice == 2:
status = 0
Can anyone help?
edit
The error I get is;
Traceback (most recent call last):
File "C:\Users\Mike\Documents\python\magic orders", line 27, in <module>
materials = 1 + (level * 1)
TypeError: unsupported operand type(s) for +: 'int' and 'str'
A stacktrace would've helped, but presumably the error is:
materials = 1 + (level * 1)
‘level’ is a string, and you can't do arithmetic on strings. Python is a dynamically-typed language, but not a weakly-typed one.
level= raw_input('blah')
try:
level= int(level)
except ValueError:
# user put something non-numeric in, tell them off
In other parts of the program you are using input(), which will evaluate the entered string as Python, so for “1” will give you the number 1.
But! This is super-dangerous — imagine what happens if the user types “os.remove(filename)” instead of a number. Unless the user is only you and you don't care, never use input(). It will be going away in Python 3.0 (raw_input's behaviour will be renamed input).
Here is an example of a Type Error and how to fix it:
# Type Error: can only concatenate str (not "int") to str
name = "John"
age = 30
message = "My name is " + name + " and I am " + age + " years old."
# Fix:
message = "My name is " + name + " and I am " + str(age) + " years old."
In the above example, the error message says that we're trying to concatenate a string and an integer which is not possible. So, we need to convert the integer to string using str() function to fix the error.
Related
I'm writing a simple program to help generate orders for a game I'm a member of. It falls into the catergory of programmes I don't actually need. But now I've started I want it to work. It all pretty much runs smoothly but I can't figure out how to stop a type-error ocurring about half way through. Here's the code;
status = 1
print "[b][u]magic[/u][/b]"
while status == 1:
print " "
print "would you like to:"
print " "
print "1) add another spell"
print "2) end"
print " "
choice = input("Choose your option: ")
print " "
if choice == 1:
name = raw_input("What is the spell called?")
level = raw_input("What level of the spell are you trying to research?")
print "What tier is the spell: "
print " "
print "1) low"
print "2) mid"
print "3) high"
print " "
tier = input("Choose your option: ")
if tier == 1:
materials = 1 + (level * 1)
rp = 10 + (level * 5)
elif tier == 2:
materials = 2 + (level * 1.5)
rp = 10 + (level * 15)
elif tier == 3:
materials = 5 + (level * 2)
rp = 60 + (level * 40)
print "research ", name, "to level ", level, "--- material cost = ",
materials, "and research point cost =", rp
elif choice == 2:
status = 0
Can anyone help?
edit
The error I get is;
Traceback (most recent call last):
File "C:\Users\Mike\Documents\python\magic orders", line 27, in <module>
materials = 1 + (level * 1)
TypeError: unsupported operand type(s) for +: 'int' and 'str'
A stacktrace would've helped, but presumably the error is:
materials = 1 + (level * 1)
‘level’ is a string, and you can't do arithmetic on strings. Python is a dynamically-typed language, but not a weakly-typed one.
level= raw_input('blah')
try:
level= int(level)
except ValueError:
# user put something non-numeric in, tell them off
In other parts of the program you are using input(), which will evaluate the entered string as Python, so for “1” will give you the number 1.
But! This is super-dangerous — imagine what happens if the user types “os.remove(filename)” instead of a number. Unless the user is only you and you don't care, never use input(). It will be going away in Python 3.0 (raw_input's behaviour will be renamed input).
Here is an example of a Type Error and how to fix it:
# Type Error: can only concatenate str (not "int") to str
name = "John"
age = 30
message = "My name is " + name + " and I am " + age + " years old."
# Fix:
message = "My name is " + name + " and I am " + str(age) + " years old."
In the above example, the error message says that we're trying to concatenate a string and an integer which is not possible. So, we need to convert the integer to string using str() function to fix the error.
I am trying to create a basic online store in python. But whenever I try to 'buy' an item it shows an error with my dictionary or something I am not sure.
The error: users[n]["Transactions"] = users[n]["Transactions"] + str(names_f, "bought", quanti, "of", final[choice*3], "with a total price of $"+price)
TypeError: str() takes at most 3 arguments (6 given)
coun = 0
users = [{"name":"Jack","username":"ja", "cc":'12345',"email":'whwhwwhh', "code": '111', "Transactions": ""}]
def sign_in():
username = input("Enter username")
for i in range (len(users)):
for x in users[i].values():
if x == username:
pin = input("Enter pin")
if pin == users[i].get("code"):
print("Welcome", users[i].get("name"))
menu(username,users[i].get("name"))
break
else:
print("Wrong pin")
sign_in()
def menu (usern, names_f):
global coun
if coun == 0:
order = ''
total = 0
for i in range (len(categories)):
print(str(i+1)+".", categories[i])
choice = int(input("Choose a category by typing the number beside the categories name."))-1
print("Items in this list are")
print("Itemname \t Price \t Stock")
final = location[choice]
for c in range((int(len(final)/3))):
print(str(c+1)+'.',str(final[c*3]),"\t",'$'+str(final[c*3+1])), "\t", str(final[(c*3)+2])
choice = int(input("Which item (Type number on left of the item name)"))-1
while True:
quanti = int(input("How many do you want to buy"))
if quanti > final[choice*3+2]:
print("Sorry your request for", quanti, "Is more than we have at the store please try again")
continue
else:
price = str(quanti*final[choice*3+1])
final[choice*3+2] = final[choice*3+2]-quanti
print("Thank you for your purchasing",quanti,"of", final[choice*3], "Your total price of this buy is", '$'+price)
for n in range (len(users)):
if usern == users[n].get("username"):
users[n]["Transactions"] = users[n]["Transactions"] + str(names_f, "bought", quanti, "of", final[choice*3], "with a total price of $"+price)
order += str(quanti, 'of', final[choice*3])
price += int(price)
done = input("Do you want to check out then type '1' if you want to continue type '2'")
if done == '1':
print("Thank you")
print ("Invoice:", order, "/n total price (HKD) $"+str(price))
else:
coun += 1
menu(usern,names_f)
variable_name = users[n]["Transactions"] + str(names_f) + "bought" + str(quanti) + "of" + str(final[choice*3]) + "with a total price of $"+ str(price)
users[n]["Transactions"] = variable_name
You will maybe need to declare variable_name somewhere.
Problem is that str usage is following
str(object, encoding=encoding, errors=errors)
but whenever you pass comma it count it as another parameter.
P.S. I'm not sure if you need all those str in my solution.
str is a class, and as stated in the docs you can pass up to 3 parameters to it:
class str(object=b'', encoding='utf-8', errors='strict')
Also, it also says what it does:
Return a string version of object. If object is not provided, returns the empty string.
Meaning it is used to cast other types to string. Thus, you need to convert every int individually:
users[n]["Transactions"] = users[n]["Transactions"] + str(names_f) + " bought " + str(quanti) + " of " + str(final[choice*3]) + " with a total price of " + str(price)
Note the spaces before and after every string. Alternatively, you can format your string:
users[n]["Transactions"] = users[n]["Transactions"] + '%s bought %s of %s with a total price of %s' % (names_f, quanti, final[choice*3], price)
As a side note, it's worth checking what happens when the first transaction is made. If the key Transactions does not yet exist, you need to add an initial value before accessing it.
I usually do it like:
if key not in dict_:
dict_[key] = 'my initial value'
dict_[key] += 'add my stuff'
another solution would be using the get method, which allows you to add a default value:
dict_.get(key, 'default')
Note that this will not add the key to the dictionary, meaning that trying to access its value later on will still result in a Key Error.
I'm new to StackOverflow (1st time posting) and new to coding with python. Currently enrolled in a course through Udacity. I'm having a very hard time with a project we were given for this course and decided to come here to see if anyone could help.
The project is to create a quiz with 4 blanks that need to be answered correctly by the player. It's required to have the quiz print out with the correct answer, but I'm having a very hard time getting this to print out correctly.
My code is below. Would appreciate any help or advice I can get on this.
Thanks!
easy_quiz = "If you ever get stuck, check out the __1__ for common
problems students face when attempting this project. If you need
additional help, you can schedule a 1:1 appointment with one of our
__2__ to get you un-stuck. This project should be __3__. If at any time
it becomes not fun, take a step back, deep breath, and ask for __4__!.
\n\n"
easy_answers = ["forums", "mentors", "fun", "help"]
medium_quiz = "Game must have 3 or more levels and each level contains 4 or more __1__ to fill in. Immediately after running the program, user is prompted to select a difficulty level from easy / __2__ / hard. Once a level is selected, game displays a fill-in-the-blank and a prompt to fill in the first one. When player guesses __3__, new prompt shows with correct answer in the previous blank and a new prompt for the next blank. When player guesses __4__, they are prompted to try again. \n"
medium_answers = ["blanks", "medium", "correctly", "incorrectly"]
hard_quiz = "__1__ are used as __2__ to automate tasks which are likely to be repeated. Functions produce the appropriate output (typically with a __3__ statement) from the appropriate input (function parameters). Your code should take advantage of __4__ and variable names should reflect the values they store. \n"
hard_answers = ["Functions", "tools", "return", "variables"]
blanks = ["__1__", "__2__", "__3__", "__4__"]
difficulty = raw_input("\nChoose your difficuty level = easy, medium, or hard? ")
print ""
if difficulty == "easy":
quiz = easy_quiz
answers = easy_answers
print "You chose easy!\n\nYou will have 5 guesses to fill in each blank. Good Luck!!\n \n" + easy_quiz
elif difficulty == "medium":
quiz = medium_quiz
answers = medium_answers
print "You chose medium!\n\nYou will have 5 guesses to fill in each blank. Good Luck!!\n \n" + medium_quiz
elif difficulty == "hard":
quiz = hard_quiz
answers = hard_answers
print "You chose hard!\n\nYou will have 5 guesses to fill in each blank. Good Luck!!\n \n" + hard_quiz
def word_in_pos(word, parts_of_speech):
for pos in parts_of_speech:
if pos in word:
return pos
return None
def play_game(quiz, parts_of_speech):
replaced = []
i = 0
quiz = quiz.split()
for word in quiz:
replacement = word_in_pos(word, parts_of_speech)
if replacement != None:
user_input = raw_input("Type an answer for: " + replacement + " " )
word = word.replace(replacement, user_input)
replaced.append(word)
guesses = 0
while user_input != answers[i]:
guesses = guesses + 1
print "Incorrect, try again \n" + " ".join(replaced)
user_input = raw_input("Type an answer for: " + replacement + " ")
if guesses == 4:
return "\nGame Over! Better luck next time. \n"
print "Correct \n" + " ".join(replaced)
i = i + 1
word = word.replace(replacement, user_input)
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
return replaced
print play_game(quiz, blanks)
Here is a working version of your play_game() method:
def play_game(quiz, parts_of_speech):
replaced = []
i = 0
quiz = quiz.split()
for word in quiz:
replacement = word_in_pos(word, parts_of_speech)
if replacement is not None:
user_input = raw_input("Type an answer for: " + replacement + " " )
guesses = 0
while user_input != answers[i]:
guesses = guesses + 1
if guesses == 5:
return "\nGame Over! Better luck next time. \n"
print "Incorrect, try again \n" + " ".join(replaced) + " " + replacement
user_input = raw_input("Type an answer for: " + replacement + " ")
replaced.append(user_input)
print "Correct \n" + " ".join(replaced)
i = i + 1
else:
replaced.append(word)
replaced = " ".join(replaced)
return replaced
The main change is to delay modifying the replaced list until the correct answer has been given. That simplifies a lot of the code, eliminating the need for the word variable.
As shown, I have written this code and have assigned values for CASH and TOTAL. What I can not understand is why I get.....
"Traceback (most recent call last):
File "C:\Python27\Checkout Counter2.py", line 29, in
change = cash - total
TypeError: unsupported operand type(s) for -: 'str' and 'str'"
I've tried multiple ways to make this work, and I dont see any difference between that and when it finds the total.
print "Welcome to the checkout counter! How many items are you purchasing today?"
#NOI is number of items
NOI = int(raw_input())
productlist = []
pricelist=[]
for counter in range(NOI):
print"Please enter the name of product", counter+1
productlist.append(raw_input())
print"And how much does", productlist[len(productlist)-1], "cost?"
pricelist.append(float(raw_input()))
if pricelist[len(pricelist)-1] < 0:
pricelist.pop()
productlist.pop()
len(productlist)-1
len(pricelist)-1
print "Your order was:"
subtotal=0.00
for counter in range(NOI):
print productlist[counter],
print "$%0.2f" % pricelist[counter]
subtotal += pricelist[counter]
total = "$%0.2f" % float(subtotal + (subtotal * .09))
print "Your subtotal comes to", "$" + str(subtotal) + ".", " With 9% sales tax, your total is " + str(total) + "."
print "Please enter cash amount:"
cash = raw_input()
while True:
change = cash - total
if cash < total:
print "You need to give more money to buy these items. Please try again."
else:
print "I owe you back", "$" + float(change)
"raw_input" will always return a string (even if you enter 3 or 3.5)
Therefore you have to:
cash = float(cash)
total = float(total)
Edit: Also, when you do:
total = "$%0.2f" % float(subtotal + (subtotal * .09))
total will also be a string, that is why you also have to convert it to float.
Hope it helps.
I am trying to get my program to limit what the user can type in. It keeps returning an "Expected an indented block" error from my code below.
deliverydetails = input("Is your order for delivery?\n Press 1 for delivery. Press 2 for pickup")
if deliverydetails == "1":
## def delivery ():
print ("Order for Delivery")
customerfirstname = " "
while len(customerfirstname) <3 or len(customerfirstname)>30 or customerfirstname.isalpha() != True:
customerfirstname = input("Customer First Name: ** must be 4 characters long + " ")
while len(customersurname) < 3 or len(customersurname) > 30 or customerfirstname.isalpha() != True:
customersurname = input("Customer Surname:" + " ")
customerstreet = input("Street name:" + " ")
customerstreetnumber = input("Street number:" + " ")
customercity = input("City:" + " ")
customersuburb = input("Suburb (If none, leave blank):" + " ")
latestOrder.append(customerfirstname)
latestOrder.append(customersurname)
latestOrder.append(customerstreet)
latestOrder.append(customerstreetnumber)
latestOrder.append(customercity)
latestOrder.append(customersuburb)
Python uses indentation to group blocks of code. After the while statements, you want to indent the lines below it that should be executed inside the while loop.
Here are some other tips that may be useful:
- Use pylint to check your syntax. It will uncover a lot of errors that you would otherwise only find out during runtime.
- Use spaces to indent. Don't use tabs. That's a PEP 8 style recommendation
Here is the corrected version of your code:
deliverydetails = input("Is your order for delivery?\n Press 1 for delivery. Press 2 for pickup")
if deliverydetails == "1":
## def delivery ():
print ("Order for Delivery")
customerfirstname = " "
customersurname = " "
while len(customerfirstname) <3 or len(customerfirstname)>30 or customerfirstname.isalpha() != True:
customerfirstname = input("Customer First Name: ** must be 4 characters long + " ")
while len(customersurname) < 3 or len(customersurname) > 30 or customerfirstname.isalpha() != True:
customersurname = input("Customer Surname:" + " ")
customerstreet = input("Street name:" + " ")
customerstreetnumber = input("Street number:" + " ")
customercity = input("City:" + " ")
customersuburb = input("Suburb (If none, leave blank):" + " ")
latestOrder.append(customerfirstname)
latestOrder.append(customersurname)
latestOrder.append(customerstreet)
latestOrder.append(customerstreetnumber)
latestOrder.append(customercity)
latestOrder.append(customersuburb)
Python uses intentation instead of {} or begin/end, so for example this line
while len(customerfirstname) <3 or len(customerfirstname)>30 or customerfirstname.isalpha() != True:
should be followed by an indented block. An indented block can be as short as a single line, usually you should indent it 4 spaces more than the while
Aside: it may be clearer to write that line as
while not (3 <= len(customerfirstname) <= 30 and customerfirstname.isalpha()):
Make sure to indent the lines that are part of the loop. That's the only way Python has to know what part you want to loop.
delivery_details = input("Is your order for delivery?\n Press 1 for delivery. Press 2 for pickup")
if delivery_details == "1":
print "Order for Delivery"
customer_first_name = ""
while len(customer_first_name) < 3 or len(customer_first_name) > 30 or not customer_first_name.isalpha():
customer_first_name = input("First name (must be 4 characters long): ")
customer_surname = input("Surname: ")
customer_street = input("Street name: ")
customer_street_number = input("Street number: ")
customer_city = input("City: ")
customer_suburb = input("Suburb (If none, leave blank): ")
latest_order.append(customer_first_name)
latest_order.append(customer_surname)
latest_order.append(customer_street)
latest_order.append(customer_street_number)
latest_order.append(customer_city)
latest_order.append(customer_suburb)
For what it's worth I've made some stylistic changes for readability. Some extra spacing, blank lines, and underscores in variable names make everything a bit easier on the eyes.