Python keeping count of totals based on user input - python

I have a function in my item ordering system where the goal is to keep totals of how many items were ordered and print each item and the amount they were ordered
class Totals(object):
def __init__(self, total):
self.total = total
def total(order_amount, coffee_id):
count = 0
print("Coffee Type\t\tAmount of Times ordered")
print("-----------\t\t-----------------------")
for coffee in coffee_available:
if coffee.coffee_id == coffee_id:
count = order_amount
coffee_id = order_coffee
print("{}\t- - -\t {} ".format(coffee.coffee_type, count))
With this I can only print one item and it does show how many of that item is ordered but again it only does this to one item
The function is based on user input and the items are
coffee_available=[Coffee(1, "1: Flat White", 3.50),
Coffee(2, "2: Long Black", 3.50),
Coffee(3, "3: Cappuccino", 4.00),
Coffee(4, "4: Espresso", 3.25),
Coffee(5, "5: Latte", 3.50)]
how do I change the function so that it prints all items and keeps track of the amount of items ordered each time it is called so that after my code is looped through multiple times it still displays each item and the amount of times it was ordered
Ok now I have a method that prints each of the types of coffee but prints the amount of coffee ordered for 1 item to all of the items and it does not retain the amount of coffee ordered for each item as is needed
class Order(object):
def __init__(self):
self.total = {}
def order(self, order_amount, coffee_id):
if coffee_id not in self.total.keys():
self.total[coffee_id] = 0
self.total[coffee_id] += order_amount
def print_order(self, coffee_id):
print(" ")
print("Coffee Type\t\tAmount of Times ordered")
print("-----------\t\t-----------------------")
for coffee in coffee_available:
print("{}\t- - -\t {} ".format(coffee.coffee_type, self.total[coffee_id]))
and this is how I call it
new_order = Order()
new_order.order(order_amount, coffee_available[order_coffee - 1])
new_order.print_order(coffee_available[order_coffee - 1])
any suggestions would be great

You should save a dictionary that map from the coffee id to it amount of orders and update it on each order.
class Totals(object):
def __init__(self):
self.total = {}
def order(self, order_amount, coffee_id):
if coffee_id not in self.total.keys():
self.total[coffee_id] = 0
self.total[coffee_id] += order_amount
For the printing you should add a print function that print self.total as you wish.

This is personally how I believe you should manage the items ordered. This example has a dictionary mapping a Coffee object to the number of times it was ordered.
class Order(object):
ID = 0
def __init__(self):
self._orders = {}
self._order_id = Order.ID
Order.ID += 1
def add_item(self, coffee):
# Gets the current quantity for the coffee
# If no previous order qty defaults to 1
qty = self._orders.get(coffee, 1)
# Add / update dict with coffee object and qty
self._orders[coffee] = qty
def display_order(self):
print("Coffee Type\t\tAmount of Times ordered")
print("-----------\t\t-----------------------")
# For each coffee object ordered | sorted by coffee id
for coffee in sorted(self._orders, key = lambda item: item.coffee_id):
print("{:<10}\t- - -\t {} ".format(coffee.coffee_type,
coffee.price * self._orders[coffee]))

Related

I got problem a about to call func from class

I got this code from a book name 'Data Structures and Algorithms in Python from Michael T. Goodrich ' chapter 5.5.1 Storing High Scores for a Game.
Can some one can explain to me what this self._board[-1].get_score( ) means ??
I try to print it to see what happens but I got:
print(self._board[-1].get_score( ))
AttributeError: 'NoneType' object has no attribute 'get_score'
class GameEntry:
def __init__(self, name, score):
self._name = name
self._score = score
def get_name(self):
return self._name
def get_score(self):
return self._score
def __str__(self):
return ('({0}, {1})'.format(self._name, self._score)) # e.g., (Bob, 98)
class Scoreboard():
def __init__(self, capacity=10):
self._board = [None]*capacity # reserve space for future scores
self._n=0 # number of actual entries
def __getitem__(self, k):
return self._board[k]
def add(self, entry):
score = entry.get_score()
print(score)
if self._n < len(self._board) or score > self._board[-1].get_score(): # what is it " self._board[-1].get_score()"
if self._n < len(self._board): # no score drops from list
self._n += 1 # so overall number increases
j = self._n - 1
while j > 0 and self._board[j-1].get_score( ) < score:
self._board[j] = self._board[j-1] # shift entry from j-1 to j
j -= 1 # and decrement j
self._board[j] = entry
def __str__(self):
return '\n' .join(str(self._board[j]) for j in range(self._n))
a_ = Scoreboard()
a = ('a','b','c','d')
b = (5,4,8,4)
c = dict(zip(a,b))
print(c)
for i,j in c.items():
x = GameEntry(i,j)
print(x)
y=a_.add(x)
print(y)
Inside your class Scoreboard you keep a list of game entries:
self._board = [None]*capacity # reserve space for future scores
This list is used to keep GameEntry entries:
self._board[j] = entry
The logic in your application uses ._n to track the number of entries added, but only up to total number of score slots available (self._n < len(self._board)).
If this is False (i.e. the number of entries added is the same as the capacity of the entry list when it was initialized), the other part of the or statement gets executed:
score > self._board[-1].get_score()
This looks at the last element in self._board - i.e. what is supposed to be the slot entry with the lowest score to see if this score deserves to be entered into the list instead of the previous one. Any negative list index starts from the end of the list instead of the wrong, so -1 points to the last entry, -2 the second to last entry, and so on.
If you get a None entry while running your code (and not just printing it out before you've added ten entries) is another question, and is probably what you need to debug further (but it doesn't seem to be the case from your code). If you attempt to print that entry before inserting all ten entries (i.e. filling up the entry list), there won't be an entry in last place, and the None placeholder will still be there.

Python terminal is printing the location of the object in a class not the data stored in the object

I have a class I've imported into a Python file. But my code is printing the location of the object not the data stored in the object. It is giving me this output, '<Chapter_10_Program_Exercise_5.RetailItem object at 0x10e281520>' which I think is the location but how can I change that? Here's the code and a picture of the python terminal output.
class RetailItem:
# __init__ method initializes the attributes.
def __init__(self, description, units, price):
self.__item_description = description
self.__units_in_inventory = units
self.__price = price
# The set_item_description method gets the item type.
def set_item_description(self, description):
self.__item_description = description
# The set_units_in_inventory method gets number of items available.
def set_units_in_inventory(self, units):
self.__units_in_inventory = units
# The set_price method gets the cost of item.
def set_price(self, price):
self.__price = price
# The get_item_description method returns the item type.
def get_item_description(self):
return self.__item_description
# The get_units_in_inventory returns the number of items available.
def get_units_in_inventory(self):
return self.__units_in_inventory
# The get_price method returns the cost of item.
def get_price(self):
return self.__price
from Chapter_10_Program_Exercise_5 import RetailItem
class CashRegister:
# The __init__ method initializes the attributes.
def __init__(self):
self.__items = []
def clear(self):
self.__items = []
def purchase_item(self, retail_item):
self.__items.append(retail_item)
print('The item was added to the cash register.')
def get_total(self):
total_cost = 0.0
# for loop
for item in self.__items:
total_cost = total_cost +item.get_price()
return total_cost
def display_items(self):
print('The items in the cash register are:')
for item in self.__items:
print(item)
PANTS = 1
SHIRT = 2
DRESS = 3
SOCKS = 4
SWEATER = 5
def main():
pants = RetailItem('Pants', 10, 19.99)
shirt = RetailItem('Shirt', 15, 12.50)
dress = RetailItem('Dress', 3, 79.00)
socks = RetailItem('Socks', 50, 1.00)
sweater = RetailItem('Sweater', 5, 49.99)
sale_items = {PANTS:pants, SHIRT:shirt, DRESS:dress, SOCKS:socks, SWEATER:sweater}
register = CashRegister()
checkout = 'N'
while checkout =='N':
# Call the get_user_option and it is assigned to the user_option
user_option = get_user_option()
# Sale_items of argument user_option is assigned to the item
item= sale_items[user_option]
# If condition to check the items in the items_in_inventory
if item.get_units_in_inventory()== 0:
print('The item is out of stock.')
else:
register.purchase_item(item)
# New item is updated and it is assigned to the new_item
new_item = RetailItem(item.get_item_description(),
item.get_units_in_inventory()-1,
item.get_price())
# Item is updated according to the user selected option
sale_items[user_option] = new_item
# The user input is assigned to the attribute checkout
checkout = input('Are you ready to check out (Y/N)? ')
print()
print('Your purchase total is:',\
format(register.get_total(),'.2f'))
print()
register.display_items()
register.clear()
# Define the get_user_option() method to print the menu items
def get_user_option():
print('Menu')
print('-------------------')
print('1. Pants')
print('2. Shirt')
print('3. Dress')
print('4. Socks')
print('5. Sweater')
print()
option = int(input('Enter the menu number of the item you would like to purchase: '))
print()
while option > SWEATER or option < PANTS:
option = int(input('Please enter a valid item number: '))
return option
main()
Python Terminal Output
This is how python manages the printing of objects. If you want to print attributes you need to tell python which representation you want for your object.
You can do that by implementing these methods in the object class:
class RetailItem:
.
.
.
def __repr__(self):
return "RetailItem()"
def __str__(self):
return "" + self.__item_description + str(self.__units_in_inventory) + str(self.__price)
Note that the two methods will be automatically called in different situations:
>>> ri = RetailItem()
>>> ri
RetailItem()
>>> print(ri)
description 2.0 13.99
Since all variables within RetailItem are private, you'd
need to use the getter method (get_*()) to grab the info.
So to apply that to your display_items() method:
def display_items(self):
print('The items in the cash register are:')
for item in self.__items:
print("Description: %s, Units in Inventory: %d, Price: %0.2f" %
(item.get_item_description(),
item.get_units_in_inventory(),
item.get_price())

How to calculate total of defs using django?

I would like to calculate the total balance of clients, i did this class with def but it calculate for one client only, i would like to create one def to calculate the total of client_balance of all clients i have.
class ClientsBalance(models.Model):
client = models.OneToOneField(Client, on_delete=models.CASCADE,related_name='Client')
def sales(self):
invoices = self.client.invoice_set.all()
sales_amount = 0
for invoice in invoices:
sales_amount += invoice.amountDuettc()
return sales_amount
def clientpayment(self):
invoices = self.client.invoice_set.all()
clientpayment = 0
for invoice in invoices:
clientpayment += invoice.amount_paid()
return clientpayment
def client_balance(self):
items = self.client.invoice_set.all()
invoice_balance = 0
for item in items:
invoice_balance = (self.sales()) - (self.clientpayment()) + (item.client.initialBalance)
return invoice_balance
First of all, you have a typo in your function which makes each iteration overwriting invoice_balance.
This will return the sum as desired:
def client_balance(self):
items = self.client.invoice_set.all()
invoice_balance = 0
for item in items:
invoice_balance += (self.sales()) - (self.clientpayment()) + (item.client.initialBalance)
return invoice_balance
Second of all you could merge your logic if required since you always use the same queryset like so e.g.:
def calculations(self):
queryset = self.client.invoice_set.all()
sales_amount = 0
clientpayment = 0
invoice_balance = 0
for client in queryset:
sales_amount += client.amountDuettc()
clientpayment += client.amount_paid()
invoice_balance += client.amountDuettc() - client.clientpayment() + client.client.initialBalance()
context = {
'sales_amount': sales_amount,
'clientpayment': clientpayment,
'invoice_balance': invoice_balance
}
return context
You current logic is returning balance of last client. In every iteration, invoice_balance override the previous value.
Try this.
Initialize an empty dictionary and append dictionary in every iteration:
def client_balance(self):
items = self.client.invoice_set.all()
invoice_dict = {}
for item in items:
invoice_balance = (self.sales()) - (self.clientpayment()) + (item.client.initialBalance)
invoice_dict[client_pk] = invoice_balance # client_pk is something unique for client.
return invoice_dict
This will return an dictionary with invoice balance of every client.

Python test andela

HST2: OBJECT ORIENTED PROGRAMMING LAB
Create a class called ShoppingCart.
Create a constructor that takes no arguments and sets the total attribute to zero, and initializes an empty dict attribute named items.
Create a method add_item that requires item_name, quantity and price arguments. This method should add the cost of the added items to the current value of total. It should also add an entry to the items dict such that the key is the item_name and the value is the quantity of the item.
Create a method remove_item that requires similar arguments as add_item. It should remove items that have been added to the shopping cart and are not required. This method should deduct the cost of the removed items from the current total and also update the items dict accordingly.
If the quantity of an item to be removed exceeds the current quantity of that item in the cart, assume that all entries of that item are to be removed.
Create a method checkout that takes in cash_paid and returns the value of balance from the payment. If cash_paid is not enough to cover the total, return "Cash paid not enough".
Create a class called Shop that has a constructor which takes no arguments and initializes an attribute called quantity at 100.
Make sure Shop inherits from ShoppingCart.
In the Shop class, override the remove_item method, such that calling Shop's remove_item with no arguments decrements quantity by one.
# OOP Lab
class ShoppingCart(object):
def __init__(self):
total = 0
item = {}
self.total = total
self.item = item
def add_item(item_name, quantity, price):
cost = quantity * price
self.total += cost
self.item = {"item_name":quantity}
def remove_item(item_name,quantity,price):
cost = quantity * cost
self.total -= cost
for i in self.item:
if quantity > self.item[i]:
del self.item["item_name"]
def checkout(cash_paid):
if cash_paid < self.total:
return "Cash paid not enough"
class Shop(ShoppingCart):
def __init__(self):
quantity = 100
self.quantity = quantity
def remove_item():
self.quantity -= 1
#! Error State the following:
my add_item is having four argument instead of three each time i run this code:
Please i need help with this code, am new with python, i will appreciate any programming angel in python to rescue me now.
Try this, it should work out just fine:
class ShoppingCart(object):
def __init__(self):
self.total = 0
self.items = {}
def add_item(self, item_name, quantity, price):
self.total += quantity * price
if type(item_name) == str and quantity > 0:
self.items.update({item_name: quantity})
def remove_item(self, item_name, quantity, price):
if quantity >= self.items[item_name] and quantity >= 1:
items_cost = price * self.items[item_name]
self.total -= items_cost
del self.items[item_name]
else:
self.total -= quantity * price
self.items[item_name] -= quantity
def checkout(self, cash_paid):
balance = 0
if cash_paid < self.total:
return "Cash paid not enough"
balance = cash_paid - self.total
return balance
class Shop(ShoppingCart):
def __init__(self):
self.quantity = 100
def remove_item(self):
self.quantity -= 1
Class methods should accept self as the first argument so for example
def add_item(self, item_name, quantity, price):
Instead of
def add_item(item_name, quantity, price):
The "4th argument" being passed is implicitly self, that is why the number of arguments is one higher than you are expecting.

Trouble with removing items from list

I'm having trouble getting this function to work. The purpose of it is to delete items from a list.
def sell(inventory_list):
print()
count = int(input('How many items would you like to sell? '))
print()
for count in range(count):
print()
type = input('Enter the type of item you wish to sell? ')
print()
name = input('Enter the name of the item you wish to sell? ')
print()
price = float(input('What is the price of the item you wish to sell? $'))
items = Plant.SubPlant(type, name, price)
inventory_list.remove(items)
return inventory_list
Your inventory list doesn't have the new instance you are trying to remove. Just because it contains the same atrrs/values does not mean they are the same.
To be able to do this perhaps implement method __eq__ in your SubPlant class:
class SubPlant(object):
def __init__(self, type, name, price):
self.type = type
self.name = name
self.price = price
def __eq__(self, other):
return self.__dict__ == other.__dict__

Categories

Resources