So when running the code, it works as intended except for the fact that when looped a second time, the if statement doesn't work. May I ask for some help please.
cart=[]
price_total=[]
stuff={"potato": 50, "apple": 35, "orange": 40, "banana": 25, "popcorn": 120, "water": 20, "cola":
40}
y=1
def main():
print("Thanks for using checkout")
print("(1) make a transaction")
customer_input=int(input("What would you like to do:"))
main()
if customer_input==1:
print("potato=50")
print("apple=35")
print("orange=40")
print("banana=25")
print("popcorn=120")
print("water=20")
print("cola=40")
global order_input
order_input=input("What would you like to order:")
cart.append(order_input)
lol()
There are a couple of ways to implement what you want to do.
Using Functions, which is the approach you seem to be trying to implement
Using classes, which would be a more Object oriented approach
The Functional Approach
In the functional approach all operations are managed by individual functions, and many of the essential variables are passed to these functions. Here are the implemented functions:
# The Functional Approach
def getInput(prompt, respType= None):
"""Simple Function To Gather input and verify it's type,
Returns the User input converted to the requested type
if it is consistent with the type specifier"""
while True:
resp = input(prompt)
if respType == str or respType == None:
break
else:
try:
resp = respType(resp)
break
except ValueError:
print('Invalid input, please try again')
return resp
def list_stock(inv):
"""Returns a printable list of all items currently in inventory """
kylist = sorted(list(inv.keys()))
s = "The Items currently in stock include:\n"
for i in range(len(kylist)):
s += f'{i+1:4}\t{kylist[i]:10} {inv[kylist[i]]} each\n'
return s
def add_to_cart(item, qty, cart):
"""Adds Item to cart and returns updated cart"""
cdi = cart.pop(item, 0)
cdi += qty
cart[item] = cdi
return cart
def contents(cart, inv):
"""Returns printable list of cart contents"""
ckys = cart.keys()
s = "The Items currently in your cart include:\n"
s += 'Item\tQty\tCost\n'
for ky in ckys:
qty = cart[ky]
cost= qty* inv[ky]
s += f'{ky}\t{qty}\t{cost}\n'
return s
def total_bill(cart, inv):
"""Returns the Total Cost of items in Cart"""
total = 0
for itm, qty in cart.items():
total += qty*inv[itm]
return total
def load_cart(cart, inv):
stock = sorted(list(inv.keys()))
print(list_stock(inv))
while True:
itm = stock[getInput('Please enter an item number to add to your cart', int)-1]
qty = getInput(f'please enter the number of {itm} you want added to your cart', int)
add_to_cart(itm, qty, cart)
if getInput("Do you have more to add? (y/n)").lower() != 'y':
break
The main function which then controls process flow and manages calling necessary functions includes:
# The Main Method for Functional Appraoch
stuff={"potato": 50, "apple": 35, "orange": 40, "banana": 25, "popcorn": 120, "water": 20, "cola":
40}
cart = dict()
print("Thanks for using checkout")
while True:
if getInput('Would you like to load a cart? (Y/N)').lower()[0] == 'y':
load_cart(cart, stuff)
print(contents(cart, stuff))
print (f'Your total bill = {total_bill(cart, stuff)}' )
else:
print('Have a nice day!')
break
A typical execution of this main routine would look like:
Thanks for using checkout
Would you like to load a cart? (Y/N) y
The Items currently in stock include:
1 apple 35 each
2 banana 25 each
3 cola 40 each
4 orange 40 each
5 popcorn 120 each
6 potato 50 each
7 water 20 each
Please enter an item number to add to your cart 3
please enter the number of cola you want added to your cart 2
Do you have more to add? (y/n) n
The Items currently in your cart include:
Item Qty Cost
cola 2 80
Your total bill = 80
Would you like to load a cart? (Y/N) n
Have a nice day!
A more Object Oriented Approach
In the OO approach, many of the basic operations are implemented as methods within a Cart Class. Using the Cart Class groups methods together and keeps them associated with the cart. The following gives an implementation using the Cart Class.
class Cart:
def __init__(self, inventory):
self._cart = dict()
self._inv = inventory
def in_inventory(self, item):
return item in self._inv.keys()
#property
def stock(self):
return sorted(list(self._inv.keys()))
def price(self, itm):
return self._inv[itm]
#property
def inventory(self):
kylist = self.stock
s = "The Items currently in stock include:\n"
for i in range(len(kylist)):
s += f'{i+1:4}\t{kylist[i]:10} {self._inv[kylist[i]]} each\n'
return s
def add_to_cart(self, item, qty= 1):
cdi = self._cart.pop(item, 0)
cdi += qty
self._cart[item] = cdi
#property
def contents(self):
ckys = self._cart.keys()
s = "The Items currently in your cart include:\n"
s += 'Item\tQty\tCost\n'
for ky in ckys:
qty = self._cart[ky]
cost= qty* self._inv[ky]
s += f'{ky}\t{qty}\t{cost}\n'
return s
#property
def bill(self):
total = 0
for itm, qty in self._cart.items():
total += qty*self.price(itm)
return total
Using the Cart Class for most of the needed methods, leaves only 1 separate function
def load_cart(cart):
stock = cart.stock
print(cart.inventory)
while True:
itm = stock[getInput('Please enter an item number to add to your cart', int)-1]
qty = getInput(f'please enter the number of {itm} you want added to your cart', int)
cart.add_to_cart(itm, qty)
if getInput("Do you have more to add? (y/n)").lower() != 'y':
break
The main function which manages the entire application would then look like:
# The main routine to execute the Object Oriented Appraoch
stuff={"potato": 50, "apple": 35, "orange": 40, "banana": 25, "popcorn": 120, "water": 20, "cola":
40}
cart = Cart(stuff)
print("Thanks for using checkout")
while True:
if getInput('Would you like to load a cart? (Y/N)').lower()[0] == 'y':
load_cart(cart)
print(cart.contents)
print (f'Your total bill = {cart.bill}' )
else:
print('Have a nice day!')
break
Executing this Main method would produce results like:
Thanks for using checkout
Would you like to load a cart? (Y/N) y
The Items currently in stock include:
1 apple 35 each
2 banana 25 each
3 cola 40 each
4 orange 40 each
5 popcorn 120 each
6 potato 50 each
7 water 20 each
Please enter an item number to add to your cart 4
please enter the number of orange you want added to your cart 3
Do you have more to add? (y/n) n
The Items currently in your cart include:
Item Qty Cost
orange 3 120
Your total bill = 120
Would you like to load a cart? (Y/N) n
Have a nice day!
Put all of your code under def main() and use main() just call the the function. You can then use while loops to keep asking for user input and provide a way for user to exit by entering -1 or something similar:
cart=[]
price_total=0
stuff={"potato": 50, "apple": 35, "orange": 40, "banana": 25, "popcorn": 120, "water": 20, "cola":40}
y=1
def main():
global price_total
print("Thanks for using checkout")
print("(1) make a transaction. (-1) to exit.")
customer_input = int(input("What would you like to do: "))
while customer_input == 1:
print("potato=50")
print("apple=35")
print("orange=40")
print("banana=25")
print("popcorn=120")
print("water=20")
print("cola=40")
global order_input
order_input = input("What would you like to order? (-1) to finish: ")
if order_input == "-1":
print(f'You bought {cart} for total price of {price_total}.')
break
cart.append(order_input)
price_total += stuff[order_input]
main()
Related
I am a beginner to using python and I was trying to create a program in pyscripter to be a basic ordering menu for a food shop. I have gotten most of what I want working but I have a problem with the program not adding the total_price at the end. It only adds the price of the last item I ordered and the other items ordered will have a value of 0.
import sys
print("Welcome to Terry's Restaurant!")
num_items=int(input("Please enter 1-4 items to be ordered, type 0 to cancel order: "))
print("""Please choose items from :
1. Macaroni Pizza
2. Garlic Bread
3. Coca Cola
4. Onion Rings
5. Fries
0. To exit shop/cancel order""")
#for loop to ask for input depending on the number the user types for num_items
#each order will ask for quantity and prints a total price
for num_items in range (num_items):
order=input("\nPlease enter your desired item using 1-5: ")
if order == "1":
item1 = "Macaroni Pizza"
price1 = 15
quantity1 =int(input("How many would you like? "))
total1 =quantity1 * price1
print (quantity1, item1 ,"$",total1)
else:
total1=0
if order == "2":
item2= "Garlic Bread"
price2 = 6
quantity2 =int(input("How many would you like? "))
total2 = quantity2 * price2
print (quantity2, item2,"$",total2)
else:
total2=0
if order == "3":
item3 = "Coca Cola"
price3 = 4
quantity3 = int(input("How many would you like? "))
total3 = quantity3 * price3
print (quantity3, item3,"$",total3)
else:
total3=0
if order == "4":
item4 = "Onion Rings"
price4 = 4
quantity4 = int(input("How many would you like? "))
total4 = quantity4 * price4
print (quantity4, item4,"$",total4)
else:
total4=0
if order == "5":
item5 = "Fries"
price5 = 4
quantity5 = int(input("How many would you like? "))
total5 = quantity5 * price5
print (quantity5, item5,"$",total5)
else:
total5=0
if order == "0":
sys.exit()
print("Cancelling Order. Thank you come again")
else:
print("Please enter a valid item")
#total_price to add the total prices for each item ordered
total_price = total1, total2, total3, total4, total5
print("\nYour order total is $", total_price)
I'm trying to create a Parking Lot in OOP. i want to check if any key is already in my dictionary.
for example i dont want the same "plate number" in my dict.
I'm using the command:
if plate in p1.carsAndEnterTime:
print("This plate number already exists in the system")
plate = input("Please enter the plate number:\n")
But it didnt found any key.
This is my full code:
class Cars:
def __init__(self, phone, car_type, plate):
self.__phone = phone
self.__car_type = car_type
self.__plate = plate
def __repr__(self):
return f"{self.__plate}, {self.__phone}, {self.__car_type}"
def __str__(self):
return f"{self.__plate}, {self.__phone}, {self.__car_type}"
class ParkingLot:
def __init__(self, name, capacity=1):
''' return a ParkingLot object with name "name" '''
self.name = name
self.capacity = capacity
self.earnings = 0
self.rate = 15
self.carsAndEnterTime = {}
def SetCapacity(self, newCap):
''' change the capacity from the default 1 '''
if newCap < 1:
raise RuntimeError("Error: parking lot size cannot be less than 1")
self.capacity = newCap
def GetCapacity(self):
''' return parking lot capacity '''
return self.capacity
def GetEarnings(self):
''' return how much much parking has made '''
return self.earnings
def VehicleEnters(self, vehicle):
''' vehicle enters parking lot'''
# put car and its enter time in a dictionary
self.carsAndEnterTime[vehicle] = datetime.datetime.now()
if self.capacity == 0:
raise RuntimeError("Error: Parking lot full!")
self.capacity -= 1
def SetSecondlyRate(self, rate=20):
self.rate = rate
def VehicleLeaves(self, vehicle):
''' vehicle leaves parking lot. when it leaves, charges money '''
secondsDiff = datetime.datetime.now() - self.carsAndEnterTime[vehicle]
hour_roundup = math.ceil(secondsDiff.seconds / 3600)
self.earnings += self.rate * hour_roundup
# after earned money, delete vehicle from dictionary
del self.carsAndEnterTime[vehicle]
self.capacity += 1
When i do the following:
>>> p1 = ParkingLot(p1,2)
>>> plate = 12345
>>> car_type = "Public"
>>> phone = "05555555"
>>> c = c1 = Cars(plate, car_type, phone)
when i try to check if the palte inside the dict
but its ignores, Although palte exists dict.
if plate in p1.carsAndEnterTime:
print("This plate number already exists in the system")
plate = input("Please enter the plate number:\n")
for example i print my dict:
and you can see the 12345 is found twise in my dict.
>>>print(p1.carsAndEnterTime)
{12345, 55555, p: datetime.datetime(2020, 5, 10, 23, 0, 36, 557859), 12345, 5555, p: datetime.datetime(2020, 5, 10, 23, 0, 44, 568150)}
What am I doing wrong and how do I fix it?
You do not put the cars into your parking lot by their Plate - you put full car-instances into your dictionary. If you put in 2 different car instances with the same values the id(car1) and id(car2) are different because 2 different objects. Hence no equality.
A crude way around that would be to check:
def CarAlreadyParked(self, vehicle):
"""Returns true if the exact car is already parked."""
return any(str(c) == str(vehicle) for c in self.carsAndEnterTime)
before letting the car in - could be a forged identity car. All in all it would be better to redesign and maybe store cars by there plate in a dict:
dict [ PlateNr] = (VehicleInstance, CheckinTime)
so you can quickly find them by plateNr and have the vehicle-object in a tuple on the value
I have a homework that tells this:
A hawker has to decide what products to take on his next trip. Unfortunately, you have a weight limit that you can carry, and having this in mind, you have to choose the best combination of products with at most this weight that will allow you to have maximum revenue.
You will receive the weight limit that the seller can carry, followed by a list of products from which he can choose (assume you have an unlimited stock of each product at your disposal). For each product will be listed its name, its value, and its weight. You should print the maximum revenue you can get if you sell all the products you choose to carry, followed by the list of products you should take to get that revenue (including replicates, if appropriate), sorted alphabetically. If there are 2 products with the same profitability / weight should give priority to the products that appear first in the entry list.
I am reading the input from a file.
Input:
14
bible 20 2
microwave 150 10
television 200 15
toaster 40 3
Output: 190 bible bible microwave
I have made this code to reach the maximum value the hawker can carry with him:
import sys
def knapsack(list_values,list_weight,limit_weight,n):
matrix = [[0 for x in range(limit_weight+1)] for y in range (n+1)]
res = []
for i in range(n+1):
for j in range(limit_weight+1):
if i == 0 or j == 0:
matrix[i][j] = 0
elif list_weight[i-1]<= j:
matrix[i][j] = max(list_values[i-1] + matrix[i-1][j-list_weight[i-1]], matrix[i-1][j])
else:
matrix[i][j] = matrix[i-1][j]
return matrix[n][limit_weight], matrix
def main():
txt = sys.stdin.readlines()
limit_weight = int(txt[0])
list_names = []
list_values = []
list_weight = []
picked = []
for lines in txt[1:]:
lines = lines.split()
list_weight.append(int(lines[2]))
list_values.append(int(lines[1]))
list_names.append(lines[0])
result, matrix = knapsack(list_values,list_weight, limit_weight, len(list_values))
print(result)
main()
I can not figure out which items are chosen.
Can you help me?
ok so this is my program so far to operate as an ordering system of a cafe with multiple items. My goal is to calculate the price of an order, store that order to keep count of which coffee was ordered and how many of that coffee was ordered. Right now I am stuck on calculating the order total for an order. The main problem im stuck on is getting the coffee price of a coffee based on what the user wants, say if i want x coffee, i need to get the price of that coffee. I've stored instances of coffee in an array and right now I am not sure of how to get the price of a coffee to be used in the calculation of the total price
class Coffee(object):
def __init__ (self, coffee_type, price):
self.coffee_type = coffee_type
self.price = price
class Order(object):
def __init__(self, coffee_type, coffee_amount):
self.coffee_type = coffee_type
self.coffee_amount = coffee_amount
if name =="main":
coffee_available=[Coffee("1 : Flat White", 3.50),
Coffee("2 : Long Black", 3.50),
Coffee("3 : Cappuccino", 4.00),
Coffee("4 : Espresso", 3.25),
Coffee("5 : Latte", 3.50)]
ordering = 'Y'
total_cost = 0
while ordering == 'Y':
print("Coffee Type\t\tPrice")
print("-----------\t\t-----")
for coffee in coffee_available:
print("{}\t- - -\t$ {}".format(coffee.coffee_type,coffee.price))
print()
order_coffee = int(input("What is the number of the coffee you want? "))
order_amount = input("How many would you like to order? ")
new_order = None
if order_coffee >= 1 and order_coffee <=5:
coffee_choice = coffee_available[coffee.price]
new_order = Order(coffee_choice, order_amount)
total_cost = new_order.coffee_type * order_amount
else:
print ("Please enter a valid number")
dine_in = input('You like to dine in? (Y/N)')
dine_in = dine_in.upper()
if dine_in == 'Y' or 'YES':
total_cost = total_cost + (total_cost * 0.1)
print (total_cost)
Ordering = 'N'
elif dine_in == 'N' or 'No':
total_cost = total_cost
else:
print("Please enter a valid input")
continue
It's better to split the id of the coffee from the name:
class Coffee(object):
def __init__ (self, coffee_id, coffee_type, price):
self.coffee_id = coffee_id
self.coffee_type = coffee_type
self.price = price
Then when you create object use:
Coffee(1, "Flat White", 3.5)
And when you want the price use:
def get_price(coffee_available, coffee_id):
for coffee in coffee_available:
if coffee.coffee_id == coffee_id:
return coffee.price
return None
I'm trying to find the minimum sum of non consecutive elements in list,
where every time I can jump one cell or two cells.
The first cell is not counted in sum.
The implementation has to include recursion and memoization. I tried to implement such method, but unfortunately, it doesn't actually use memoization and it doesn't work for some examples.
My code looks like this:
def optimal_cruise_seasick(toilet_prices):
prices_dict = {}
return optimal_cruise_seasick_mem(toilet_prices, 0, len(toilet_prices), prices_dict)
def optimal_cruise_seasick_mem(prices_lst, start, end, dic):
if (start,end) in dic:
return dic[(start,end)]
if(start + 1 == end or start + 2 == end):
return prices_lst[end-1]
min_cost = prices_lst[end-1]
i = start + 1
while(i < end - 1):
one = optimal_cruise_seasick_mem(prices_lst, i, i+1, dic)
two = optimal_cruise_seasick_mem(prices_lst, i, i+2, dic)
if (one <= two):
min_cost += one
i += 1
else:
min_cost += two
i += 2
dic[(start,end)] = min_cost
return min_cost
I tried to run it for toilet_prices = [20,40,60,80,100,70,50,30,10,30].
It returns 320 instead of 250 (40,80,70,30,30). How should I fix my code so it will work as required?
Thanks!
Your implementation is, frankly, confusing. I have written an alternate implementation that works correctly (per your clarifications in the comments), though I don't know if it's memoizing in the way you want it to.
What we do is start at the first "actual" thing in the prices list (stripping off the first element; in your example, 20), and then successively see whether chopping off the left one or left two elements gives us a lower sum.
def f(prices, memo):
if prices not in memo:
if len(prices) == 1:
memo[prices] = prices[0]
elif len(prices) == 2:
# We must include the final cell in the list, but can choose to get there
# either by two 1-moves or one 2-move. Obviously the one 2-move is going
# to be non-pessimal if all prices are non-negative, but we'll put the min
# call in here for elucidation/explicitness anyway.
memo[prices] = min(prices[1], prices[0] + prices[1])
else:
memo[prices] = prices[0] + min(f(prices[1:], memo), f(prices[2:], memo))
return memo[prices]
def optimal_cruise_seasick(prices):
return f(prices[1:], dict())
Adding some print statements to indicate when we read from memo:
>>> optimal_cruise_seasick((20,40,60,80,100,70,50,30,10,30))
Read from memo: (10, 30) -> 30
Read from memo: (30, 10, 30) -> 60
Read from memo: (50, 30, 10, 30) -> 80
Read from memo: (70, 50, 30, 10, 30) -> 130
Read from memo: (100, 70, 50, 30, 10, 30) -> 180
Read from memo: (80, 100, 70, 50, 30, 10, 30) -> 210
250
As you can see, it's memoizing over suffixes of the prices list.
I should add that you can achieve the same effect in a cleaner way using functools.lru_cache. The f2 here is equivalent to the f above (if your price lists are short enough that everything fits into the cache), except that you don't pass in a dict() for memo, obviously.
from functools import lru_cache
#lru_cache()
def f2(prices):
if len(prices) == 1:
return prices[0]
elif len(prices) == 2:
return min(prices[1], prices[0] + prices[1])
else:
return prices[0] + min(f2(prices[1:]), f2(prices[2:]))