-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrounding_example.py
161 lines (130 loc) · 4.89 KB
/
rounding_example.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
'''Rounding Issue with Floats and Solutions'''
# Floating point numbers are subject to rounding errors as they convert between
# binary and decimal. One solution is to use the decimal module that comes with
# python. The decimal module provides support for fast correctly-rounded
# decimal floating point arithmetic. It offers several advantages over the
# float datatype but will require some heavy investigation.
# The other method of dealing with this rounding error is to work strictly
# with integers instead of floats. This would mean multiplying by 100 and
# essentially doing all calculations as pennies, then dividing by 100 to
# convert back to dollars for the final show_balance.
# Example 1: floats
# -----------------------------------------------------------------------------
class Account1():
def __init__(self, name: str, opening_balance: float=0.0):
self.name = name
self._balance = opening_balance
print('Account created for {}'.format(self.name))
self.show_balance()
def deposit(self, amount: float):
if amount > 0.0:
self._balance += amount
print('{} deposited'.format(amount))
return self._balance
def withdraw(self, amount: float):
if 0 < amount <= self._balance:
self._balance -= amount
print('{} withdrawn'.format(amount))
return amount
else:
print('Amount must be greater than 0 and not exceed balance')
return 0.0
def show_balance(self):
print('Balance on account {} is {}'.format(self.name, self._balance))
# testing:
if __name__ == '__main__':
rick = Account1('Rick')
rick.deposit(100.10)
rick.deposit(499.10)
rick.deposit(55.10)
rick.withdraw(80.00)
rick.show_balance()
# Account created for Rick
# Balance on account Rick is 0.0
# 100.1 deposited
# 499.1 deposited
# 55.1 deposited
# 80.0 withdrawn
# Balance on account Rick is 574.3000000000001
# Example 2: decimal module
# -----------------------------------------------------------------------------
from decimal import *
class Account2():
# class constant, accessible without creating an instance:
_qb = Decimal('0.00')
def __init__(self, name: str, opening_balance: float=0.0):
self.name = name
self._balance = Decimal(opening_balance).quantize(Account2._qb)
print("Account created for {}. ".format(self.name))
self.show_balance()
def deposit(self, amount: float):
decimal_amount = Decimal(amount).quantize(Account2._qb)
if decimal_amount > Account2._qb:
self._balance = self._balance + decimal_amount
print("{} deposited".format(decimal_amount))
return self._balance
def withdraw(self, amount: float):
decimal_amount = Decimal(amount).quantize(Account2._qb)
if Account2._qb < decimal_amount <= self._balance:
self._balance = self._balance - decimal_amount
print("{} withdrawn".format(decimal_amount))
return decimal_amount
else:
print('Amount must be greater than 0 and not exceed balance')
return Account2._qb
def show_balance(self):
print("Balance on account {} is {}".format(self.name, self._balance))
#testing:
if __name__ == '__main__':
rick = Account2('Morty')
rick.deposit(100.10)
rick.deposit(499.10)
rick.deposit(55.10)
rick.withdraw(80.00)
rick.show_balance()
# Account created for Morty.
# Balance on account Morty is 0.00
# 100.10 deposited
# 499.10 deposited
# 55.10 deposited
# 80.00 withdrawn
# Balance on account Morty is 574.30
# Example 3: use integers
# -----------------------------------------------------------------------------
class Account3():
def __init__(self, name: str, opening_balance: int=0):
self.name = name
self._balance = opening_balance
print('Account created for {}'.format(self.name))
self.show_balance()
def deposit(self, amount: int):
if amount > 0.0:
self._balance += amount
print('{:.2f} deposited'.format(amount / 100))
return self._balance / 100
def withdraw(self, amount: int):
if 0 < amount <= self._balance:
self._balance -= amount
print('{:.2f} withdrawn'.format(amount / 100))
return amount / 100
else:
print('Amount must be greater than 0 and not exceed balance')
return 0.0
def show_balance(self):
print('Balance on account {} is {:.2f}'.format(
self.name, self._balance / 100))
# testing:
if __name__ == '__main__':
rick = Account3('Bob')
rick.deposit(10010)
rick.deposit(49910)
rick.deposit(5510)
rick.withdraw(8000)
rick.show_balance()
# Account created for Bob
# Balance on account Bob is 0.00
# 100.10 deposited
# 499.10 deposited
# 55.10 deposited
# 80.00 withdrawn
# Balance on account Bob is 574.30