为了账号安全,请及时绑定邮箱和手机立即绑定

如何更改我的代码以与此单元测试兼容?

如何更改我的代码以与此单元测试兼容?

ibeautiful 2022-07-05 17:38:46
我正在 Exercism 网站上进行一项练习,并且我已经编写了程序,但它没有通过 Exercism 对其进行的一项测试。不过,我不太清楚我需要做什么来修复它。这是我的代码:import randomABILITIES = ['strength', 'dexterity', 'constitution',             'intelligence', 'wisdom', 'charisma']class Character:    def __init__(self):        for ability in ABILITIES:            setattr(self, ability, roll_ability())        self.hitpoints = 10 + modifier(self.constitution)def modifier(constitution):    return (constitution - 10) // 2def roll_ability(dice=4, sides=6):    rolls = []    for die in range(dice):        rolls.append(random.randint(1, sides))    rolls.remove(min(rolls))    return sum(rolls)这是测试文件中失败的代码:def test_random_ability_is_within_range(self):        score = Character().ability()        self.assertIs(score >= 3 and score <= 18, True)这是失败消息:________________________________ DndCharacterTest.test_random_ability_is_within_range _________________________________self = <dnd_character_test.DndCharacterTest testMethod=test_random_ability_is_within_range>    def test_random_ability_is_within_range(self):>       score = Character().ability()E       AttributeError: 'Character' object has no attribute 'ability'dnd_character_test.py:58: AttributeError我想我需要一个名为“能力”的对象属性?但它有什么作用?我不喜欢必须如此专门地编写程序才能通过单元测试!我想我需要在开始编写代码之前通读单元测试,这样我才能知道该怎么做?
查看完整描述

1 回答

?
慕莱坞森

TA贡献1810条经验 获得超4个赞

阅读了D&D Character 练习描述后,这里根本没有具体说明。您对必须依靠这里的测试来为您提供规范感到不安是对的,这应该在您的作业中更清楚地描述。


测试当然期望有一个Character().ability()方法,并验证该方法返回一个 3-18 范围内的整数,包括 3-18。因此,在描述告诉您如何计算能力以及测试正在寻找什么的内容之间阅读,您只需将您的roll_ability()函数移动到您的Character类并重命名它ability():


class Character:

    def __init__(self):

        for ability in ABILITIES:

            setattr(self, ability, self.ability())

        self.hitpoints = 10 + modifier(self.constitution)


    def ability(self, dice=4, sides=6):

        rolls = []

        for die in range(dice):

            rolls.append(random.randint(1, sides))

        rolls.remove(min(rolls))

        return sum(rolls)

您自己的实现已经产生了 3 到 18 之间的数字(包括 3 个最高骰子的总和),因此应该毫无问题地通过测试。我已经确认上述实现(加上你的modifier()函数)确实通过了给定的单元测试。


从设计的角度来看,您在这里使用单独的功能是正确的。ability()不依赖于任何Character状态,也不是字符实例预期执行的功能。与其把它变成一个方法(带有一个无用的self参数),你可以在这里妥协并把它变成一个@staticmethod:


class Character:

    def __init__(self):

        for ability in ABILITIES:

            setattr(self, ability, self.ability())

        self.hitpoints = 10 + modifier(self.constitution)


    @staticmethod

    def ability(dice=4, sides=6):

        rolls = []

        for die in range(dice):

            rolls.append(random.randint(1, sides))

        rolls.remove(min(rolls))

        return sum(rolls)

至于ability()函数实现,您可能想在这里查看干净有效地从 4 个骰子中选出前 3 个的heapq.nlargest()函数:


from heapq import nlargest


class Character:

    # ...


    @staticmethod

    def ability(dice=4, sides=6):

        rolls = (random.randint(1, sides) for _ in range(dice))

        return sum(nlargest(dice - 1, rolls))

我只是根据 YAGNIdice将andsides参数放在此处,或者至少将幻数移动到顶部的大写全局名称中。46


查看完整回答
反对 回复 2022-07-05
  • 1 回答
  • 0 关注
  • 115 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信