Settling Balance in Python - python

Just wanted to know let's say
Person 1: Paid 66USD
Person 2: Paid 0USD
Person 3: Paid 33USD
How do I program it in a way that it sends a table that tells person 2 has to pay 33USD TO person 1 to settle an equal balance amongst all members?
print('How many people in total')
people_num = int(input())
#Get the name list of everyone
name_list = []
for num in range(0,people_num):
print("What are their names?")
name_list.append(input())
print(name_list)
#get the amount everyone paid
amount = []
for name in name_list:
print("How much did " + name + " pay?")
amount.append(float(input()))
total_amount = sum(amount)
print(total_amount)
#create empty dictionary to calculate how much one person has to pay or receive
owe = []
for x in amount:
owe.append(round(x - (total_amount/people_num),2))
info = {}
for name, amt_owe in zip(name_list,owe):
info[name] = amt_owe
print(info)```

Here is a solution
def find_transactions(info):
for i in info.keys():
# find a negative balance : user A
if info[i] < 0:
for j in info.keys():
# find a positive balance : user B
if info[j] > 0 and i != j:
# user A will pay user B
x = abs(info[i])
if x > info[j]:
x = abs(info[j])
# change values of balances of user A and B
info[j] = info[j]-x
info[i] = info[i]+x
print(f"{i} pay {x} to {j}")
return info
Let's try with different values
people_num = 3
name_list = ["a", "b", "c"]
amount = [66, 0, 33]
in : info = {'a': 33.0, 'b': -33.0, 'c': 0.0}
out :
b pay 33.0 to a
info = {'a': 0.0, 'b': 0.0, 'c': 0.0}
amount = [66, 33, 33]
in : info = {'a': 22.0, 'b': -11.0, 'c': -11.0}
out :
b pay 11.0 to a
c pay 11.0 to a
info = {'a': 0.0, 'b': 0.0, 'c': 0.0}

The simple solution to this would be to count person's balance iterating through a list.
def process_transaction(from_user, to_user, amount):
if from_user['balance'] >= amount:
to_user['balance'] += amount
from_user['balance'] -= amount
print("Transaction success")
else:
print("Transaction failed")
bob = {"balance":100}
alice = {"balance":50}
process_transaction(bob, alice, 50)
print(bob)
print(alice)

does this help you ?
def info():
return {_name: _amount for _name, _amount in zip(name_list, amount)}
def equal_balances(_info):
# Make the transaction between sender and receiver
def transaction(payment_amount):
# print(f"balance before payment: {sender}: {round(_info[sender])}, {receiver}: {round(_info[receiver])}")
_info[receiver] += payment_amount
_info[sender] -= payment_amount
print(f"{sender} pay {round(payment_amount, 2)} to {receiver}")
# print(f"balance after payment: {sender}: {round(_info[sender])}, {receiver}: {round(_info[receiver])}")
medium_amount = total_amount / people_num # get medium amount
# get hwo pay hwo
print(f'The medium amount is: {round(medium_amount, 2)}')
for sender in _info:
if _info[sender] > medium_amount:
for receiver in _info:
if _info[sender] > medium_amount > _info[receiver]:
receiver_need = medium_amount - _info[receiver]
if _info[sender] - receiver_need < medium_amount:
transaction(_info[sender] - medium_amount)
elif _info[sender] >= receiver_need:
transaction(receiver_need)
elif _info[sender] - receiver_need == medium_amount:
transaction(_info[sender] - medium_amount)
return _info
people_num = int(input('How many people in total? '))
# Get the name list of everyone
name_list = []
for num in range(0, people_num):
name_list.append(input('What are their names? '))
print(name_list)
# get the amount everyone paid
amount = []
for name in name_list:
amount.append(float(input(f'How much did {name} pay? ')))
total_amount = sum(amount)
print(total_amount)
people_info = info()
print(people_info)
people_info = equal_balances(people_info)
print(people_info)

Related

How to add a currency symbol to my array?

Goal:
Display my list of commission pay with a £ symbol.
Explanation of what the problem is:
When it comes to displaying the result it does not print the whole result instead it just prints the £ symbol.
What I have tried:
As you can see in the code, I have attempted to convert the array into a string (putting it into its own variable) then I added the currency symbol (£) to it and asked for commission2 to be called. However, it does not show.
OUTPUTTED:
Name Id Houses Sold Commission
£1000
ki 2 2 £
(the £1000 is just to show that the data is actually there, but for some reason when printing in the list, it is not displayed...)
OUTPUT DESIRED:
Name Id Houses Sold Commission
ki 2 2 £1000
I've been at it for hours so any help would be greatly appreciated!
Code where the error occurs:
def print_entered_info(names, ids, num_sold_houses):
print()
row_width = 12
comission_per_house = 500
header = ['Name', 'Id', 'Houses Sold', 'Commission']
print(' '.join(f'{h:<{row_width}}' for h in header))
commission = [n * comission_per_house for n in num_sold_houses]
commission2 = commission
commission2 = ''.join(str(e) for e in commission)
commission2= "£" + commission2
print(commission2)
for values in zip(*[names, ids, num_sold_houses, commission2]):
print()
print(' '.join(f'{v:<{row_width}}' for v in values))
My full code:
def get_int_input(prompt: str) -> int:
num = -1
while True:
try:
num = int(input(prompt))
break
except ValueError:
print('Error: Enter an integer, try again...')
return num
def get_yes_no_input(prompt: str) -> bool:
allowed_responses = {'y', 'yes', 'n', 'no'}
user_input = input(prompt).lower()
while user_input not in allowed_responses:
user_input = input(prompt).lower()
return user_input[0] == 'y'
names = []
ids = []
num_sold_houses= []
def get_single_employee_info(names, ids, num_sold_houses):
names.append(input('What is the employee\'s name?: '))
ids.append(get_int_input('What is the employee\'s id?: '))
num_sold_houses.append(get_int_input('How many houses did the employee sell?: '))
def get_houses_sold_info(names, ids, num_sold_houses):
get_single_employee_info(names, ids, num_sold_houses)
add_another_employee = get_yes_no_input('Add another employee [yes/no]?: ')
while add_another_employee:
get_single_employee_info(names, ids, num_sold_houses)
add_another_employee = get_yes_no_input(
'Add another employee [yes/no]?: ')
def print_entered_info(names, ids, num_sold_houses):
print()
row_width = 12
comission_per_house = 500
header = ['Name', 'Id', 'Houses Sold', 'Commission']
print(' '.join(f'{h:<{row_width}}' for h in header))
commission = [n * comission_per_house for n in num_sold_houses]
commission2 = commission
commission2 = ''.join(str(e) for e in commission)
commission2= "£" + commission2
print(commission2)
for values in zip(*[names, ids, num_sold_houses, commission2]):
print()
print(' '.join(f'{v:<{row_width}}' for v in values))
print()
total_commission = sum(commission)
print(f'Total Commission: £{total_commission}.00 (before bonus)')
print()
bonus = max(commission)
if bonus >= max(commission):
bonus = bonus*0.15
bonus = (int(max(commission)) + bonus)
commission = bonus
print("The person at the top of ranking gets: " + "£" + str(commission)+"0")
print()
rankings = sorted(zip(num_sold_houses, names), reverse=True)
print('Ranking:')
for houses_sold, name in rankings:
print(f'{name} - {houses_sold}')
def main() -> None:
print('Houses Sold Tracker')
print('===================')
names, ids, num_houses_sold = [], [], []
get_houses_sold_info(names, ids, num_houses_sold)
print_entered_info(names, ids, num_houses_sold)
if __name__ == '__main__':
main()
Change out
commission2 = ''.join(str(e) for e in commission)
to
commission2 = ["£" + str(e) for e in commission]
and remove the line under it. Your ''.join was taking 2 list elements and forcing them into a single string, which is not what you want for this logic. You want a list output for the commission2 variable so we create a list and append the stringified values to it along with the currency symbol.
Output:
Name Id Houses Sold Commission
Kevin 1 3 £1500
Stacey 2 5 £2500
Total Commission: £4000.00 (before bonus)
The person at the top of ranking gets: £2875.00
Ranking:
Stacey - 5
Kevin - 3

I want to create a simple inventory management system using classes and data structures. I am new to OOP in python

The code should Capture products in stock (i.e. name, price, date supplied, supplier name, quantity), Retrieve the price when name is given upon each purchase and deducts the quantity in
stock, Calculate the total price for each purchase and prints value indicating date and time of
purchase, Sends an alert when quantity reaches 5 to shopkeeper and places order to supplier.
My code right now is not looping so that I can add a number of products then be able to access them, I tried using a while loop but it is running forever. Kindly help
import datetime
class Stock:
def __init__(self, name, price, supplier, quantity,date):
self.name = name
self.price = price
self.date = date
self.supplier = supplier
self. quantity = quantity
def check_item(self, name):
for i in range(len(ls)):
if (ls[i].name == name):
return i
def sale(self):
n = int(input("How many products to sale: "))
total = 0
for j in range(n):
name = input("Enter Product name : ")
quantity = int(input("Enter quantity: "))
i = obj.check_item(name)
if i and ls[i].quantity >= quantity:
ls[i].quantity -= quantity
if ls[i].quantity < 5:
print("Low Stock! Low Stock! Order Placed")
obj.place_order(name, ls[i].supplier, quantity+10)
print("....Uncle G Shop....")
print(datetime.date.today())
print("Product Name | Quantity | Cost $")
print(ls[i].name, end=" ")
print(quantity, end=" ")
print(ls[i].price * quantity)
total += ls[i].price * quantity
print("\n")
print("Total Cost----->", "$" + total)
else:
print("Product out of stock or not enough quantity")
def purchase(self):
name = input("Enter Product name: ")
date = datetime.date.today()
i = obj.check_item(name)
if i:
ls[i].quantity += int(input("Enter quantity: "))
ls[i].price = int(input("Enter product price: "))
ls[i].date = date
else:
quantity = int(input("Enter quantity: "))
price = int(input("Enter product price: "))
supplier = input("Enter Supplier: ")
ob = Stock(name, price, supplier, quantity, date)
ls.append(ob)
def place_order(self,name, supplier, quantity):
return name, supplier, quantity
def print_products(self):
def __repr__(self):
return str(self.name) + str(self.price) + str(supplier) + str(self.quantity) + str(self.date)
return __repr__
def main(self):
print("Welcome To Uncle G Shop")
print("choose an option below")
print("\n1.Enter a Product\n2.Make a sale \n3.See all Products\n4.Exit")
option = int(input("Enter option here: "))
while True:
if option == 1:
obj.purchase()
elif option == 2:
obj.sale()
elif option == 3:
obj.print_products()
elif option == 4:
print("Have a good day")
break
else:
print("Enter a valid input!")
# A list to add Products
ls = []
# an object of Stock class
obj = Stock('', 0, 0, 0, '')
obj.main()
Your main menu doesn't have a break from the while loop for option 4.
You also need to think again about how to use your class. At present, you have multiple methods referring to a variable, ls, created outside of the class. Either treat Stock as a class to deal with individual purchase records, or to deal with stock overall. You could maintain in the class itself a list of instances of the class and offer class methods, as well as instance methods, to manage that overall stock.

Trying to sort data in a specific format by 3 types

So I am having issues with sorting data in the format:
Name, Score1, Score2, Score3 stored in a text file.
For example:
Zac, 0, 0, 0
Zac, 0, 0, 0
Zac, 0, 0, 0
Zac, 0, 0, 0
I need to sort it by alphabetical, highest score and average score but I am unsure on how to do this.
Could someone help me out or give me some pointers as I'm not sure where to start?
Here is the task:
Task 3
The teacher wants to use the results from students taking these quizzes to log their performance. The system should store the last three scores for each student. The teacher would like to be able to output the results of the quiz for a particular class, sorted:
• in alphabetical order with each student’s highest score for the tests
• by the highest score, highest to lowest
• by the average score, highest to lowest.
And my code so far:
import random
import csv
User = input("Student (s) / Teacher (t):")
if User == "s" or "S":
classList = []
Name = input("What is your name? ")
Class = int(input("Please enter your class: "))
CompletedTimes = int(0)
while CompletedTimes <= 2:
NumberQuestion = 0
Score = int(0)
while NumberQuestion < 10:
Symbol = random.randrange (1, 4)
if Symbol == 1:
number1 = random.randrange(1, 25)
number2 = random.randrange(1, 25)
SetQuestion = (number1 * number2)
print (number1, "x", number2)
while True:
try:
Answer = int(input("Answer: "))
break
except ValueError:
print("Enter a number")
if Answer == SetQuestion:
print ("Correct. +1")
Score = (Score + 1)
NumberQuestion = (NumberQuestion + 1)
else:
print ("incorrect")
NumberQuestion = (NumberQuestion + 1)
if Symbol == 2:
number1 = random.randrange(1, 25)
number2 = random.randrange(1, 25)
SetQuestion = (number1 + number2)
print (number1, "+", number2)
while True:
try:
Answer = int(input("Answer: "))
break
except ValueError:
print("Enter a number")
if Answer == SetQuestion:
print ("Correct. +1")
Score = (Score + 1)
NumberQuestion = (NumberQuestion + 1)
else:
print ("incorrect")
NumberQuestion = (NumberQuestion + 1)
elif Symbol == 3:
number1 = random.randrange(1, 25)
number2 = random.randrange(1, 25)
SetQuestion = (number1 - number2)
print (number1, "-", number2)
while True:
try:
Answer = int(input("Answer: "))
break
except ValueError:
print("Enter a number")
if Answer == SetQuestion:
print ("Correct. +1")
Score = (Score + 1)
NumberQuestion = (NumberQuestion + 1)
else:
print ("incorrect")
NumberQuestion = (NumberQuestion + 1)
classList.append(Score)
print ("Your final score is: ", Score)
CompletedTimes = (CompletedTimes + 1)
classList = str(classList)
classList = str(classList)[1:-1]
Class = str(Class)
Class = (Class+'.csv')
thefile = open(Class, 'w')
thefile.write(Name + ',')
thefile.write(classList)
thefile.close()
elif User == "t" or 'T':
CONTINUE CODE HERE
Assuming that your file is named "data.csv" and has the following text:
Zac, 0, 0, 0
Zac, 4, 5, 6
Zac, 0, 0, 0
Zac, 1, 2, 3
Al, 1, 2, 3
Then we can construct our code:
import csv # import csv reader
with open("data.csv", 'r') as f: # open the file
reader = csv.reader(f) # read the data
lines = [[l[0], float(l[1][1:]), float(l[2][1:]), float(l[3][1:]) for l in reader]
# sort the list
sorted(lines, key = lambda x: (x[0], max(x[1:3]),sum(x[1:3])/float(len(x[1:3]))))
# [['Al', 1.0, 2.0, 3.0],
# ['Zac', 0.0, 0.0, 0.0],
# ['Zac', 0.0, 0.0, 0.0],
# ['Zac', 1.0, 2.0, 3.0],
# ['Zac', 4.0, 5.0, 6.0]]
Because your file isn't perfectly formatted csv (there is a space in between the commas), we have to do some extra parsing. This is the breakdown of what happens at lines=:
reader contains each line from your file so we can iterate through it
for l in reader says, for each line in reader, do some action
The outermost brackets indicate that we want to store the result of these actions in a list
The innermost brackets indicate that for each line in reader, we want to build a list that holds the data from the line
In order to do math operations, we have to convert the strings to int or float types
i[0] access the first element which is the name
i[1] is the second element which is currently a string - ' 0'
i[1][1:] says given the second element, take everything from the second element to the end of the string which is '0'
float([1][1:]) says given the string '0', convert it to a float type
Then we sort the list. First, it will sort on the names, then on the max score, then on the average.
Sort list by multiple attributes
I would have an object like this:
class Grade(object):
def __init__(self, name, score1, score2, score3):
self.name = name
self.score1 = score1
self.score2 = score2
self.score3 = score3
#property
def average(self):
return float(self.score1 + self.score2 + self.score3) / 3.0
#property
def highest(self):
return max([self.score1, self.score2, self.score3])
def __repr__(self):
return "<Grade({}, [{}, {}, {}]) object at 0x{:08X}>".format(self.name, self.score1, self.score2, self.score3, id(self))
def __str__(self):
return "Grade({}, [{}, {}, {}])".format(self.name, self.score1, self.score2, self.score3)
x = Grade("Bob", 85, 92, 90)
y = Grade("Alice", 80, 75, 95)
grades = [x, y]
alphabetical = sorted(grades, key=lambda g: g.name)
highest_score = sorted(grades, key=lambda g: g.highest, reverse=True)
average_score = sorted(grades, key=lambda g: g.average, reverse=True)
def display(l):
print([str(item) for item in l])
display(alphabetical) # => ['Grade(Alice, [80, 75, 95])', 'Grade(Bob, [85, 92, 90])']
display(highest_score) # => ['Grade(Alice, [80, 75, 95])', 'Grade(Bob, [85, 92, 90])']
display(average_score) # => ['Grade(Bob, [85, 92, 90])', 'Grade(Alice, [80, 75, 95])']

Getting the total sum in simple cash register script

I just started learning Python and I would really appreciate some advice on this.
When I try to save the last total in the 'total_price' list, it doesn't save.
What am I doing wrong?
Also, are there any better ways to write this?
Thank you
price_list = {'gold': 10,
'red': 20,
'brown': 30
}
vol_list = {'gold': 0.1,
'red': 0.2,
'brown': 0.3
}
cl_list = {'gold': 100,
'red': 200,
'brown': 300
}
while True:
print("What do you want to buy?")
choice = input("Choices: gold, red or brown > ")
amount = int(input("How many do you want? >"))
price = price_list[choice] * amount
vol = (cl_list[choice] * amount) * vol_list[choice]
total_price = []
total_vol = []
total_price.append(price)
total_vol.append(vol)
print_price = sum(total_price[:])
print_vol = sum(total_vol[:])
print("-" * 10)
print("Your total is now: ", print_price)
print("Your total vol is now: ", print_vol)
print("-" * 10)
cont = input("Do you want to continue shopping [Y/n]?> ")
if cont == "n" or cont == "no":
print("#" * 10)
print("#" * 10)
print("Your total is: ", print_price)
print("Your total vol is: ", print_vol)
print("#" * 10)
print("#" * 10)
break
You are Initializing your arrays in your while loop, so on every new iteration the old total_price gets overwritten.
Initialize your arrays before you loop
total_price = []
total_vol = []
while True:
...

Can't figure out a Python exercise with dictionaries

I have the following code:
shoppingList = ["banana","orange","apple"]
inventory = {"banana": 6,
"apple": 0,
"orange": 32,
"pear": 15
}
prices = {"banana": 4,
"apple": 2,
"orange": 1.5,
"pear": 3
}
def calculateBill(food):
total = 0
for k in food:
total += prices[k]
return total
calculateBill(shoppingList)
The exercise tells me to complete the function following these instructions:
Don't add the price of an article in your bill if it is not in your inventory.
After you buy an article, substract one from the inventory.
I don't know how to do it and I don't know if I have any other mistakes in my code.
If it isn't clear, the value in inventory is the stock of that item, and the value in "prices" is the price.
First of all, I don't see comida defined anywhere before its use. I'll assume that by comida, you mean food.
Here is a simple solution:
def calculateBill(food):
total = 0
for k in food:
if inventory.get(k, 0) > 0:
total += prices[k] # updates total
inventory[k] = inventory[k] - 1 # updates inventory
return total
You could do the following
def calculateBill(food):
total = 0
for k in food:
if k in inventory:
if inventory[k] > 0:
total += prices[k]
inventory[k] = inventory[k] - 1
else:
print 'There are no %s in stock' % k
else:
print 'dont stock %s' % k
return total
For 1)
if k in inventory:
Will check if the key is present in your inventory dict.
For 2)
inventory[k] = inventory[k] - 1
Will substract 1 from your inventory
One flaw in this code is that it does not check that the inventory count is above 0 before allowing to buy. So
if inventory[k] > 0:
Does this.
Here's a complete solution.
class Error(Exception):
"""Base class for Exceptions in this module"""
pass
class QtyError(Error):
"""Errors related to the quantity of food products ordered"""
pass
def calculateBill(food):
def buy_item(food_item, qty=1, inv_dict=None, prices_dict=None):
get_price = lambda item,price_dct: price_dct.get(item,9999999)
if inv_dict is None:
inv_dict = inventory
if prices_dict is None:
prices_dict = prices
if inv_dict.get(food_item, 0) >= qty:
inv_dict[food_item] -= qty
return sum(get_price(food_item, prices_dict) for _ in range(qty))
else:
raise QtyError("Cannot purchase item '{0}' of quantity {1}, inventory only contains {2} of '{0}'".format(food_item, qty, inv_dict.get(food_item,0)))
total = sum(buy_item(food_item, 1, inventory, prices) for food_item in food)
return total

Categories

Resources