def get_integer_digit(value):
from typepy import TypeConversionError
from typepy.type import RealNumber
float_type = RealNumber(value)
try:
abs_value = abs(float_type.convert())
except TypeConversionError:
raise ValueError(
"the value must be a number: value='{}' type='{}'".format(
value, type(value)))
if abs_value.is_zero():
return 1
try:
return len(str(abs_value.quantize(
Decimal("1."), rounding=decimal.ROUND_DOWN)))
except decimal.InvalidOperation as e:
raise ValueError(e)
python类ROUND_DOWN的实例源码
def __init__(self, min_value=None, max_value=None, force_string=False,
precision=2, rounding=decimal.ROUND_HALF_UP, **kwargs):
"""
:param min_value: Validation rule for the minimum acceptable value.
:param max_value: Validation rule for the maximum acceptable value.
:param force_string: Store as a string.
:param precision: Number of decimal places to store.
:param rounding: The rounding rule from the python decimal library:
- decimal.ROUND_CEILING (towards Infinity)
- decimal.ROUND_DOWN (towards zero)
- decimal.ROUND_FLOOR (towards -Infinity)
- decimal.ROUND_HALF_DOWN (to nearest with ties going towards zero)
- decimal.ROUND_HALF_EVEN (to nearest with ties going to nearest even integer)
- decimal.ROUND_HALF_UP (to nearest with ties going away from zero)
- decimal.ROUND_UP (away from zero)
- decimal.ROUND_05UP (away from zero if last digit after rounding towards zero would have been 0 or 5; otherwise towards zero)
Defaults to: ``decimal.ROUND_HALF_UP``
"""
self.min_value = min_value
self.max_value = max_value
self.force_string = force_string
self.precision = precision
self.rounding = rounding
super(DecimalField, self).__init__(**kwargs)
def cube_root(x):
"""Required because the usual x ^ 1/3 does not work with big integers."""
decimal.getcontext().prec = 2 * len(str(x))
power = decimal.Decimal(1) / decimal.Decimal(3)
x = decimal.Decimal(str(x))
root = x ** power
integer_root = root.quantize(decimal.Decimal('1.'), rounding=decimal.ROUND_DOWN)
return int(integer_root)
# Taken from Hal Finney's summary at https://www.ietf.org/mail-archive/web/openpgp/current/msg00999.html,
def round_quantity(self, quantity: str, rounding=ROUND_DOWN) -> Decimal:
return Decimal(quantity).quantize(self.base_min_size, rounding=rounding)
def get_transfer_tax_for_amount(amount):
return (amount * settings.TRANSFERTAX).quantize(settings.SMALLESTAMOUNT, rounding=decimal.ROUND_DOWN)
def get_weekly_balance_tax_for_amount(amount):
return (amount * settings.WEEKLYBALANCETAX).quantize(settings.SMALLESTAMOUNT, rounding=decimal.ROUND_DOWN)
def get_post_registration_tax_for_amount(amount):
return (amount * settings.POSTTAX).quantize(settings.SMALLESTAMOUNT, rounding=decimal.ROUND_DOWN)
# --------------- ACCOUNT ACCESS ---------------
def elapsed(t0=0.0):
"""get elapsed time from the give time
Returns:
now: the absolute time now
dt_str: elapsed time in string
"""
now = time()
dt = now - t0
dt_sec = Decimal(str(dt)).quantize(Decimal('.0001'), rounding=ROUND_DOWN)
if dt_sec <= 1:
dt_str = str(dt_sec) + ' second'
else:
dt_str = str(dt_sec) + ' seconds'
return now, dt_str
def cpu_total(self):
decimal.getcontext().rounding = decimal.ROUND_DOWN
return int(self.cpu * float(self.cpu_coef))
def ram_total(self):
decimal.getcontext().rounding = decimal.ROUND_DOWN
return int(self.ram * float(self.ram_coef))
def resources(self):
"""Return tuple with total (cpu, ram, disk) resources"""
# We are working with decimal objects and rounding everything down
decimal.getcontext().rounding = decimal.ROUND_DOWN
# The total local disk size should not include backups and snapshots
# TODO: fix ns.size_images and subtract it too
disk_size_total = self.storage.size_total
if self._ns:
disk_size_total -= self._ns.size_backups + self._ns.size_snapshots + self._ns.size_rep_snapshots
return self.cpu * float(self.cpu_coef), self.ram * float(self.ram_coef), disk_size_total
def size_total(self):
# We are working with decimal objects and rounding everything down
decimal.getcontext().rounding = decimal.ROUND_DOWN
return int(int(self.size) * float(self.size_coef))
def func_rounddown(a, places=0):
""" functor for round down with decimal places """
return Decimal(a).quantize(Decimal(10) ** -places, rounding=ROUND_DOWN)
def sync_block(num):
start_time = time.time()
while True:
current_block = RN.getBlock(num)
if not current_block.has_key('result'):
time.sleep(SYNC_TIME_GAP)
else:
break
mongo_block = {}
mongo_block['_id'] = num
mongo_block['previousblockhash'] = current_block['result']['previousblockhash'][-64:]
mongo_block['index'] = current_block['result']['index']
mongo_block['hash'] = current_block['result']['hash'][-64:]
mongo_block['time'] = current_block['result']['time']
trs = current_block['result']['tx']
mongo_block['tx'] = []
#sync address
for tr in trs:
sync_address(tr)
#sync claim
for tr in trs:
sync_claim(tr, num)
#sync transactions
sys_fee = D('0')
for i in get_fixed_slice(trs, GEVENT_MAX):
threads = []
for j in i:
sys_fee += D(j['sys_fee']).quantize(D('1'),rounding=ROUND_DOWN)
mongo_block['tx'].append(j['txid'][-64:])
threads.append(gevent.spawn(sync_transaction, j))
gevent.joinall(threads)
if num:
mongo_block['sys_fee'] = str(sys_fee + D(DB.blocks.find_one({'_id':num-1})['sys_fee']))
else:
mongo_block['sys_fee'] = str(sys_fee)
try:
result = DB.blocks.insert_one(mongo_block)
print '->', num, 'at %f seconds, %s' % (time.time() - start_time, datetime.datetime.now())
except DuplicateKeyError:
print 'duplicate block %s' % num
def get_total_cost(self):
total_cost = Decimal()
for entry in self.entries.iterator():
try:
if entry.task.hourly_rate:
total_cost += (
duration_decimal(entry.duration)
* entry.task.hourly_rate
)
except: # noqa: E722
continue
return total_cost.quantize(Decimal('.01'), rounding=ROUND_DOWN)
def clamp_amount(amount):
"""
Round the amount to integer pence,
rounding fractional pence up (away from zero) for any fractional pence value
that is greater than or equal to a tenth of a penny.
@param amount: Decimal amount to round
"""
tenths_of_pennies = (amount * Decimal('1000')).to_integral_value(rounding=ROUND_DOWN)
pounds = tenths_of_pennies / Decimal('1000')
return pounds.quantize(Decimal('1.00'), rounding=ROUND_UP)
def average_per_day(self):
days = monthrange(date.today().year, date.today().month)[1]
return (self.amount.amount/days).quantize(Decimal('.01'), rounding=ROUND_DOWN)
def left_average_per_day(self):
days = monthrange(date.today().year, date.today().month)[1]
rest_days = days - date.today().day + 1 # we need to take into account spendings for today
return (self.left/rest_days).quantize(Decimal('.01'), rounding=ROUND_DOWN)
def allocate_cost_by_value(self):
pool = Pool()
Currency = pool.get('currency.currency')
Move = pool.get('stock.move')
if not self.cost:
return
cost = Currency.compute(self.cost_currency, self.cost,
self.company.currency, round=False)
moves = [m for m in self.incoming_moves
if m.state not in ('done', 'cancel')]
sum_value = 0
unit_prices = {}
for move in moves:
unit_price = Currency.compute(move.currency, move.unit_price,
self.company.currency, round=False)
unit_prices[move.id] = unit_price
sum_value += unit_price * Decimal(str(move.quantity))
costs = []
digit = Move.unit_price.digits[1]
exp = Decimal(str(10.0 ** -digit))
difference = cost
for move in moves:
quantity = Decimal(str(move.quantity))
if not sum_value:
move_cost = cost / Decimal(len(moves))
else:
move_cost = cost * quantity * unit_prices[move.id] / sum_value
unit_shipment_cost = (move_cost / quantity).quantize(exp,
rounding=ROUND_DOWN)
costs.append({
'unit_shipment_cost': unit_shipment_cost,
'difference': move_cost - (unit_shipment_cost * quantity),
'move': move,
})
difference -= unit_shipment_cost * quantity
costs.sort(key=itemgetter('difference'))
for cost in costs:
move = cost['move']
quantity = Decimal(str(move.quantity))
if exp * quantity < difference:
cost['unit_shipment_cost'] += exp
difference -= exp * quantity
if difference < exp:
break
for cost in costs:
move = cost['move']
unit_shipment_cost = Currency.compute(
self.company.currency, cost['unit_shipment_cost'],
move.currency, round=False)
unit_shipment_cost = unit_shipment_cost.quantize(
exp, rounding=ROUND_HALF_EVEN)
move.unit_price += unit_shipment_cost
move.unit_shipment_cost = unit_shipment_cost
Move.save(moves)