Python Supermarket combine lists and format - python

I have to create a program that asks user to input the number of items to purchase. the program then asks the user to enter the item and price of each, give a total and provide the amount of change.
I am stuck on the part where I need to combine the lists and output the item and cost in currency format
#Checkout program
print "Welcome to the checkout counter! How many items will you be purchasing?"
number = int (raw_input ())
grocerylist = []
costs = []
for i in range(number):
groceryitem = raw_input ("Please enter the name of product %s:" % (i+1))
grocerylist.append(groceryitem)
itemcost = float(raw_input ("What is the cost of %s ?" % groceryitem))
costs.append(itemcost)
order = {}
for index in range (min(len(grocerylist), len(costs))):
order[grocerylist[index]] = costs[index]
print ("This is your purchase") + str(order)

# the simple way
for index in range (min(len(grocerylist), len(costs))):
print("Item: %s Cost: $%5.2f " % (grocerylist[index], costs[index]))
or you can use the locale currency() function.. see Currency formatting in Python or https://docs.python.org/2/library/locale.html

In addition to the above approaches, you can also iterate over order.keys(). And to format use the in-built string methods. Here's an example.
>>> order = {1 : 10.23, 2 : 1.0, 3 : 3.99}
>>> for key, val in order.items():
... print "Item " + key + ": ", "$" + "{0:.2f}".format(val)
...
Item 1: $10.23
Item 2: $1.00
Item 3: $3.99

you can directly store it in dictionary:
#Checkout program
print "Welcome to the checkout counter! How many items will you be purchasing?"
number = int(raw_input ())
order = {}
for i in range(number):
groceryitem = raw_input("Please enter the name of product %s:" % (i+1))
itemcost = float(raw_input("What is the cost of %s ?" % groceryitem))
order[groceryitem] = itemcost
print("your Purchase")
for x,y in order.items():
print (str(x), "$"+str(y))
note: order.values() will give you price list
order.keys() will give you item list
Read about dictionary here :Dictionary
demo:
>>> order = {'cake':100.00,'Coke':15.00}
>>> for x,y in order.items():
... print(x,"$"+str(y))
...
cake $100.0
Coke $15.0
better using format:
>>> for x,y in enumerate(order.items()):
... print("Item {}: {:<10} Cost ${:.2f}".format(x+1,y[0],y[1]))
...
Item 1: cake Cost $100.00
Item 2: Coke Cost $15.00
Make it tabular:
print("{:<5}{:<10}{}".format("Num","Item","Cost"))
for x,y in enumerate(order.items()):
print("{:<5}{:<10}${:.2f}".format(x+1,y[0],y[1]))
print("{:>10}{:>6}{:.2f}".format("Total","$",sum(order.values())))
Num Item Cost
1 cake $100.00
2 Coke $15.00
Total $115.00

Related

invoice (receipt) program in python. How to prevent overwriting old values

I'm a new learner for python and I'm trying to make a program that prints in invoice of all the items + their price + their quantity. each item is in separate line.
I have got tot he point where I print each item in a line, but I keep overwriting the old values by the last value entered. how can I prevent this?
this is the code:
print("This program prints your invoices."
"\nPlease enter the item identification, item cost and quantity sold when promted."
"\nEnter 'done' when no more items"
"\n=========================================")
saveqty= ()
savetprice=()
qtysum= 0 #quantity =qty for short
sumprice=0
list1 = []
totalprice=0
while True:
itemid = input('Item identification: ')
if itemid == "done":
break
if len(itemid)<3:
print("item identification should be at least 3 characters long, try again")
continue
else:
list11 = list[itemid]
list1 +=[itemid]
qtysold = input("Qty sold: ")
try:
qtysold =int(qtysold)
except ValueError:
print("must be an integer value, try again")
continue
qtysum+=qtysold
try:
itemprice = float(input("Item price: "))
savetprice= (itemprice)
except ValueError:
print("item price must be numerical value, try again")
continue
totalprices= (qtysold*itemprice)
totalprice+=totalprices
for elem in list1:
print(qtysold,'x ',elem, '# ', savetprice, 'SAR', '===', totalprices)
total = sumprice
itemtotal = qtysum
print("=========================================\nNo. of items purchased: ", itemtotal,"\nTotal price is: ", totalprice, "SAR")
Below is the code that fixes your problem
print("This program prints your invoices."
"\nPlease enter the item identification, item cost and quantity sold when promted."
"\nEnter 'done' when no more items"
"\n=========================================")
saveqty = ()
savetprice = ()
qtysum = 0 # quantity =qty for short
sumprice = 0
list1 = []
totalprice = 0
while True:
itemid = input('Item identification: ')
if itemid == "done":
break
if len(itemid) < 3:
print("item identification should be at least 3 characters long, try again")
continue
qtysold = input("Qty sold: ")
try:
qtysold = int(qtysold)
except ValueError:
print("must be an integer value, try again")
continue
qtysum += qtysold
try:
itemprice = float(input("Item price: "))
savetprice = (itemprice)
except ValueError:
print("item price must be numerical value, try again")
continue
totalprices = (qtysold * itemprice)
totalprice += totalprices
list1.append((itemid, qtysold, savetprice, totalprices))
for elem, qtysold, savetprice, totalprices in list1:
print(qtysold, 'x ', elem, '# ', savetprice, 'SAR', '===', totalprices)
total = sumprice
itemtotal = qtysum
print("=========================================\nNo. of items purchased: ", itemtotal, "\nTotal price is: ", totalprice, "SAR")
Output:
This program prints your invoices.
Please enter the item identification, item cost and quantity sold when promted.
Enter 'done' when no more items
=========================================
Item identification: 123
Qty sold: 5
Item price: 20
Item identification: 456
Qty sold: 3
Item price: 30
Item identification: done
5 x 123 # 20.0 SAR === 100.0
3 x 456 # 30.0 SAR === 90.0
=========================================
No. of items purchased: 8
Total price is: 190.0 SAR
Note: You need to save all the information (e.g., itemid, qtysold) in the while loop to list1 if you want to print them out later. Otherwise, qtysold and totalprices will always keep the last value when exiting the while loop. This explains the reason for the problem you are facing.

Existing dictionaries in list all being updated to new dictionary entry?

I am trying to create a simple program that contains a list of dictionaries. The grocery_history is the list of dictionaries, and the dictionary is grocery_item. Here is the code:
'''
The task is broken down into three sections.
Section 1 - User Input
Section 2 - loop through the grocery list
Section 3 - provide output to the console
'''
grocery_item = {}
grocery_history = []
stop = 'go'
while stop != 'q':
item_name = input("Item name:\n")
quantity = int(input("Quantity purchased:\n"))
cost = float(input("Price per item:\n"))
grocery_item['name'] = item_name
grocery_item['number'] = quantity
grocery_item['price'] = cost
grocery_history.append(grocery_item)
stop = input("Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n")
print(grocery_history)
grand_total = 0
for grocery_item in range(0, len(grocery_history)):
item_total = grocery_history[grocery_item]['number'] * grocery_history[grocery_item]['price']
grand_total += item_total
print(str(grocery_history[grocery_item]['number']) + " " + grocery_history[grocery_item]['name'] + " # $%.2f" % grocery_history[grocery_item]['price'] + " ea \t$%.2f" % item_total)
item_total = 0.0
print("Grand total: $%.2f" % grand_total)
print(grocery_history)
In case you're wondering, the prompt for this assignment told me to use the variable grocery_item in my for loop. I normally would have chosen a different name since it becomes confusing. I also added a couple of print statements to print out the contents of grocery_history to see what's going wrong, and I confirmed it's when the dictionary is being added to the grocery_history list, that's when it for some reason updates existing dictionary items to match the new one being added. I can't figure out what I'm doing wrong. Any help would be greatly appreciated!
You need to define a new dictionary object each time in loop or else you end up using the same dictionary object so in effect replaces the already added one.
while stop != 'q':
grocery_item = {}
# ...
sample code should work
grocery_history = []
stop = 'go'
while stop != 'q':
item_name = input("Item name:\n")
quantity = int(input("Quantity purchased:\n"))
cost = float(input("Price per item:\n"))
grocery_item = {}
grocery_item['name'] = item_name
grocery_item['number'] = quantity
grocery_item['price'] = cost
grocery_history.append(grocery_item)
stop = input("Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n")
print(grocery_history)
grand_total = 0
for grocery_item in range(0, len(grocery_history)):
item_total = grocery_history[grocery_item]['number'] * grocery_history[grocery_item]['price']
grand_total += item_total
print(str(grocery_history[grocery_item]['number']) + " " + grocery_history[grocery_item]['name'] + " # $%.2f" % grocery_history[grocery_item]['price'] + " ea \t$%.2f" % item_total)
item_total = 0.0
print("Grand total: $%.2f" % grand_total)
print(grocery_history)
the problem happened because you are repeating using same dict, although it adds to list each time, what you actually doing is keep updating the same reference so all content in the list becomes the same value
move dict inside solve the problem
This is because your loop does not create a new grocery_item object each time; it just updates the same grocery_item object over and over.
grocery_history ends up containing multiple references to this single object, in its latest state.
To fix this issue, move the line grocery_item = {} to be the first item underneath the while stop != 'q': loop. This will create a new object each time through the loop.
You can use map and sum to get grand_total
grocery_history = []
stop = 'go'
while stop != 'q':
grocery_item = {}
grocery_item['name'] = input("Item name:\n")
grocery_item['number'] = int(input("Quantity purchased:\n"))
grocery_item['price'] = float(input("Price per item:\n"))
grocery_history.append(grocery_item)
stop = input("Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n")
grand_total = sum(map(lambda item: item['number'] * item['price'], grocery_history))
print("Grand total: $%.2f" % grand_total)
print(grocery_history)
Input:
Item name:
item
Quantity purchased:
2
Price per item:
1.2
Would you like to enter another item?
Type 'c' for continue or 'q' to quit:
q
Output:
Grand total: $2.40
[{'name': 'item', 'number': 2, 'price': 1.2}]

Difficulties with funtions and syntax in python

I have written a program for a homework assignment, that should function as a mock grocery list that will calculate how much the items should cost as well.
grocery_item = {}
grocery_history=[{'name': 'milk', 'number': int(1), 'price': float(2.99)},
{'name': 'eggs', 'number': 2, 'price': 3.99},
{'name': 'onions', 'number': 4, 'price': 0.79}]
stop = 'go'
item_name = "Item name"
quantity = "Quantity purchased"
cost = "Price per item"
print ("Item name:")
print ("Quantity purchased:")
print ("Price per item:")
cont = 'c'
while cont != 'q':
item_name = "milk"
quantity = "Quantity purchased"
quantity = 2
cost = "Price per item"
cost = 2.99
grocery_history.append(item_name)
grocery_history.append(quantity)
grocery_history.append(cost)
grocery_item['name'] = item_name
grocery_item['number'] = quantity
grocery_item['price'] = cost
print("Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n")
cont = 'c'
item_name = "eggs"
quantity = "Quantity purchased"
quantity = 1
cost = "Price per item"
cost = 3.99
grocery_history.append(item_name)
grocery_history.append(quantity)
grocery_history.append(cost)
grocery_item['name'] = item_name
grocery_item['number'] = quantity
grocery_item['price'] = cost
"Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n"
cont = 'c'
item_name = "onions"
quantity = "Quantity purchased"
quantity = 4
cost = "Price per item"
cost = 0.79
"Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n"
cont = 'q'
grand_total = []
number = grocery_item['number']
price = grocery_item['price']
for grocery_history in grocery_item:
item_total = number*price
grand_total.append(item_total)
print (grocery_item['number'] + ['name'] + "#" + ['price'] + "ea" + ['item_total'])
item_total = 0
print (grand_total)
This is the error I get:
print (grocery_item['number'] + ['name'] + "#" + ['price'] + "ea" + ['item_total'])
TypeError: unsupported operand type(s) for +: 'int' and 'list'
There are multiple problems with this code.
I am supposed to use the %.2f to get the price in dollar form, but I have no idea how, and the things I've tried haven't worked.
There are syntax errors in my print(grocery_item) statement.
The code doesn't run through the list grocery_history, and just repeats with the same input over and over.
To get a formatted print with the fields from the dict you can use .format() like:
print('{number} {name} # {price:.2f} ea'.format(**grocery_item))
You have an error because you are adding string to floats. Python does not know how to do that.
As #Stephen Rauch showed, you can do it in one line with a very pythonic structure. If you want you can use the syntax
'%s\t%s\t...'%(my_variable1, my_variable2)
Which works great as well.
I assume you wanted to add items to already existing grocery_history and then calculate the grand total of all your groceries (using Stephen Rauch's printing answer).
grocery_history=[{'name': 'milk', 'number': int(1), 'price': float(2.99)},
{'name': 'eggs', 'number': 2, 'price': 3.99},
{'name': 'onions', 'number': 4, 'price': 0.79}]
cont = 'c'
grand_total = 0
while cont != 'q':
num = input("How many bottles of milk do you want to buy? ")
grocery_history[0]['number'] += num
num = input("How many eggs do you want to buy? ")
grocery_history[1]['number'] += num
num = input("How many onions do you want to buy? ")
grocery_history[2]['number'] += num
cont = raw_input("Enter c to continue or q to quit: ")
while cont not in ['c', 'q']:
cont = raw_input("Wrong choice, enter your choice again: ")
for grocery_item in grocery_history:
item_total = grocery_item['number'] * grocery_item['price']
grand_total += item_total
print('${:.2f} for {number} {name} # {price:.2f} ea'.format(item_total, **grocery_item))
print ("Grand total is ${:.2f}".format(grand_total))
Some of what went wrong:
You weren't actually asking the user to enter c or q, so you just went once over the list and exited in the end because of cont = 'q'.
You were constantly overwriting your variables, for example:
quantity = "Quantity purchased"
quantity = 2
First line assigns string and the second - integer. You can operate directly on dict values, provided you know how to access them.
This part:
number = grocery_item['number']
price = grocery_item['price']
assigned the last actually updated grocery_item (eggs) and you did all your calculations in for loop with these two values.
Here:
grocery_history.append(item_name)
grocery_history.append(quantity)
grocery_history.append(cost)
you were appending strings and numbers to a list of dictionaries.

convert to arbitrary number of inputs while being case insensitive

So I am given a menu and the food rating, i have to create a data structure, then make a getInfo function, and findCheapest function.
getInfo(item) takes 1 item and prints outs its price and ratings.
findCheapest(item1, item2) takes in 2 items, checks if items are in menu and gives the cheapest. I have written this far here is where i am struggling.
how to make all the input case insensitive for both functions, but still return correctly formatted words. Eg:
getInfo("tEa") should return:
Tea- price: 7. Rating: 4
I get you could do string compare and convert it to lowercase but you can't do that in a set cause then it will print wrong and how do you do it and still compare each value properly.
The second part i am struggling at is for the findCheapest function how make it so that it can take an arbitrary number of values and still print the cheapest without changing the data structure too much.
So i implemented a formatText(item) function that converts to the correct format.
Here is the code:
menu= {"Tea", "Coffee", "Cookie", "Chips"}
price={
"Tea": 7,
"Coffee": 5,
"Cookie": 2,
"Chips": 3
}
rating= {
"Tea": 4,
"Coffee": 4.5,
"Cookie":5,
"Chips": 2
}
def getInfo(item):
if item in menu:
print item + "- price: %s." % price[item] + " Ratings %s" %rating[item]
else:
print "This item was not found: " + item
def findCheapest (item1,item2):
if item1 in menue and item2 in menue:
if (price[item1] < price[item2]):
print item2+ " is the cheapest"
elif (price[item1] > price[item2]):
print item1 +" is the cheapest"
else:
print "An item was not found."
getInfo("tEa")
getInfo("coFfeE")
findCheapest("tEa", "coFfeE")
Use either #Aswin Murugesh solution to make everything uppercase or lowercase
Or
wrt your current setup, you can use capitalize()
Or
construct following string (1st char upper using upper()+rest char lower using lower()) to make the 1st char capital.
getInfo("tEa".capitalize())
getInfo("coFfeE".capitalize())
findCheapest("tEa".capitalize(), "coFfeE".capitalize())
Apply it to the input values or as the 1st step in your method
my_menu= ["Tea", "Coffee", "Cookie", "Chips"]
price={
"Tea": 7,
"Coffee": 5,
"Cookie": 2,
"Chips": 3
}
rating= {
"Tea": 4,
"Coffee": 4.5,
"Cookie":5,
"Chips": 2
}
def isItemInMenue(item="", menu=[]):
for x in menu:
if x.lower() == item.lower():
return x
return ""
def getInfo(item):
item_ = isItemInMenue(item, my_menu)
if item_:
print item_ + " - price: %s." % price[item_], "Ratings %s" % rating[item_]
else:
print "This item was not found: " + item_
def findCheapest (item1, item2):
item1_ = isItemInMenue(item1, my_menu)
item2_ = isItemInMenue(item2, my_menu)
if item1_ and item2_:
if (price[item1_] price[item2_]):
print item1_ + " is the cheapest"
else:
print "An item was not found."
getInfo("tEa")
getInfo("coFfeE")
findCheapest("tEa", "coFfeE")
Irrespective of the user input, use capitalize function. and get the price and rating. Capitalize returns with just the first letter of each word in capital, all others lower
list_of_items = [x.capitalize() for x in raw_input.split()]
find_cheapest(list_of_items)
def find_cheapest(list_of_items):
cheapest_price = 12345
cheapest_item = ""
for item in list_of_items:
# Get the price of the item and check with the least price
item_price = price.get(item,None)
if item_price and item_price < cheapest_price:
cheapest_price = item_price
cheapest_item = item
if cheapest_item:
return cheapest_item + "is the cheapest"
else:
return "No Items were found"
Code looks pretty good so far. One easy fix is to use the upper and lower functions to properly format your items before doing the logic.
def format_item(someItem):
return " ".join(x[0].upper() + x[1:].lower() for x in someItem.split())
print format_item("tEA") #Tea
Then you can just call format item before the rest of your logic. For example.
def findCheapest (item1,item2):
item1 = format_item(item1)
item2 = format_item(item2)
...

Input into tuple that goes into list

I'm trying to convert input from the user into a tuple that goes into a list. I'm using the split method, but it seems to take the input and creates a tuple inside the list, but also creates another itself in the list also...I hope that made sense...anyways, I ran it in the visualizer, and saw that it was going to both each with an index of 0 and 1, so I figured I have one small detail outta whack.
In short:
Enter an employee's name. (Last, First)
and that last name, first name gets converted into the tuple and sent to the
list.
I figured a list of employees with two values would be better as a tuple in a list, correct? Let me know if I'm just off and it's better as a plain list.
Anyways, here's the code:
empList = []
empName = input("Please enter employee name. (Last name, First name):\n")
nameSplit = tuple(empName.split(","))
empList += nameSplit
salary = float(input("Please enter salary for " +str(empList[0:]) + ":\n" ))
grossSalary = salary
if (grossSalary > 100000):
fedTax = (grossSalary * .2)
else:
fedTax = (grossSalary * .15)
stateTax = (grossSalary * .05)
netSalary = (grossSalary - (fedTax + stateTax))
print('''\nGross Salary: {0:>5.2f} \n
Federal Tax: {minus:>2}{1:>6.2f} \n
State Tax: {minus:>4}{2:>4.2f} \n
Net Salary: {3:>10.2f}'''.format(grossSalary, fedTax, stateTax, netSalary,
minus = "-"))
empList = []
empName = input("Please enter employee name. (Last name, First name):\n")
nameSplit = tuple(empName.split(","))
empList += nameSplit
The last line empList += nameSplit adds/concatentates each item from the tuple to the list. It does not add the tuple itself:
>>> l = [1, 2, 3]
>>> l += (4, 5)
>>> l
[1, 2, 3, 4, 5]
You should use list.append() instead:
empList.append(nameSplit)
Now it will append the tuple:
>>> empList = []
>>> empName = 'Lastname, Firstname'
>>> nameSplit = tuple(empName.split(","))
>>> empList.append(nameSplit)
>>> empList
[('Lastname', ' Firstname')]
>>> empName = 'Else, Someone'
>>> nameSplit = tuple(empName.split(","))
>>> empList.append(nameSplit)
>>> empList
[('Lastname', ' Firstname'), ('Else', ' Someone')]
One other thing. Whitespace is left in the strings that you split with ,. You should strip each string prior to adding it to the list, and you don't really need the intermediate variable:
empList.append(tuple(s.strip() for s in empName.split(",")))
Here is an example session with your actual code (python3)
Please enter employee name. (Last name, First name):
Payne,Max
Please enter salary for ['Payne', 'Max']:
100000
Gross Salary: 100000.00
Federal Tax: -15000.00
State Tax: -5000.00
Net Salary: 80000.00
Therefore, the only modification I would do is
salary = float(input("Please enter salary for " + empList[1] + " " + empList[0] + ":\n" ))
Unless from your comment input = (Payne, Max), are you expecting the user to enter the parentheses? This will not produce a tuple in a list. Anyway, in your program empList can be a tuple or a list, it doesn't matter.

Categories