1 class currency(object):
2 def __init__(self, symbol):
5 def sformat(self, amount):
6 return "%s %s" % (self.symbol, self.format(amount))
9 return "#<currency %s>" % self.symbol
17 def define(cls, *args, **kwargs):
18 self = cls(*args, **kwargs)
19 cls._known[self.symbol] = self
22 return cls._known[symbol]
25 return _currency_restore, (type(self), self.symbol,)
26 def _currency_restore(cls, symbol):
27 return cls.get(symbol)
29 class integral(currency):
30 def __init__(self, symbol):
31 super().__init__(symbol)
33 def format(self, amount):
36 def parse(self, text):
37 return value(int(text), self)
39 class decimal(currency):
40 def __init__(self, symbol, separator, thseparator, decimals=2):
41 super().__init__(symbol)
42 self.separator = separator
43 self.thseparator = thseparator
44 self.decimals = decimals
46 def format(self, amount):
48 return "-" + self.format(-amount)
49 bias = 10 ** self.decimals
51 fp = amount - (ip * bias)
52 return "%i.%0*i" % (ip, self.decimals, fp)
54 def parse(self, text):
56 p = text.find(self.separator)
57 bias = 10 ** self.decimals
59 text = text.replace(self.thseparator)
60 if not text.isdigit():
61 raise ValueError(text)
62 return int(text) * bias
64 if p != len(text) - 3:
65 raise ValueError(text)
66 ip = text[:p].replace(self.thseparator, "")
68 if not (ip.isdigit() and fp.isdigit()):
69 raise ValueError(text)
73 raise ValueError(text)
74 return (ip * bias) + fp
76 return value(-parse2(text[1:]), self)
78 return value(parse2(text), self)
80 decimal.define("SEK", ",", " ")
81 decimal.define("USD", ".", ",")
82 integral.define("JPY")
85 __slots__ = ["amount", "currency"]
86 def __init__(self, amount, currency):
87 self.amount = int(amount)
88 self.currency = currency
91 return "%s %s" % (self.currency.symbol, self.currency.format(self.amount))
93 def __add__(self, other):
94 if self.currency != other.currency:
95 raise ValueError("cannot add %s to %s" % (other.currency.symbol, self.currency.symbol))
96 return value(int(self.amount + other.amount), self.currency)
97 def __sub__(self, other):
98 if self.currency != other.currency:
99 raise ValueError("cannot subtract %s from %s" % (other.currency.symbol, self.currency.symbol))
100 return value(int(self.amount - other.amount), self.currency)
101 def __mul__(self, other):
102 return value(int(self.amount * other), self.currency)
103 def __truediv__(self, other):
104 if self.currency != other.currency:
105 raise ValueError("cannot divide %s with %s" % (self.currency.symbol, other.currency.symbol))
106 return self.amount / other.amount
107 def __floordiv__(self, other):
108 if self.currency != other.currency:
109 raise ValueError("cannot divide %s with %s" % (self.currency.symbol, other.currency.symbol))
110 return self.amount // other.amount
111 def __mod__(self, other):
112 if self.currency != other.currency:
113 raise ValueError("cannot divide %s with %s" % (self.currency.symbol, other.currency.symbol))
114 return value(int(self.amount % other.amount), self.currency)
115 def __divmod__(self, other):
116 if self.currency != other.currency:
117 raise ValueError("cannot divide %s with %s" % (self.currency.symbol, other.currency.symbol))
118 return (self.amount // other.amount, value(int(self.amount % other.amount), self.currency))
120 return value(-self.amount, self.currency)
122 def __eq__(self, other):
123 if self.currency != other.currency:
124 raise ValueError("cannot compare %s with %s" % (self.currency.symbol, other.currency.symbol))
125 return self.amount == other.amount
126 def __ne__(self, other):
127 if self.currency != other.currency:
128 raise ValueError("cannot compare %s with %s" % (self.currency.symbol, other.currency.symbol))
129 return self.amount != other.amount
130 def __lt__(self, other):
131 if self.currency != other.currency:
132 raise ValueError("cannot compare %s with %s" % (self.currency.symbol, other.currency.symbol))
133 return self.amount < other.amount
134 def __le__(self, other):
135 if self.currency != other.currency:
136 raise ValueError("cannot compare %s with %s" % (self.currency.symbol, other.currency.symbol))
137 return self.amount <= other.amount
138 def __gt__(self, other):
139 if self.currency != other.currency:
140 raise ValueError("cannot compare %s with %s" % (self.currency.symbol, other.currency.symbol))
141 return self.amount > other.amount
142 def __ge__(self, other):
143 if self.currency != other.currency:
144 raise ValueError("cannot compare %s with %s" % (self.currency.symbol, other.currency.symbol))
145 return self.amount >= other.amount
148 return hash(self.amount) + hash(self.currency)