1

(別のクラス)knapsackのリストをパラメーターとして受け取るクラスを作成しています。Items各アイテムには重量と値があり、ナップザックには合計重量 (すべての のitem.weights合計) と合計値 (すべての の合計item.values) が必要です。

私が達成しようとしているknapsack.total_weightのはknapsack.total_value、私がknapsack.items.append(new_item).

これまで、 、 、 を で装飾してみましたitemstotal_weighttotal_valueうまく@propertyいかないようです。プロパティデコレータを適切に使用する方法についてのアイデアはありますか、それとも別の実装を検討する必要がありますか?

class Item:
    def __init__(self,name:str,weight:int,value:int):
        self.name = name
        self.weight = weight
        self.value = value

    def __str__(self):
        return f'{self.name}: {self.weight}kg ({self.value})'

class Knapsack:

    def __init__(self,items=[],max_weight=250,score=None,weight=None):
        self.max_weight = max_weight
        self._items = items
        self._score = score
        self._weight = weight

    @property
    def items(self):
        return self._items

    @items.setter
    def items(self,new_item):
        self._items += [new_item]
        self._score = self._items
        self._weight = self._items

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self,items):
        total_score = 0
        for item in items:
            total_score += item.value
        self._score = total_score

    @property
    def weight(self):
        return self._weight

    @weight.setter
    def weight(self,items):
        total_weight = 0
        for item in items:
            total_weight += item.weight
        self._weight = total_weight

    def __str__(self):
        out = [item.name for item in self.items]
        return f'{"".join(out)}\t{self.score}'
4

2 に答える 2

1

あなたは正しい考えを持っていますが、OOP には少し慣れていないようです。このようなものはどうですか?

class Item:
    def __init__(self, name, value, weight):
        self.name = name
        self.value = value
        self.weight = weight


class Knapsack:
    def __init__(self, max_weight):
        self._items = []
        self.max_weight = max_weight

    @property
    def total_weight(self):
        return sum(i.weight for i in self._items)

    @property
    def total_value(self):
        return sum(i.value for i in self._items)

    def add(self, item):
        if self.total_weight + item.weight > self.max_weight:
            raise ValueError("that ain't gonna fit in there")
        self._items.append(item)

sack = Knapsack(100)
sack.add(Item('a', 1, 10))
sack.add(Item('b', 1, 20))
sack.add(Item('c', 1, 30))

print('Total weight: ', sack.total_weight)
print('Total value: ', sack.total_value)

try:
    sack.add(Item('too big', 1, 50))
except ValueError as e:
    print(e)

アップデート:

いくつかのメモ。あなたが行った方法でアイテムセッターを実装することもできますが、結果として得られる使用法は直感に反するものでsack.items = itemあり、アイテムを追加するようなことをしなければなりません. これらはアイテムが変更されたときにのみ変更され、個別に変更することはできないため、重みまたは値のいずれかに対してセッターを定義する必要はありません。Knapsack を list のサブクラスにしようとすることもできますが、それを機能させるにはたくさんの「秘密の」メソッドを実装する必要があります。

更新の更新:

上記は高品質のタラではないことに注意してください。実装を説明することのみを目的としています。たとえば、私はsack.add(Item('x', 'x', 'x'))すべてを実行して壊します。

于 2019-09-23T20:40:29.910 に答える