class _Amount: def __init__(self, fraction_digits: int, precision: int): self._ctx = Context(prec=precision, rounding=ROUND_HALF_EVEN) self._fraction_digits = fraction_digits self._precision = precision self._quantizer = self._ctx.create_decimal(1).scaleb(-fraction_digits) self._value = self._ctx.create_decimal(0) def deserialize(self, serialized_value): self._value = ( self._ctx.create_decimal(serialized_value) .scaleb(-self._fraction_digits) .quantize(self._quantizer) ) return self def serialize(self) -> int: return int(self._value.scaleb(self._fraction_digits)) def set(self, value: Decimal): self._value = self._ctx.create_decimal(value).quantize(self._quantizer) return self def clone(self): raise NotImplementedError def __str__(self): return str(self._value) def __imul__(self, other): operand = other._value if isinstance(other, Amount) else other value = self._ctx.multiply(self._value, operand) return self.set(value) def __itruediv__(self, other): operand = other._value if isinstance(other, Amount) else other value = self._ctx.divide(self._value, operand) return self.set(value) def __mul__(self, other): return self.clone().__imul__(other) def __truediv__(self, other): return self.clone().__itruediv__(other) def __iadd__(self, other): operand = other._value if isinstance(other, Amount) else other value = self._ctx.add(self._value, operand) return self.set(value) def __add__(self, other): return self.clone().__iadd__(other)
def confine(w, h, req_w, req_h): # reduce longest edge to size if w <= req_w and h <= req_h: return w, h context = Context(prec=17, rounding=ROUND_HALF_EVEN) d_w = context.create_decimal(w) d_req_w = context.create_decimal(req_w) d_h = context.create_decimal(h) d_req_h = context.create_decimal(req_h) scale = context.create_decimal(round(min(d_req_w / d_w, d_req_h / d_h), 17)) return tuple(map(lambda d: (d * scale).to_integral_exact(context=context), [d_w, d_h]))
def gen_doc_freq(self): """ For each term, count how many movies contains this term DF(movie, term) = Total movies / (# of movies with term + 1)\ IDF(movie, term) = log(Df(movie,term)) doc_freq_dict = { term_1: DF(), term_2: ... } :return None """ # Loading term freq since it contains a corpus with k-phrases term_freq = self.search_index.get_term_freq() df_dict = dict() dec_con = Context(prec=6, rounding=ROUND_05UP) for movie in term_freq: # Collapse the dict so that for each movie, we have a set of unique k-phrases movie_alpha = set(y for x in term_freq[movie].values() for y in x.keys()) # For each k-phrase, add it into df_dict as a key # and as a value keep count how many times it appears for term in movie_alpha: df_dict[term] = df_dict[term] + 1 if df_dict.get(term) else 1 # df_dict should be populated with every unique k-phrase and the number movies that contain it # Calculate the IDF() = log(total movies / documents with term + 1) for term in df_dict: dec_df_score = dec_con.create_decimal( log(_d(self.total_movies) / _d(df_dict[term]))) df_dict[term] = str(dec_df_score) self.search_index.set_doc_freq(json.dumps(df_dict))
def floatToString(cls, f: float): ''' Converts the given float to a string, without resorting to the scientific notation ''' ctx = Context() ctx.prec = 32 d1 = ctx.create_decimal(repr(f)) return format(d1, 'f')
def float_to_str(f): ctx = Context() ctx.prec = 50 d1 = ctx.create_decimal(repr(f)) f1 = format(d1, 'f') if f1[::-1][:2][::-1] == '.0': f1 = f1[::-1][2:][::-1] return f1
def test_timepoint(self): """Assert timepoints are saved from the schedule correctly as Decimals and ordered by appt_datetime. """ context = Context(prec=2) self.helper.consent_and_put_on_schedule() self.assertEqual( [obj.timepoint for obj in Appointment.objects.all().order_by('appt_datetime')], [context.create_decimal(n) for n in range(0, 4)])
def round4_float(f): """ Implements the IEEE floating point rounding rules with the "round half even" option when rounding. This means that 1000.5 rounds to 1000 while 1001.5 rounds to 1002. """ from decimal import ROUND_HALF_EVEN, Context prec4_rounder = Context(prec=4, rounding=ROUND_HALF_EVEN) return float(str(prec4_rounder.create_decimal(f)))
def inner_decorator(*a, **kwa): ctx = Context(*args, **kwargs) # Convert any Decimal object in args temp_args = list(a) for i in range(len(temp_args)): arg = temp_args[i] if isinstance(arg, Decimal): temp_args[i] = ctx.create_decimal(arg) a = tuple(temp_args) # Convert any Decimal objects in kwargs for i in kwa: arg = kwa[i] if isinstance(arg, Decimal): kwa[i] = ctx.create_decimal(arg) # Inject the newly created Decimal Context f.__globals__["decimal_ctx"] = ctx return f(*a, **kwa)
def test_timepoint(self): """Assert timepoints are saved from the schedule correctly as Decimals and ordered by appt_datetime. """ context = Context(prec=2) self.helper.consent_and_put_on_schedule() self.assertEqual( [ obj.timepoint for obj in Appointment.objects.all().order_by("appt_datetime") ], [context.create_decimal(n) for n in range(0, 4)], )
class NumberDecimal(ParticularScalar): """Validates value is compatible with :class:`bson.Decimal128`. Useful for financial data that need arbitrary precision. The argument `precision` specifies the number of decimal digits to evaluate. Defaults to 6. The argument `rounding` specifies the kind of rounding to be performed. Valid values are `decimal.ROUND_DOWN`, `decimal.ROUND_HALF_UP`, `decimal.ROUND_HALF_EVEN`, `decimal.ROUND_CEILING`, `decimal.ROUND_FLOOR`, `decimal.ROUND_UP`, `decimal.ROUND_HALF_DOWN`, `decimal.ROUND_05UP`. Defaults to `decimal.ROUND_HALF_DOWN`. """ type = (int, float, Decimal, Decimal128) def __init__( self, precision=None, rounding=ROUND_HALF_DOWN, **kwargs ): super(NumberDecimal, self).__init__(**kwargs) self.precision = precision self.rounding = rounding self._context = Context(prec=34, rounding=rounding) # Max Decimal128 precision if self.precision: self._quantizing = self._context.create_decimal(Decimal(str(10 ** -precision))) def _validate(self, value, **kw): value = super(NumberDecimal, self)._validate(value, **kw) if isinstance(value, Decimal128): value = value.to_decimal() value = self._context.create_decimal(value) if self.precision: value = value.quantize(self._quantizing, rounding=self.rounding) return Decimal128(value)
def _tf(self, term_list): """ turn the list into a dict where key = term and value = tf score :param term_list: list of str :return: dict(key=term:value=tf score) """ # Can use collection.counter, but I want to implement counter tf_scores = dict() dec_con = Context(prec=6, rounding=ROUND_05UP) for x in term_list: if len(x) == 0 or len(x) == 1: continue term = x.lower() tf_scores[term] = tf_scores[term] + 1 if tf_scores.get(term) else 1 for x, y in tf_scores.items(): term = x.lower() tf_scores[term] = "{}".format( dec_con.create_decimal(_d(y) / _d(len(term_list)))) return tf_scores
def gen_tfidf(self): """ For every term, create a dict of movies and their tf-idf score TFIDF(movie, term) = TF(movie, term) * log(DF(movie,term)) tfidf_dict = { term_1: { movie_1: TFIDF(), movie_2: ... }, term_2: ... } :return None """ doc_freq = self.search_index.get_doc_freq() term_freq = self.search_index.get_term_freq() alpha_dict = self.search_index.get_alpha() dec_con = Context(prec=6, rounding=ROUND_05UP) # Create a tfidf_dict to hold each term's tf-idf index of movies it appears in tfidf_dict = dict() for term in doc_freq: tfidf_dict[term] = dict() # Generate the tf-idf score for each movie and place them in the tfidf_dict for movie in term_freq: for alpha in term_freq[movie]: for term in term_freq[movie][alpha]: # we are getting every term's individual score that corresponds to a movie term_tf = _d(term_freq[movie][alpha][term]) term_idf = _d(doc_freq[term]) term_alpha = _d(alpha_dict[alpha]) # generate the term's score for the movie it appears in term_tf_idf = term_tf * term_idf * term_alpha # add this score to a tfidf dict that we can use to rank sum_term_tfidf = _d(tfidf_dict[term][movie]) + term_tf_idf if \ tfidf_dict[term].get(movie) else \ term_tf_idf tfidf_dict[term][movie] = str( dec_con.create_decimal(sum_term_tfidf)) self.search_index.set_tfidf(json.dumps(tfidf_dict))
def _num_to_tuple(self, n, shift=0, max_num_digits=None): """Function to convert any number in it's normalized tuple. Args: n (float or str): Number to be converted. shift (int): Number of digits to be shifted. max_num_digits (int): Max number of digits to keep. Returns: DecimalTuple(sign, digits, exponent): A tuple representing the number. Examples: >>> c = OrderBook() >>> c._num_to_tuple('001') DecimalTuple(sign=0, digits=(1,), exponent=0) >>> c._num_to_tuple('00300.00') DecimalTuple(sign=0, digits=(3,), exponent=2) >>> c._num_to_tuple(008.003) DecimalTuple(sign=0, digits=(8, 0, 0, 3), exponent=-3) >>> c._num_to_tuple('500.43210000', max_num_digits=3) DecimalTuple(sign=0, digits=(5,), exponent=2) >>> c._num_to_tuple(500.43210000, max_num_digits=4, shift=1) DecimalTuple(sign=0, digits=(5, 0, 0, 4), exponent=0) >>> c._num_to_tuple('-00000000.0056000000', max_num_digits=2, shift=4) DecimalTuple(sign=1, digits=(5, 6), exponent=0) >>> c._num_to_tuple('-0000.0058064171659814651465', max_num_digits=1, shift=4) DecimalTuple(sign=1, digits=(6,), exponent=1) """ number = Decimal(str(n)).normalize().as_tuple() l = len(number.digits) max_num_digits = max_num_digits if max_num_digits else l context = Context(prec=max_num_digits, rounding=ROUND_HALF_EVEN) digits_round = context.create_decimal((0, number.digits, -l)).normalize().as_tuple() return Decimal( (number.sign, digits_round.digits, number.exponent+digits_round.exponent+l+shift) ).normalize().as_tuple()
# Decimal precision getcontext().prec = 64 getcontext().Emax = 33 getcontext().Emin = -33 dec_con = getcontext() # Decimal constants dec_zero = dec_con.create_decimal('0E-16') dec_one = dec_con.create_decimal('1.0000000000000000') dec_eps = dec_con.create_decimal('1E-16') dec_qua = dec_con.create_decimal('1E-8') # Reward decimal context rew_con = Context(prec=64, Emax=33, Emin=-33) rew_quant = rew_con.create_decimal('0E-32') # Debug flag debug = True # logger class Logger(object): logger = logging.getLogger('Cryptotrader') @staticmethod def __init__(name, output_dir=None): """ Initialise the logger """ # Logger.logger = logging.getLogger(name) Logger.logger.setLevel(logging.DEBUG)
def float_to_str(inp): context = Context() context.prec = 20 dec = context.create_decimal(repr(inp)) return format(dec, 'f')
def round_places(input_value, prec=4): from decimal import Decimal, ROUND_HALF_EVEN, Context ctx = Context(prec=prec, rounding=ROUND_HALF_EVEN) return float(ctx.create_decimal(input_value))
CurrencyTypeException) CONTEXT = Context(prec=28, rounding='ROUND_HALF_EVEN').copy() currency_euro_zero = Currency(amount=0, alpha_code='EUR') currency_euro_one = Currency(amount=1, alpha_code='EUR') currency_euro_two = Currency(amount=2, alpha_code='EUR') currency_euro_three = Currency(amount=3, alpha_code='EUR') currency_euro_fifteen = Currency(amount=15, alpha_code='EUR') currency_another_euro_one = Currency(amount=1, alpha_code='EUR') currency_another_euro_negative_one = Currency(amount=-1, alpha_code='EUR') currency_euro_negative_one = Currency(amount=-1, alpha_code='EUR') currency_euro_negative_two = Currency(amount=-2, alpha_code='EUR') currency_euro_negative_three = Currency(amount=-3, alpha_code='EUR') currency_usd_one = Currency(amount=1, alpha_code='USD') currency = Currency(amount=CONTEXT.create_decimal(1) / CONTEXT.create_decimal(7), alpha_code='EUR', symbol='€', symbol_ahead=True, symbol_separator='', numeric_code='978', decimal_places=2, decimal_sign=',', grouping_sign='.', convertion='', international=True) def test_currency_default(): """test_currency_default."""