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.
Related
I have this function, which is part of a larger code I am working on for a class, so I am not looking for all the answers, just a little help with this part because I really don't know how to proceed. I have a function that asks for multiple inputs. firstname, lastname, bus row, and bus seat. these are then split and printed into a text file that I will do some other things with that i have not included the code for because I am still working on it.
the first two entries need to be strings(first and last name), and the second two need to be numbers ( at least for now) the first number needs to be 1-4(row), and the second needs to be 1-15(seat), because that is all the seats available. I want an error to come back if anything else is entered in the following code.
def purchase():
while True:
try:
firstname, lastname, bus_row, bus_seat = input(
'Enter name first and last name and bus row and seat:').split()
print("Name: {} {}\nrow {} seat {}".format(firstname, lastname, bus_row, bus_seat))
with open('bookings.txt', 'a') as bookings:
bookings.write('\n' + firstname + " " + lastname + " " + bus_row + " " + bus_seat)
break
except ValueError:
print('Invalid entry')
return
purchase()
This should work. You don't need to raise anything because you are already in a try/except. Simply you assert there are exactly 4 inputs and they are 2 strings and 2 integers. if they are not the program runs into an error and prints 'Invalid Entry'
def purchase():
while True:
try:
variables = input('Enter name first name, last name, bus row and bus seat:').split()
assert len(variables) == 4
firstname, lastname, bus_row, bus_seat = variables
for i in firstname:
assert not i.isdigit()
for i in lastname:
assert not i.isdigit()
bus_row = int(bus_row)
bus_seat = int(bus_seat)
assert 0 < bus_row < 5 and 0 < bus_seat < 16
print("Name: {} {}\nrow {} seat {}".format(firstname, lastname, bus_row, bus_seat))
with open('bookings.txt', 'a') as bookings:
bookings.write('\n' + firstname + " " + lastname + " " + str(bus_row) + " " + str(bus_seat))
break
except:
print('Invalid entry')
purchase()
Hope I helped
You will need to include something like this in your code:
try:
bus_row = int(bus_row)
bus_seat = int(bus_seat)
if not 1 <= bus_row <= 4:
raise ValueError("A bus row should be a whole number between 1 and 4")
if not 1 <= bus_seat <= 15:
raise ValueError("A bus seat should be a whole number between 1 and 15")
except ValueError as e:
# handle the exception
Don't assign firstname, lastname, etc. until you know they entered exactly four things. If they entered more or fewer, the assignment will fail.
# keep prompting until they enter correct input
while True:
answers = input('Enter name and ...').split()
if len(answers) != 4:
print('You did not enter the correct number of answers')
continue
firstname, lastname, bus_row, bus_seat = answers
if not firstname.isalpha():
print('First name must be only letters')
continue
# do the same for last name ...
if not bus_row.isdigit():
print('Bus row must be a number')
# do the same for bus seat ...
# if we make it all the way here, the input must be correct, so break the loop
break
I am trying to create a function that will receive input from a list and justify whether it is a float value or not, and if it is, continue with the program, and if it is not, ask the user to enter the answer a second time. The new value should go into the list at the same index as the previous, incorrect value.
For example, if somebody inputted into my code the value 'seventy-two' instead of 72, I want the inputHandler function to receive this incorrect value, tell the user that it is invalid, and ask the user to answer the same question again.
I want my function to use try-except-else statements. Here is my code:
QUIZ_GRADES = int(input("How many quiz grades? "))
PROGRAM_GRADES = int(input("How many program grades? "))
TESTS = int(input("How many tests? "))
def main():
globalConstantList = [QUIZ_GRADES, PROGRAM_GRADES, TESTS]
scoreList = []
returnedScoreList = getGrades(globalConstantList,scoreList)
returnedScoreValue = inputHandler(returnedScoreList)
returnedScoreValue2 = inputHandler(returnedScoreList)
returnedScoreListSum, returnedScoreListLength = totalList(returnedScoreList)
returnedScoreListAverage = calcAverage(returnedScoreListSum,
returnedScoreListLength)
returnedLetterGrade = determineGrade(returnedScoreListAverage)
userOutput(returnedScoreListAverage,returnedLetterGrade)
def getGrades(globalConstantList,scoreList):
for eachScore in globalConstantList:
#totalScoreList = 0.0
index = 0
for index in range(QUIZ_GRADES):
print("What is the score for", index + 1)
scoreList.append(float(input()))
index += 1
for index in range(PROGRAM_GRADES):
print("What is the score for", index + 1)
scoreList.append(float(input()))
index += 1
for index in range(TESTS):
print("What is the score for", index + 1)
scoreList.append(float(input()))
index += 1
return scoreList
def inputHandler(scoreList):
index = 0
try:
print("What is the score for", index + 1)
scoreList.append(float(input()))
return scoreList
except ValueError:
print("Your value is not correct. Try again.")
print("What is the score for", index + 1)
scoreList.append(float(input()))
return scoreList
def totalList(newScoreList):
returnedScoreListLength = len(newScoreList)
returnedScoreListSum = sum(newScoreList)
return returnedScoreListSum, returnedScoreListLength
def calcAverage(newScoreListSum, newScoreListLength):
returnedScoreListAverage = newScoreListSum / newScoreListLength
return returnedScoreListAverage
def determineGrade(newScoreListAverage):
if newScoreListAverage >= 90:
return 'A'
elif newScoreListAverage >= 80:
return 'B'
elif newScoreListAverage >= 70:
return 'C'
elif newScoreListAverage >= 60:
return 'D'
else:
return 'F'
def userOutput(newScoreListAverage, newLetterGrade):
print("Your overall grade is",format(newScoreListAverage,'.2f'))
print("Your letter grade is",newLetterGrade)
print()
main()
As far as I understand, you want to check an user's input and convert it to a float. If successful, you want to proceed, if not, you want to ask again.
Assuming this is the case, you might want to write a function which asks for user input, tries to convert input to float, and returns it if successful.
def input_float(prompt):
while True:
try:
inp = float(input(prompt))
return inp
except ValueError:
print('Invalid input. Try again.')
f = input_float('Enter a float')
print(f)
You can then use this snippet as a starting point for further handling of f (which is a float) the user provided.
You can check your number float or int or string using if elif statement then do your work in side the body of your code
num = input("Enter a number ")
if type(num ) == int : print "This number is an int"
elif type(num ) == float : print "This number is a float"
here you can use function to call this code again and again and place this code in that function and also use try bock to catch exception .
I am having trouble getting past writing user input to my list what am I doing wrong here? This is an address book program that I am writing, the assignment is to create parallel lists that will store user input data in the appropriate list using a for or while loop. The program must also have a search function which you can see is at the bottom of the code. My issue that I am having is getting the program to store data within my lists. Unfortunately lists are something that give me lots of trouble I just cant seem to wrap my head around it no matter how much research I have done. The issue im running into is the append.data function when trying to write lastname and firstname to my list of names. what am I doing wrong?
#NICHOLAS SHAFFER
#5/11/2016
#MYADDRESSBOOK
def menu():
index = 0
size = 100
count = 0
answer = raw_input("Are You Creating An Entry [Press 1] \nOr Are You Searching An Entry [Press 2] ")
if answer == "1" :
print ("This is where we create")
append_data(index, size, count)
elif answer == "2" :
print ("this is where we search")
search_database()
name[size]
phone[size]
addresss[size]
# IF we are creating
def append_data(index, size, count):
# collect information
for index in range(0, 100):
optOut = 'no'
while optOut == 'no':
lastname[count] = raw_input("What is the persons last name? ")
firstname[count] = raw_input("What is the persons first name? ")
phone[count] = raw_input("What id the persons phone number? ")
address[count] = raw_input("What is the persons address? ")
count = count + 1
print 'Would you like to create another entry?'
optOut = raw_input('Would you like to create another entry? [ENTER YES OR NO]:')
if optOut == 'yes':
menu()
#create string to print to file
#print temp1
#print (firstname + " " + lastname + ", " + phone + ", " + email + ", " + address)
print listName[index]
print listPhone[index]
print listAddress[index]
print 'file has been added to your addressbook sucessfuly'
menu()
# SEARCHING FOR A RECORD
def search_database():
searchcriteria = raw_input("Enter your search Criteria, name? phone, or address etc ")
print searchcriteria
if searchcriteria == "name":
temp1 = open(listName[lastname, firstname],"r")
print temp1
if searchcriteria == "phone":
temp1 = open(listPhone[0], "r")
print temp1
if searchcriteria == "address":
temp1 = open(listAddress[0], "r")
print temp1
else:
print "sorry you must enter a valid responce, try again."
menu()
for line in temp1:
if searchcriteria in line:
print line
errorMessage()
# USER DID NOT PICK CREATE OR SEARCH
def errorMessage():
print ("Incorrect Answer")
exit()
menu()
Your error message says it all:
line 34, in append_data lastname[count]... NameError: global name 'lastname' is not defined
You'll get this same error if you type lastname[4] in any interpreter -- you've simply never defined a list called lastname, so you can't access items in it. In the short term, you can fix this with a line
lastname = list()
You're going to end up with more troubles though; lastname won't be accessible outside the function where you define it, neither will listName. I'd probably approach that by writing them into a data file/database, or maybe creating a quick class whose members will all have access to self.lastname.
My final append for lists thanks again Noumenon
def append_data(index, size, count):
lastnames = list()
if count < size -1:
lastname = raw_input("What is the persons last name? ")
lastnames.append(lastname)
print lastnames
firstnames = list()
if count < size - 1:
firstname = raw_input("What is the persons first name? ")
firstnames.append(firstname)
print firstnames
phones = list()
if count < size - 1:
phone = raw_input("What id the persons phone number? ")
phones.append(phone)
print phones
addresss = list()
if count < size - 1:
address = raw_input("What is the persons address? ")
addresss.append(address)
print addresss
listName = (lastnames, firstnames)
addressbook =(listName, phones, addresss)
index = index + 1
count = count + 1
print addressbook
optOut = raw_input('Would you like to create another entry? [Enter YES or NO]: ')
if optOut == 'YES':
menu()
print 'file has been added to your addressbook sucessfuly'
menu()
I'm trying to compare two string values that was retrieved in my first function, but it doesn't work. It keeps telling me 'invalid syntax' and moves my cursor over to the elif line.
This is my program...
def find_number_of_service():
with open('TheData.txt', 'r') as data_file:
data = data_file.read()
countS = data.count('S')
countW = data.count('W')
print ("There are " + str(countS) + " S's")
print ("There are " + str(countW) + " W's")
return
def find_popular_service():
if (countS) > (countW):
print ("The most used service to buy tickets was the school.")
elif print ("The most used service to buy tickets was the website.")
return
#Main program
find_number_of_service()
find_popular_service()
Thank you in advance.
Problem in second function elif you have not defined correctly it should be elif <condition>:
Here the working function
def find_popular_service():
if (countS) > (countW):
print ("The most used service to buy tickets was the school.")
else:
print ("The most used service to buy tickets was the website.")
return
You don't give elif a condition. elif means otherwise if.... Perhaps you mean else.
elif should be in line with if
print ... should be on a new line.
I am making a Recipe book, at the moment I have the ability to create a recipe, but now I am starting to build the module of searching and displaying stored recipes.
At the moment I have a .txt document with the contents along the lines of:
Williams Special Recipe
Ingredients:
bread: 120 grams
butter: 1234 grams
Recipe Serves: 12
I then ask the user how many they are serving and based on how many the recipe serves, I need to multiply all the ingredients quantity by that number. I then need to print that off with the full recipe again.
I was wondering how I would go about achieving this result, not asking specifically for a coded response as an answer, but I would greatly appreciate how I would approach this task and any specific functions required.
I have also included my code so far, I appreciate the fact it is incredibly un-organised at the moment, and probably hard to understand, but I included it for any reference.
(I have also created a .txt file of all the created recipes which will be implemented later on as a way of displaying to the user all recipes, but at the moment it is just set up for searching.)
#Recipe Task
import os.path
def file_(n):
if n == "listR" :
list_f = open("list_recipes.txt", "a+")
list_f.write(new_name + "\n")
if n == "oar": #open append read
f=open(new_name + ".txt","a+")
elif n == "c": #closes file
f.close()
def print_line(x): #ease of printing multiple lines to break up text
for c in range(x):
print ""
def new_ingredients(): #adding new ingredients
f.write("Ingredients:" + "\n" + "\n")
fin_ingredient = False
while fin_ingredient != True :
input_ingredient = raw_input("New ingredient:" + "\n").lower()
split_ingred = input_ingredient.split()
if input_ingredient == "stop": #stops asking questions when user types 'stop'
fin_ingredient = True
else :
f.write(split_ingred[0] + ":" + " " + split_ingred[1] + " " + split_ingred[2] + "\n")
def search_recipe(n): #searching for recipes
n = n + ".txt"
if os.path.isfile('/Users/wjpreston/Desktop/' + n) == True :
print "Recipe Found..."
found_recipe = open(n)
print found_recipe.read()
append_serving = raw_input("Would you like to change the number of people you are serving?" + "\n").lower()
if append_serving == "yes" :
appended_serving = input("How many would you like to serve?" + "\n")
with open(n) as f: #here is my issue - not sure where to go with this!!
list_recipe = f.readlines()
found_recipe.close()
else :
print "fail"
else:
print "No existing recipes under that name have been found."
print "Welcome to your Recipe Book"
print_line(3)
recipe_phase = raw_input("Are you 'creating' a recipe or 'viewing' an existing one?" + "\n").lower()
if recipe_phase == "creating":
new_name = raw_input("Name of Recipe: " + "\n")
file_("listR")
file_("oar")
f.write("------------" + "\n" + new_name + "\n" + "\n")
print "Ingrediants required in the format 'ingredient quantity unit' - type 'stop' to end process"
new_ingredients()
new_num = input("Number serving: ")
f.write("\n" + "Recipe Serves: " + str(new_num) + "\n" "\n" + "\n")
file_("c")
elif recipe_phase == "viewing":
search = raw_input("Search for recipe: ")
search_recipe(search)
I'm not the specialist in processing strings, but I'd approach your problem following way:
Save each ingredient on a new line.
Split the loaded string by "\n".
Then process the list with some for-loops while creating two dicts, one for the actual data
e.g. {"bread": 4, "butter": 7}
and one for the types of each ingredient:
e.g. {"bread": grams, "butter": grams}
The you should also save how many serves the recipe is written for, and maybe the order of the ingredients (dicts get stored in a random order):
e.g. ["bread", "butter"]
After that, you can ask your costumer how many serves he has and then finally calculate and print the final results.
for ing in ing_order:
print ing+":", ing_amount[ing]*requested_serves/default_seves, ing_types[ing]
...hopyfully you still have enough challange, and hopefully I understood your question correctly.