2

アカウントと代金引換の取引を処理するシステムを持っています。クライアントが代金引換で支払う場合、セントを切り上げるか切り捨てる必要があります。

Eg.
Total = 64.42 - rounds to: 64.40
Total = 64.57 - rounds to 64.60

私はこれをPythonで行う最良の方法を見つけようとしており、データベースの10進数フィールドにも差を保存しています。

ジャンゴを使っています。10 進数の ROUND_05UP 部分を使用しようとしていましたが、その方法がわかりません。それを表示するカスタム フィルターを作成しましたが、機能していません。

@register.filter
def currency(value, arg='en_US', symbol=True):

    saved = '.'.join([x for x in locale.getlocale() if x]) or (None, None)
    given = arg and ('.' in arg and str(arg) or str(arg) + '.UTF-8')

    # Workaround for Python bug 1699853 and other possibly related bugs.
    if '.' in saved and saved.split('.')[1].lower() in ('utf', 'utf8'):
        saved = saved.split('.')[0] + '.UTF-8'

    if saved == (None, None) and given == '':
        given = 'en_US.UTF-8'

    try:
        locale.setlocale(locale.LC_ALL, given)

        return locale.currency(value or 0, symbol, True)

    except (TypeError, locale.Error):
        return ''

    finally:
        locale.setlocale(locale.LC_ALL, saved)


@register.filter
def currency_cash(value):
    value = decimal.Decimal(value)
    return currency(value.quantize(Decimal(10) ** -2, rounding=decimal.ROUND_05UP))

これを行う関数を書いた人はいますか?

更新:この理由は、オーストラリアでは 5 セント未満の硬貨がないからです。したがって、45.55 は 45.55 のままです。

乾杯、ベン

4

3 に答える 3

3

私が正しく理解していれば、入ってくる金額はすでに正確な整数のセントであり、10セントの最も近い倍数に丸めたいだけですが、すでに終わっている値はそのままにしておきます5。あれは正しいですか?これは、 remainder_nearメソッドを使用した簡単なソリューションです。

from decimal import Decimal

def round_to_10_cents(x):
    """
    Round a Decimal value to the nearest multiple of 0.10,
    unless already an exact multiple of 0.05.

    """
    remainder = x.remainder_near(Decimal('0.10'))
    if abs(remainder) == Decimal('0.05'):
        return x
    else:
        return x - remainder


# Test code.
for x in range(80, 120):
    y = Decimal(x) / Decimal('1E2')
    print "{0} rounds to {1}".format(y, round_to_10_cents(y))

サンプル出力:

0.80 rounds to 0.80
0.81 rounds to 0.80
0.82 rounds to 0.80
0.83 rounds to 0.80
0.84 rounds to 0.80
0.85 rounds to 0.85
0.86 rounds to 0.90
0.87 rounds to 0.90
0.88 rounds to 0.90
0.89 rounds to 0.90
0.90 rounds to 0.90
0.91 rounds to 0.90
0.92 rounds to 0.90
0.93 rounds to 0.90
0.94 rounds to 0.90
0.95 rounds to 0.95
0.96 rounds to 1.00
0.97 rounds to 1.00
0.98 rounds to 1.00
0.99 rounds to 1.00
1.00 rounds to 1.00
1.01 rounds to 1.00
1.02 rounds to 1.00
1.03 rounds to 1.00
1.04 rounds to 1.00
1.05 rounds to 1.05
1.06 rounds to 1.10
1.07 rounds to 1.10
1.08 rounds to 1.10
1.09 rounds to 1.10
1.10 rounds to 1.10
1.11 rounds to 1.10
1.12 rounds to 1.10
1.13 rounds to 1.10
1.14 rounds to 1.10
1.15 rounds to 1.15
1.16 rounds to 1.20
1.17 rounds to 1.20
1.18 rounds to 1.20
1.19 rounds to 1.20
于 2012-10-28T10:51:33.187 に答える
3

あなたが話しているこのタイプの丸めは、スウェーデンの丸めと呼ばれます。

  • 1 セントは 0 に切り捨てます
  • 2 セントは 0 に切り捨てます
  • 3 セントは 5 セントに切り上げ
  • 4 セントは 5 セントに切り上げ

等々。

from decimal import Decimal as D, ROUND_HALF_EVEN  # or ROUND_HALF_UP

def round_to_5_cents(d):
    """
    Round a Decimal value to the nearest multiple of 0.05,
    """
    return (d*2).quantize(D('0.1'), ROUND_HALF_EVEN)/D(2)

for x in range(80, 120):
    d = D(x) * D('0.01')
    print "{0} rounds to {1}".format(d, round_to_5_cents(d))

出力例:

0.80 rounds to 0.8
0.81 rounds to 0.8
0.82 rounds to 0.8
0.83 rounds to 0.85
0.84 rounds to 0.85
0.85 rounds to 0.85
0.86 rounds to 0.85
0.87 rounds to 0.85
0.88 rounds to 0.9
0.89 rounds to 0.9
0.90 rounds to 0.9
0.91 rounds to 0.9
0.92 rounds to 0.9
0.93 rounds to 0.95
0.94 rounds to 0.95
0.95 rounds to 0.95
0.96 rounds to 0.95
0.97 rounds to 0.95
0.98 rounds to 1.0
0.99 rounds to 1.0
1.00 rounds to 1.0
1.01 rounds to 1.0
1.02 rounds to 1.0
1.03 rounds to 1.05
1.04 rounds to 1.05
1.05 rounds to 1.05
1.06 rounds to 1.05
1.07 rounds to 1.05
1.08 rounds to 1.1
1.09 rounds to 1.1
1.10 rounds to 1.1
1.11 rounds to 1.1
1.12 rounds to 1.1
1.13 rounds to 1.15
1.14 rounds to 1.15
1.15 rounds to 1.15
1.16 rounds to 1.15
1.17 rounds to 1.15
1.18 rounds to 1.2
1.19 rounds to 1.2

@Mark Dickingsonの答えは別のことをします。丸め誤差の累積が大きくなります。

于 2015-05-12T06:11:58.793 に答える
2

ROUND_05UPに関しては、古い標準に準拠するためだけに追加されたようで、実用的なアプリケーションがまったくないかほとんどありません (特に、丸めに関するウィキペディアの記事にない唯一の python 丸めメソッドです)

于 2015-05-12T10:56:43.730 に答える