-
Notifications
You must be signed in to change notification settings - Fork 11
/
utils.py
176 lines (145 loc) · 5.72 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
""" Utility functions for the Retail Market Project """
def change_detail(stock, detail):
""" Function for admin to change details of items """
max_id = len(stock) # Instead of len() being computed on each iteration.
progress = 'y'
while progress == 'y':
try:
item_id = int(input("Enter item ID: "))
if item_id < 1 or item_id > max_id:
print("Invalid Item ID")
continue
value = input("Enter new %s: " % detail)
if detail != "name":
value = int(value)
if value < 0:
print("Invalid %s!!" % detail)
continue
except ValueError:
print("Invalid input!!")
continue
else:
item = stock[item_id - 1]
item[detail] = value
print(f"{detail} of '{item['name']}' successfully changed")
finally:
progress = input(
f"Do you want to change the {detail} of another item (y/n)? ").lower()
while progress != 'y' and progress != 'n':
print("Invalid Input!!")
progress = input(
f"Do you want to change the {detail} of another item (y/n)? ").lower()
print()
def add_items(stock):
""" Adds new items to the stock """
progress = 'y'
while progress == 'y':
try:
name = input("Enter Item Name: ")
price = int(input("Enter Unit Price of item: "))
if price < 0:
print("Invalid price!!")
continue
quantity = int(input("Enter item Quantity: "))
if quantity < 0:
print("Invalid quantity!!")
continue
except ValueError:
print("Invalid input!!")
continue
else:
# Add only if item doesn't already exists in stock
for item in stock:
if item["name"].casefold() == name.casefold():
print("'%s' already exists in stock!" % name)
break
else:
# No matching item in stock
stock.append({"name": name, "price": price, "quantity": quantity})
print("New item '%s' successfully added." % name)
finally:
progress = input("Do you want to add another item (y/n)? ").lower()
while progress != 'y' and progress != 'n':
print("Invalid Input!!")
progress = input("Do you want to add another item (y/n)? ").lower()
print()
def make_purchase(stock, purchase):
""" Computes goods purchased by the customer and displays receipt
stock: stock data; list of dicts
purchase: purchase details; dict of the form {id: quantity, ...}
"""
total = 0
total_vat = 0
unit_prices = set() # To avoid unnecessary repetition
width = 81
disp_format = "| {:<30} || {:>8} || {:>3} || {:>10.2f} || {:>10.2f} |"
print('=' * width)
print("|%s|" % "RECEIPT".center(width - 2))
# The above can be acheived thus, using the new style:
# By using replacement fields within format_spec or another replacement field.
# print(f"|{'RECEIPT':^{width-2}}|")
# OR
# print("|{0:^{1}}|".format("RECEIPT", width-2))
# This last one is probably the easiest to read
#
# The `-2` is because of the two '|' (pipe) characters in the string.
print('-' * width)
print("| {:^30} || {:^8} || {:^3} || {:^10} || {:^10} |".format(
"Item", "Unit (#)", "Qty", "VAT (#)", "Amount (#)"))
# *Implicit line continuation* applies above
print('-' * width)
for item_id, quantity in purchase.items():
item = stock[item_id - 1]
unit_price = item["price"]
amount = quantity * unit_price
unit_prices.add(unit_price)
if quantity < 5:
vat = amount * 0.2
amount *= 1.2 # 100% + 20%
elif quantity > 10:
vat = amount * 0.3
amount *= 1.3 # 100% + 30%
else:
vat = 0
print(disp_format.format(item["name"], unit_price, quantity, vat, amount))
total_vat += vat
total += amount
print('-' * width)
print(disp_format.format("Total", "", "", total_vat, total))
if len(purchase) > 10 and min(unit_prices) >= 100:
print('-' * width)
print("| %s |" % "Bonus Voucher: #800".ljust(width - 4))
# The above can also be acheived as done for "RECEIPT" above.
# The `-4` is because of the two '| ' (pipe and space) in the string.
print('=' * width)
print()
return total
def update_stock(stock, purchase):
""" Update stock after a purchase
stock: stock data; list of dicts
purchase: purchase details; dict of the form {id: quantity, ...}
"""
for item_id, quantity in purchase.items():
stock[item_id - 1]["quantity"] -= quantity
# Note:
# The global scope of a function/class
# is the scope of the module in which it's defined,
# NOT neccessarily the module in which it's called.
# This comes into play when a function/class is imported and used in another module
# e.g the case of `_gain` in the functions below
def add_gain(amount):
""" Computes daily gain, using a global variable """
global _gain # `_gain` will be re-assigned to
_gain += amount
def view_gain():
""" Display the day's Total Gain """
output = f"| Today's Total Gain: {_gain:.2f} |"
print('=' * len(output))
print(output)
print('=' * len(output))
print()
# A leading underscore automatically makes a global name
# hidden from a wildcard (*) import of this module
# i.e any `from utils import *` in another module
# but it's still visible to functions in this module.
_gain = 0