Прочитав описание упражнения D & D Character , это просто не указано . Вы вправе испытывать неловкость из-за необходимости полагаться на тесты, чтобы предоставить вам спецификации, это должно было быть более четко описано в вашем задании.
В ходе теста, безусловно, ожидается, что Character().ability()
метод, и он проверяет, что этот метод возвращает целое число в диапазоне 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 самых высоких костей выкатывается из 4), поэтому должен пройти тест без проблем. Я подтвердил, что вышеприведенная реализация (плюс ваша 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()
реализации, вы можете захотеть взглянуть на функцию heapq.nlargest()
, чтобы аккуратно и эффективно выбрать 3 верхних из 4 бросков кубиков здесь:
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))
Я бы просто бросил аргументы dice
и sides
здесь на основе YAGNI или не менее перемещают маги c числа 4
и 6
в глобальный верхний регистр имена вверху.