首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将硬币分成不同面额的组合

将硬币分成不同面额的组合
EN

Code Review用户
提问于 2019-04-24 15:46:46
回答 3查看 992关注 0票数 7

我有三种硬币:金,银,铜。

1银= 100铜。

1金= 100银。

我的输入总是用铜版,我想让它更易读。到目前为止,我的代码是:

代码语言:javascript
复制
def api_wallet_translate_gold(value):
    """Translate a value into string of money"""
    if value >= 10000:  # Gold
        return ("{0} gold, {1} silver and {2} copper."
                .format(str(value)[:-4], str(value)[-4:-2], str(value)[-2:]))
    elif value >= 100:  # Silver
        return "{0} silver and {1} copper.".format(str(value)[-4:-2], str(value)[-2:])
    else:  # Copper
        return "{0} copper.".format(str(value)[-2:])

它起作用了,但我想知道如何改进它。我认为有一种方法可以将其格式化为{xx:2:2}或其他什么东西,但我不记得该如何做。

注:我们永远不知道我们有多少黄金数字,可能是999999比1。

EN

回答 3

Code Review用户

回答已采纳

发布于 2019-04-24 15:58:36

如果你直接处理数字,而不是转换成字符串,它可能就不那么脆弱了。它也将是更干净的代码。

您可以从从最高到最低排序列表中的值开始。然后,在您的函数中,您可以找到下一个最大的值,并保留在divmod()中。之后,您需要决定如何格式化生成的dict:

代码语言:javascript
复制
coins = [
    ("gold",  100 * 100),
    ("silver", 100), 
    ("copper", 1)
]

def translate_coins(value, coins):
    res = {}
    for coin, v in coins:
        res[coin], value = divmod(value, v)
    return res 

translate_coins(1013323, coins)

结果:

代码语言:javascript
复制
{'gold': 101, 'silver': 33, 'copper': 23}
票数 10
EN

Code Review用户

发布于 2019-04-25 01:11:18

这是一个很好的休息,可以问这个问题:-)我认为这是对象/类和方法的一个很好的用例。

我会创建一个货币类,然后允许您打印它,或者独立地访问它的属性.

代码语言:javascript
复制
class Currency(object):

    COPPER_CONVERSION_MAP = {
        'copper': 1,
        'gold': 100 * 100,
        'silver': 100
    }
    gold = 0
    silver = 0
    copper = 0

    def __init__(self, copper=0, silver=0, gold=0):
        # convert all inputs into copper
        self.copper = (
            copper +
            silver * self.COPPER_CONVERSION_MAP['silver'] +
            gold * self.COPPER_CONVERSION_MAP['gold']
          )
        self.break_currency()

    def break_currency(self):
        for coin_type in ['gold', 'silver']:
            coins, coppers = divmod(self.copper, self.COPPER_CONVERSION_MAP[coin_type])
            setattr(self, coin_type, coins)
            self.copper = coppers

    def __str__(self):
        return '{:,} gold, {:,} silver and {:,} copper'.format(self.gold, self.silver, self.copper)

然后,您可以这样消费:

代码语言:javascript
复制
>>> c = Currency(copper=653751735176)
>>> str(c)
'65,375,173 gold, 51 silver and 76 copper'
>>> c.copper
76
>>> c.silver
51
>>> c.gold
65375173
票数 3
EN

Code Review用户

发布于 2019-04-25 06:37:49

另一种可能是使用namedtuple来存放硬币。

代码语言:javascript
复制
from collections import namedtuple

class Currency(namedtuple("Currency", "gold silver copper")):

    def __new__(cls, copper):
        gold, copper = divmod(copper, 10000)
        silver, copper = divmod(copper, 100)
        return super().__new__(cls, gold, silver, copper)

    def __str__(self):
        return "{} gold, {} silver, {} copper".format(*self)

c = Currency(1234567)

print(c)

在这里,我对转换进行了硬编码,但这可以很容易地适应金银和铜币之间的可变汇率,类似于其他答案。

命名元组的好处是可以获得单个钱币数:

代码语言:javascript
复制
print(c.gold, c.silver, c.copper)

由于我们现在有了一个用于Currency对象的类,所以可以添加基本的算术运算符,因此如果需要的话,可以简洁地表示操作。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/219029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档