-
Notifications
You must be signed in to change notification settings - Fork 0
/
Currency.py
147 lines (130 loc) · 4.01 KB
/
Currency.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
# Author Geoff Miller
# Date: 12-26-15
# Currency Problem
import operator
from Control import Control
from Errors import ErrorCodes
class Currency:
"""
Defines a currency set
"""
# num of solutions
num_solutions = 0
# currency names
names = {}
# currency values
values = {}
# number of coins to hit target
r_values = {}
# list of defined currency names sorted by value
s_values = []
# bool for keeping track if the amounts need adjusted
is_adjusted = False
max_name_len = 0
@staticmethod
def use_default_currency():
Control.target = 100
Currency.define("quarter", 25)
Currency.define("dime", 10)
Currency.define("nickle", 5)
Currency.define("penny", 1)
Currency.process_defined_values()
# Control.target = 1500
# Currency.define("coin", 1000)
# Currency.define("arrowhead", 500)
# Currency.define("button", 10)
# Currency.process_defined_values()
@classmethod
def get_coin_name(cls, val):
"""
Prints only the name of the specified currency unit
:param val: val of the unit name to print
:return:
"""
# TODO forgot where i was going with this...
return cls.names[val]
@classmethod
def get_coin_val(cls, name):
"""
returns the value of the named coin in the currency set
:param name: name of coin
:return: value of coin
"""
return cls.values[name]
@classmethod
def define(cls, name, val):
"""Defines a unit of currency with a name and value (AKA "coin")
:param val: value of the unit being defined
:param name: label of the unit being defined
:return:
"""
cls.values[name] = val
cls.names[val] = name
return ErrorCodes.R_SUCCESS
@classmethod
def define_by_list(cls, list):
target = None
nums = []
r_nums = []
vals = []
names = []
has_float = False
for coin in list:
if isinstance(coin[1], float):
has_float = True
break
if has_float:
for coin in list:
if has_float:
nums.append(float(coin[1]))
else:
nums.append(int(coin[1]))
names.append(str(coin[0]))
else:
for coin in list:
nums.append(float(coin[1]))
names.append(str(coin[0]))
target = max(nums)
r_nums = nums[:]
while has_float:
has_float = False
target *= 10
for coin in r_nums:
coin *= 10
if not has_float:
has_float = not coin.is_integer()
Control.target = target
for i, coin in enumerate(r_nums):
if r_nums[i] == 0:
Control.error_exit(ErrorCodes.E_ZERO)
Currency.define(names[i], (target / r_nums[i]))
@classmethod
def process_defined_values(cls):
"""
checks for values that are not integers and adjusts values
so that all numbers will work with integer arithmetic
also performs other utility tasks on finalized currency set
:return:
"""
if not cls.is_adjusted:
cls.s_values = sorted(cls.values.items(), key=operator.itemgetter(1), reverse=True)
cls.r_values = cls.values
# TODO revisit r_values
cls.is_adjusted = True
return ErrorCodes.R_SUCCESS
@classmethod
def sorted_val(cls, val):
"""
:param val: value
:return: return the value of the nth valued coin
"""
return cls.s_values[val][1]
@classmethod
def printer(cls, list):
output = ""
for coin in list:
plural = "s"
if coin[0] == 1:
plural = ""
output += " | %s %-s%+s" % (str(coin[0]).ljust(3), str(coin[1]), plural.ljust(2))
return output