def chakra(N): b = Decimal(1) k = Decimal(0) while not issquare(k + N): k = k + 1 l = Decimal(0) while not issquare(l + N): l = l - 1 if abs(l) < abs(k): k = l a = Decimal(k + N).sqrt() while k != 1 or (not isnatural(a) or not isnatural(b)): #print a, b, k d = [a, b, k] if k.copy_abs() == 4: [a, b, k] = [a / 2, b / 2, k / 4] continue if k == 1: while not isnatural(a) or not isnatural(b): [a, b, k] = compose([a, b, k], d, N) continue if k == -1: [a, b, k] = compose(d, d, N) while not isnatural(a) or not isnatural(b): [a, b, k] = compose([a, b, k], d, N) continue if k.copy_abs() == 2: [a, b, k] = compose(d, d, N) continue m = findm(a, b, k, N) [a, b, k] = [(a * m + N * b) / k.copy_abs(), (a + m * b) / k.copy_abs(), (m ** 2 - N) / k] return a, b, k
class Account: def __init__(self, name: str): self.name = name self.balance = Decimal("0.00") self.transactions = [] def add_transaction_from(self, transaction: Transaction): self.transactions.append(transaction) self.balance -= transaction.amount def add_transaction_to(self, transaction: Transaction): self.transactions.append(transaction) self.balance += transaction.amount def list_all_format(self): minus = "" if self.balance < 0: minus = "- " return "Name: %s. Balance: %s£%s." % (self.name, minus, str(self.balance.copy_abs())) def print_account_transactions(self): print("%s's transactions:" % self.name) for transaction in self.transactions: transaction.print_info() def sort_transactions(self): self.transactions.sort(key=lambda transaction: transaction.date)
def __init__(self, data): # credit transaction if len(data) == 3: self.date = datemaker.makedate(data[0]) self.locn = data[1] self.type = "credit" amt = Decimal(data[2].replace(",", "")) if amt > Decimal('0'): self.fout = amt self.fin = Decimal('0.0') else: self.fout = Decimal('0.0') self.fin = Decimal.copy_abs(amt) #print("CREATING: {}, AMT: {}, FIN: {}, FOUT: {}".format(data[1], data[2], self.fin, self.fout)) # debit transaction elif len(data) == 4: self.date = datetime.strptime(data[0], "%m/%d/%Y") self.locn = data[1] self.type = "debit" if data[2] != '': data[2] = Decimal(data[2]) else: data[2] = Decimal('0.0') self.fout = data[2] if data[3] != '': data[3] = Decimal(data[3]) else: data[3] = Decimal('0.0') self.fin = data[3]
def unit_format(num): if num is None: return '0' elif not isinstance(num, Decimal): num = Decimal(num) abs_val = num.copy_abs() if abs_val >= pow(10, 8): return '%s亿' % cut_format(div(num, pow(10, 8))) elif abs_val >= pow(10, 4): return '%s万' % cut_format(div(num, pow(10, 4))) else: return '%s' % cut_format(num)
def parse_from_csv(year=2019): csv_in = csv.DictReader(find_csv_file(get_input_folder('activity')).open(), fieldnames=[DispositionFieldIds.statement_type, DispositionFieldIds.row_type]) currency_rates = currency_parser.parse_currencies(year, currency_parser.CurrencyTimeFrame.DAILY) dispositions_by_ticker = {} decimal.getcontext().prec = 9 header_read = False for row in csv_in: statement_type = row.get(DispositionFieldIds.statement_type) if statement_type == 'Trades': if row.get(DispositionFieldIds.row_type) == 'Header' and not header_read: csv_in.fieldnames += row.get(None) header_read = True elif row.get(DispositionFieldIds.row_type) == 'Data' and 'Forex' not in row.get(DispositionFieldIds.asset): profit = Decimal(row.get(DispositionFieldIds.profit)) if profit != 0: timestamp = date.fromisoformat(row.get(DispositionFieldIds.datetime).split(',')[0]) currency = row.get(DispositionFieldIds.currency) if timestamp.year != year: continue while not currency_rates[currency].get(timestamp): timestamp -= timedelta(days=1) amount = Decimal(row.get(DispositionFieldIds.amount)) if amount < 0: amount = amount.copy_abs() amount_in_base_currency = amount / currency_rates[currency][timestamp] profit_in_base_currency = profit / currency_rates[currency][timestamp] ticker = row.get(DispositionFieldIds.ticker) if ticker in dispositions_by_ticker: dispositions = dispositions_by_ticker[ticker] else: dispositions = Dispositions(ticker) dispositions_by_ticker[ticker] = dispositions dispositions.add_disposition(amount_in_base_currency, profit_in_base_currency) sum_of_amounts = Decimal() sum_of_profits = Decimal() for dispositions in dispositions_by_ticker.values(): sum_of_amounts += dispositions.amount sum_of_profits += dispositions.profits + dispositions.losses print(dispositions) print('\nTotal sum of dispositions', sum_of_amounts, '€ with profits amounting to', sum_of_profits, '€') return dispositions_by_ticker
def _view_balances(self, session): # Money that the user needs back all_due = defaultdict(lambda: Decimal("0.00")) # Money that the user needs to give back all_owed = defaultdict(lambda: Decimal("0.00")) # All the times the user covered someone for transaction in Cover.objects.filter( transaction_payer=session.user): all_due[transaction.user.buy_index] += transaction.amount # All the times the user was covered by someone for transaction in Cover.objects.filter(user=session.user): all_owed[ transaction.transaction_payer.buy_index] += transaction.amount # All the times the user was paid back for transaction in Payment.objects.filter( transaction_payer=session.user): all_due[transaction.user.buy_index] -= transaction.amount # All the times the user paid someone back for transaction in Payment.objects.filter(user=session.user): all_owed[ transaction.transaction_payer.buy_index] -= transaction.amount # The net money the user needs back net_due = {} # The net money that the user needs to give back net_owed = {} for user in User.objects.exclude(buy_index=session.user.buy_index): net_total = all_due[user.buy_index] - all_owed[user.buy_index] if net_total < 0: net_owed[str(user.buy_index)] = str( Decimal.copy_abs(net_total)) elif net_total > 0: net_due[str(user.buy_index)] = str(net_total) self._respond( session.uuid, { "type": "balances", "net_due": net_due if len(net_due) > 0 else None, "net_owed": net_owed if len(net_owed) > 0 else None, })
def transactions_by_account(fileobj): account_name = fileobj.readline().rstrip('\n') balance = Decimal(fileobj.readline().rstrip('\n')) result = [] lines = list(csv.reader(fileobj))[1:] for date, transaction_type, description, _, signed_amount_str in lines: signed_amount = Decimal(signed_amount_str.replace(',', '')) frm, to = '', account_name if signed_amount > 0: assert transaction_type == 'CREDIT' else: assert signed_amount < 0 assert transaction_type == 'DEBIT' frm, to = to, frm month, day, year = map(int, date.split('/')) result.append( schema.Transaction(frm, to, schema.Date(year, month, day), description, signed_amount.copy_abs())) correct_balance(account_name, balance, result) return {account_name: result}
class FVal(): """A value to represent numbers for financial applications. At the moment we use the python Decimal library but the abstraction will help us change the underlying implementation if needed. At the moment we do not allow any operations against floating points. Even though floating points could be converted to Decimals before each operation we will use this restriction to make sure floating point numbers are rooted from the codebase first. """ __slots__ = ('num',) def __init__(self, data: AcceptableFValInitInput = 0): try: if isinstance(data, float): self.num = Decimal(str(data)) elif isinstance(data, bytes): # assume it's an ascii string and try to decode the bytes to one self.num = Decimal(data.decode()) elif isinstance(data, bool): # type: ignore # This elif has to come before the isinstance(int) check due to # https://stackoverflow.com/questions/37888620/comparing-boolean-and-int-using-isinstance raise ValueError('Invalid type bool for data given to FVal constructor') elif isinstance(data, (Decimal, int, str)): self.num = Decimal(data) elif isinstance(data, FVal): self.num = data.num else: raise ValueError(f'Invalid type {type(data)} of data given to FVal constructor') except InvalidOperation as e: raise ValueError( 'Expected string, int, float, or Decimal to initialize an FVal.' 'Found {}.'.format(type(data)), ) from e def __str__(self) -> str: return str(self.num) def __repr__(self) -> str: return 'FVal({})'.format(str(self.num)) def __gt__(self, other: AcceptableFValOtherInput) -> bool: evaluated_other = evaluate_input(other) return self.num.compare_signal(evaluated_other) == Decimal('1') def __lt__(self, other: AcceptableFValOtherInput) -> bool: evaluated_other = evaluate_input(other) return self.num.compare_signal(evaluated_other) == Decimal('-1') def __le__(self, other: AcceptableFValOtherInput) -> bool: evaluated_other = evaluate_input(other) return self.num.compare_signal(evaluated_other) in (Decimal('-1'), Decimal('0')) def __ge__(self, other: AcceptableFValOtherInput) -> bool: evaluated_other = evaluate_input(other) return self.num.compare_signal(evaluated_other) in (Decimal('1'), Decimal('0')) def __eq__(self, other: object) -> bool: evaluated_other = evaluate_input(other) return self.num.compare_signal(evaluated_other) == Decimal('0') def __add__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__add__(evaluated_other)) def __sub__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__sub__(evaluated_other)) def __mul__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__mul__(evaluated_other)) def __truediv__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__truediv__(evaluated_other)) def __floordiv__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__floordiv__(evaluated_other)) def __pow__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__pow__(evaluated_other)) def __radd__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__radd__(evaluated_other)) def __rsub__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__rsub__(evaluated_other)) def __rmul__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__rmul__(evaluated_other)) def __rtruediv__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__rtruediv__(evaluated_other)) def __rfloordiv__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__rfloordiv__(evaluated_other)) def __mod__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__mod__(evaluated_other)) def __rmod__(self, other: AcceptableFValOtherInput) -> 'FVal': evaluated_other = evaluate_input(other) return FVal(self.num.__rmod__(evaluated_other)) def __float__(self) -> float: return float(self.num) # --- Unary operands def __neg__(self) -> 'FVal': return FVal(self.num.__neg__()) def __abs__(self) -> 'FVal': return FVal(self.num.copy_abs()) # --- Other operations def fma(self, other: AcceptableFValOtherInput, third: AcceptableFValOtherInput) -> 'FVal': """ Fused multiply-add. Return self*other+third with no rounding of the intermediate product self*other """ evaluated_other = evaluate_input(other) evaluated_third = evaluate_input(third) return FVal(self.num.fma(evaluated_other, evaluated_third)) def to_percentage(self, precision: int = 4, with_perc_sign: bool = True) -> str: return f'{self.num*100:.{precision}f}{"%" if with_perc_sign else ""}' def to_int(self, exact: bool) -> int: """ Tries to convert to int, If `exact` is true then it will convert only if it is a whole decimal number; i.e.: if it has got nothing after the decimal point Raises: ConversionError: If exact was True but the FVal is actually not an exact integer. """ if exact and self.num.to_integral_exact() != self.num: raise ConversionError(f'Tried to ask for exact int from {self.num}') return int(self.num) def is_close(self, other: AcceptableFValInitInput, max_diff: str = "1e-6") -> bool: evaluated_max_diff = FVal(max_diff) if not isinstance(other, FVal): other = FVal(other) diff_num = abs(self.num - other.num) return diff_num <= evaluated_max_diff.num
class FVal(object): """A value to represent numbers for financial applications. At the moment we use the python Decimal library but the abstraction will help us change the underlying implementation if needed. At the moment we do not allow any operations against floating points. Even though floating points could be converted to Decimals before each operation we will use this restriction to make sure floating point numbers are rooted from the codebase first. """ __slots__ = ('num',) def __init__(self, data): try: if isinstance(data, float): self.num = Decimal(str(data)) elif isinstance(data, bytes): # assume it's an ascii string and try to decode the bytes to one self.num = Decimal(data.decode()) elif isinstance(data, (Decimal, int, str)): self.num = Decimal(data) elif isinstance(data, FVal): self.num = data.num else: self.num = None except InvalidOperation: self.num = None if not self.num: raise ValueError( 'Expected string, int, float, or Decimal to initialize an FVal.' 'Found {}.'.format(type(data)) ) def __str__(self): return str(self.num) def __repr__(self): return 'FVal({})'.format(str(self.num)) def __gt__(self, other): other = evaluate_input(other) return self.num.compare_signal(other) == Decimal('1') def __lt__(self, other): other = evaluate_input(other) return self.num.compare_signal(other) == Decimal('-1') def __le__(self, other): other = evaluate_input(other) return self.num.compare_signal(other) in (Decimal('-1'), Decimal('0')) def __ge__(self, other): other = evaluate_input(other) return self.num.compare_signal(other) in (Decimal('1'), Decimal('0')) def __eq__(self, other): other = evaluate_input(other) return self.num.compare_signal(other) == Decimal('0') def __add__(self, other): other = evaluate_input(other) return FVal(self.num.__add__(other)) def __sub__(self, other): other = evaluate_input(other) return FVal(self.num.__sub__(other)) def __mul__(self, other): other = evaluate_input(other) return FVal(self.num.__mul__(other)) def __truediv__(self, other): other = evaluate_input(other) return FVal(self.num.__truediv__(other)) def __floordiv__(self, other): other = evaluate_input(other) return FVal(self.num.__floordiv__(other)) def __pow__(self, other): other = evaluate_input(other) return FVal(self.num.__pow__(other)) def __radd__(self, other): other = evaluate_input(other) return FVal(self.num.__radd__(other)) def __rsub__(self, other): other = evaluate_input(other) return FVal(self.num.__rsub__(other)) def __rmul__(self, other): other = evaluate_input(other) return FVal(self.num.__rmul__(other)) def __rtruediv__(self, other): other = evaluate_input(other) return FVal(self.num.__rtruediv__(other)) def __rfloordiv__(self, other): other = evaluate_input(other) return FVal(self.num.__rfloordiv__(other)) def __float__(self): return float(self.num) # --- Unary operands def __neg__(self): return FVal(self.num.__neg__()) def __abs__(self): return FVal(self.num.copy_abs()) # --- Other oparations def fma(self, other, third): """ Fused multiply-add. Return self*other+third with no rounding of the intermediate product self*other """ other = evaluate_input(other) third = evaluate_input(third) return FVal(self.num.fma(other, third)) def to_percentage(self): return '{:.5%}'.format(self.num) def to_int(self, exact): """Tries to convert to int, If `exact` is true then it will convert only if it is a whole decimal number; i.e.: if it has got nothing after the decimal point""" if exact and self.num.to_integral_exact() != self.num: raise ValueError('Tried to ask for exact int from {}'.format(self.num)) return int(self.num) def is_close(self, other, max_diff="1e-6"): max_diff = FVal(max_diff) if not isinstance(other, FVal): other = FVal(other) diff_num = abs(self.num - other.num) return diff_num <= max_diff.num
class Duration(AnyAtomicType): """ Base class for the XSD duration types. :param months: an integer value that represents years and months. :param seconds: a decimal or an integer instance that represents \ days, hours, minutes, seconds and fractions of seconds. """ name = 'duration' pattern = re.compile( r'^(-)?P(?=(?:[0-9]|T))(?:([0-9]+)Y)?(?:([0-9]+)M)?(?:([0-9]+)D)?' r'(?:T(?=[0-9])(?:([0-9]+)H)?(?:([0-9]+)M)?(?:([0-9]+(?:\.[0-9]+)?)S)?)?$' ) def __init__(self, months: int = 0, seconds: Union[Decimal, int] = 0): if seconds < 0 < months or months < 0 < seconds: raise ValueError('signs differ: (months=%d, seconds=%d)' % (months, seconds)) elif abs(months) > 2**31: raise OverflowError("months duration overflow") elif abs(seconds) > 2**63: raise OverflowError("seconds duration overflow") self.months = months self.seconds = Decimal(seconds).quantize(Decimal('1.000000')) def __repr__(self): return '{}(months={!r}, seconds={})'.format( self.__class__.__name__, self.months, normalized_seconds(self.seconds)) def __str__(self): m = abs(self.months) years, months = m // 12, m % 12 s = self.seconds.copy_abs() days = int(s // 86400) hours = int(s // 3600 % 24) minutes = int(s // 60 % 60) seconds = s % 60 value = '-P' if self.sign else 'P' if years or months or days: if years: value += '%dY' % years if months: value += '%dM' % months if days: value += '%dD' % days if hours or minutes or seconds: value += 'T' if hours: value += '%dH' % hours if minutes: value += '%dM' % minutes if seconds: value += '%sS' % normalized_seconds(seconds) elif value[-1] == 'P': value += 'T0S' return value @classmethod def fromstring(cls, text): """ Creates a Duration instance from a formatted XSD duration string. :param text: an ISO 8601 representation without week fragment and an optional decimal part \ only for seconds fragment. """ if not isinstance(text, str): msg = 'argument has an invalid type {!r}' raise TypeError(msg.format(type(text))) match = cls.pattern.match(text.strip()) if match is None: raise ValueError('%r is not an xs:duration value' % text) sign, years, months, days, hours, minutes, seconds = match.groups() seconds = Decimal(seconds or 0) minutes = int(minutes or 0) + int(seconds // 60) seconds = seconds % 60 hours = int(hours or 0) + minutes // 60 minutes = minutes % 60 days = int(days or 0) + hours // 24 hours = hours % 24 months = int(months or 0) + 12 * int(years or 0) if sign is None: seconds = seconds + (days * 24 + hours) * 3600 + minutes * 60 else: months = -months seconds = -seconds - (days * 24 + hours) * 3600 - minutes * 60 if cls is DayTimeDuration: if months: raise ValueError('months must be 0 for %r' % cls.__name__) return cls(seconds=seconds) elif cls is YearMonthDuration: if seconds: raise ValueError('seconds must be 0 for %r' % cls.__name__) return cls(months=months) return cls(months=months, seconds=seconds) @property def sign(self): return '-' if self.months < 0 or self.seconds < 0 else '' def _compare_durations(self, other, op): """ Ordering is defined through comparison of four datetime.datetime values. Ref: https://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/#duration """ if not isinstance(other, self.__class__): raise TypeError("wrong type %r for operand %r" % (type(other), other)) m1, s1 = self.months, int(self.seconds) m2, s2 = other.months, int(other.seconds) ms1, ms2 = int((self.seconds - s1) * 1000000), int( (other.seconds - s2) * 1000000) return all([ op(datetime.timedelta(months2days(1696, 9, m1), s1, ms1), datetime.timedelta(months2days(1696, 9, m2), s2, ms2)), op(datetime.timedelta(months2days(1697, 2, m1), s1, ms1), datetime.timedelta(months2days(1697, 2, m2), s2, ms2)), op(datetime.timedelta(months2days(1903, 3, m1), s1, ms1), datetime.timedelta(months2days(1903, 3, m2), s2, ms2)), op(datetime.timedelta(months2days(1903, 7, m1), s1, ms1), datetime.timedelta(months2days(1903, 7, m2), s2, ms2)), ]) def __hash__(self): return hash((self.months, self.seconds)) def __eq__(self, other): if isinstance(other, self.__class__): return self.months == other.months and self.seconds == other.seconds elif isinstance(other, UntypedAtomic): return self.__eq__(self.fromstring(other.value)) else: return other == (self.months, self.seconds) def __ne__(self, other): if isinstance(other, self.__class__): return self.months != other.months or self.seconds != other.seconds elif isinstance(other, UntypedAtomic): return self.__ne__(self.fromstring(other.value)) else: return other != (self.months, self.seconds) def __lt__(self, other): return self._compare_durations(other, operator.lt) def __le__(self, other): return self == other or self._compare_durations(other, operator.le) def __gt__(self, other): return self._compare_durations(other, operator.gt) def __ge__(self, other): return self == other or self._compare_durations(other, operator.ge)
# print set3 # # # 添加元素 # set1.add(4) # print set1 # # # 删除元素 # set1.remove(4) # print set1 # # # 定义字符元素类型的集合 # set1 = {'sd', 'fds'} # set2 = {'sd', 'fds', 'fds'} # print set1, set2 # # # 定义浮点类型的集合 # set1 = {2.1, 4.3} # print set1 # # # 定义bool类型变量 # bool1 = True # bool2 = False # # # 定义Decimal类型变量,需要导入decimal.Decimal dec = Decimal("-1.0") print dec.copy_abs() print dec.to_integral_value() # # # fra = Fraction(1, 3) # # fra.
# -*- coding: utf-8 -*- ''' Created on 18 de ene. de 2016 @author: dam2 ''' from decimal import Decimal fNuml = 3.34 # float o reales usa doble precision INuml = 3L # Entero largo como long de C dNuml = Decimal(fNuml) # La mayor precision posible print " Funciones basicas " print dNuml.copy_abs() print dNuml.is_infinite() print dNuml.log10() print dNuml.sqrt() print dNuml.max(INuml) print fNuml.hex() # representacion hexadecimal print INuml.bit_length() # bits necesarios para representar el valor
def _ticker(self, irc, ticker): prev = dict() while True: if self.stop: return try: log.debug("refreshing ticker %r", ticker) data = dict() for key, url in TICKERS[ticker]["urls"].iteritems(): log.debug("fetching url %r", url) try: t0 = time.time() data[key] = json.load(urllib2.urlopen(url, timeout=30)) except Exception, e: log.exception("error fetching %r", url) continue log.info("fetched %r in %.2f s", url, time.time() - t0) log.debug("data = %r", data[key]) if not data: raise Exception("no data for ticker %s" % repr(ticker)) for output, o in TICKERS[ticker]["outputs"].iteritems(): log.debug("processing output %r: %r", output, o) values = [] diffstring = "" report = False for metric, m in o["metrics"].iteritems(): value = d(getvalue(data, m[1:])).quantize(m[0]) if metric == "volume": # volume is in base units currency = o["unit"] else: # others are in currency currency = o["currency"] log.debug("output %r metric %r has value %r", output, metric, value) if metric in o["reportchange"]: if output + metric in prev: vdiff = value - prev[output + metric] else: vdiff = Decimal(0) prev[output + metric] = value report = True if vdiff.copy_abs() >= o["reportchange"][metric]: log.debug( "output %r metric %r value diff %r exceeds %r, reporting change", output, metric, vdiff.copy_abs(), o["reportchange"][metric], ) prev[output + metric] = value report = True values.append("%12s %-3s" % (value, currency)) diffstring = updown(vdiff) else: values.append("%12s %-3s" % (value, currency)) diffstring = updown( vdiff, "(%s%s %s)" % ("-" if vdiff.is_signed() else "+", vdiff.copy_abs(), currency) ) out = "%s %s %s %s" % ( "[" + TICKERS[ticker]["label"] + "]", currencycolor(o["unit"]), " ".join(values), diffstring, ) if report: for chan in self.registryValue("channels"): irc.queueMsg(ircmsgs.privmsg(chan, ircutils.bold(out))) except Exception, e: log.exception("in ticker thread %r", ticker)
def copy_abs(x: Decimal) -> Decimal: return x.copy_abs()
adjusted() return the adjusted exponent as_integer_ratio() return a pair (n, d) of integers that represent the given Decimal instance as a fraction as_tuple() return a named tuple DecimalTuple(sign, digits, exponent) copy_abs() return the absolute value of the argument copy_sign(other) return a copy of the first operand with the sign set to be the same as other exp() return the value of the (natural) exponential function e**x at the given number quantize(exp, rounding=None) round a number to a fixed exponent Rounding modes decimal.ROUND_CEILING round towards Infinity decimal.ROUND_FLOOR round towards -Infinity decimal.ROUND_UP round away from zero decimal.ROUND_DOWN round towards zero decimal.ROUND_HALF_UP round to nearest with ties going away from zero. decimal.ROUND_HALF_DOWN round to nearest with ties going towards zero decimal.ROUND_HALF_EVEN round to nearest with ties going to nearest even integer """ import decimal from decimal import Decimal a = Decimal(-139) + Decimal('-2e-5') + Decimal('1.53') print(a) print(a.adjusted()) # the position of the most significant digit with respect to the decimal point print(a.as_integer_ratio()) print(a.as_tuple()) # sign 0 for positive or 1 for negative print(a.copy_abs(), a.quantize(Decimal('1.000'), rounding=decimal.ROUND_UP)) b = Decimal(15) print(a, b, a + b, a - b, a * b, a / b)
def _ticker(self, irc, ticker): prev = dict() while True: if self.stop: return try: log.debug("refreshing ticker %r", ticker) data = dict() for key, url in TICKERS[ticker]['urls'].iteritems(): log.debug("fetching url %r", url) try: t0 = time.time() data[key] = json.load(urllib2.urlopen(url, timeout=30)) except Exception, e: log.exception("error fetching %r", url) continue log.info("fetched %r in %.2f s", url, time.time() - t0) log.debug("data = %r", data[key]) if not data: raise Exception("no data for ticker %s" % repr(ticker)) for output, o in TICKERS[ticker]['outputs'].iteritems(): log.debug("processing output %r: %r", output, o) values = [] diffstring = '' report = False low = high = None for metric, m in o['metrics'].iteritems(): value = d(getvalue(data, m[1:])).quantize(m[0]) if metric == 'volume': # volume is in base units currency = o['unit'] else: # others are in currency currency = o['currency'] log.debug("output %r metric %r has value %r", output, metric, value) if metric in o['reportchange']: if output+metric in prev: vdiff = value - prev[output+metric] else: vdiff = Decimal(0) prev[output+metric] = value report = True if vdiff.copy_abs() >= o['reportchange'][metric]: log.debug("output %r metric %r value diff %r exceeds %r, reporting change", output, metric, vdiff.copy_abs(), o['reportchange'][metric]) prev[output+metric] = value report = True values.append("%12s %-3s" % ( value, currency)) diffstring = updown(vdiff) else: values.append("%12s %-3s" % ( value, currency)) if low is None or value < low: low = value if high is None or value > high: high = value diffstring=updown(vdiff, '(%s%s %s)' % ( '-' if vdiff.is_signed() else '+', vdiff.copy_abs(), currency)) out = "%s %s %s %s" % ( '['+TICKERS[ticker]['label']+']', currencycolor(o['unit']), " ".join(values), diffstring) if report: for chan in self.registryValue('channels'): irc.queueMsg(ircmsgs.privmsg(chan, ircutils.bold(out))) nicks = self.lowvalues.keys() for nick in nicks: user_value = self.lowvalues[nick] if low is not None and low <= user_value: out = "%s: OMG, it went below %s to %s!" % (nick, user_value, low) irc.queueMsg(ircmsgs.privmsg(chan, ircutils.bold(out))) del self.lowvalues[nick] nicks = self.highvalues.keys() for nick in nicks: user_value = self.highvalues[nick] if high is not None and high >= user_value: out = "%s: OMG, it went above %s to %s!" % (nick, user_value, high) irc.queueMsg(ircmsgs.privmsg(chan, ircutils.bold(out))) del self.highvalues[nick] except Exception, e: log.exception("in ticker thread %r", ticker)