Правильное использование классов данных для возврата значений элементов - PullRequest
0 голосов
/ 30 октября 2018

Проект состоит в том, чтобы сортировать элементы - используя определенный алгоритм - в ящики. У меня возникают проблемы после назначения каждого элемента соответствующему классу, чтобы вернуться к другой функции и использовать и изменять данные, содержащиеся в объекте в классе данных.

Мой тестовый файл выглядит так:

17 10 4
Abacus 3
Blender 5
Chessboard 3
Dishes 6

Мои занятия:

@dataclass
class InventoryItem:
    name: str
    weight: float


@dataclass
class BoxInventory:
    name: str
    maxWeight: float
    remainingWeight: float
    contents: dict = ""
    """
    def listContents(self, contents):
        self.listContents = contents

    def remainingWeight(self, remainingWeight):
        self.remainingWeight = remainingWeight

    def addItemWeight(self, itemWeight):
        self.remainingWeight -= itemWeight

    def addItemList(self, itemName, itemWeight, contents):
        self.contents = contents[itemName] = contents[itemWeight]
    """

Здесь я читаю свой текстовый файл и передаю его в класс:

"""
Take the given txt file and format into proper list for boxes and items
:param filename: The filename of the text file
:return: Send lists to to be used by an algo.
"""
with open(filename, 'r') as myFile:  # Open the correct file
    itemDict = {}
    boxDict = {}

    myList = [line.split() for line in myFile.readlines()]
    boxLine = ' '.join(myList[0])

    for line in range(1, len(myList)):
        lines = ''.join(myList[line])
        itemName = lines[:-1]
        weight = lines[len(lines) - 1:]

        item = InventoryItem(itemName, int(weight))
        itemDict[itemName] = [item]

    boxString = ""
    count = 0
    for char in boxLine:
        if char != " ":
            boxString = boxString + char
        else:
            boxName = "Box" + str(count)
            box = BoxInventory(boxName, int(boxString), int(boxString))
            boxDict[boxName] = [box]
            boxString = ""
            count += 1

myReturn = {}
myReturn['boxDict'] = boxDict
myReturn['itemDict'] = itemDict
return myReturn

Не реализованный алгоритм:

def roomiest(myReturnDict):
    """
    For each item find the box with the greatest remaining allowed weight that can support the item and place the item in that box
    :param boxList: The list of boxes in the class from the given file
    :param itemList: The list of items in the class from the given file
    :return: If boxes were able to fit all items(1); items in box with individual weights(2); Box name with max
    weight(3); items with their weights that were left behind(4)
    """
    itemList = myReturnDict.get("itemDict")
    boxList = myReturnDict.get("boxDict")

Моя проблема в том, что я знаю, как читать проанализированные данные из моего Функция fileReader в моем алгоритме. функция.

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Что я сделал, вместо того, чтобы использовать словарь, я использую список для передачи данных в новую функцию.

Текстовый файл -> Список -> Dict -> Список -> sortedList

Вот моя новая функция fileReader:

def fileReader(filename):
    """
    Take the given txt file and format into proper list for boxes and items
    :param filename: The filename of the text file
    :return: Send lists to to be used by an algo.
    """
    with open(filename, 'r') as myFile:  # Open the correct file
        itemList = []
        boxList = []

        myList = [line.split() for line in myFile.readlines()]
        boxLine = ' '.join(myList[0])

        for line in range(1, len(myList)):
            lines = ''.join(myList[line])
            itemName = lines[:-1]
            weight = lines[len(lines) - 1:]

            item = InventoryItem(itemName, int(weight))
            itemList.append(item)

        boxString = ""
        count = 0
        for char in boxLine:
            if char != " ":
                boxString = boxString + char
            else:
                boxName = "Box" + str(count)
                box = BoxInventory(boxName, int(boxString), int(boxString))
                boxList.append(box)
                boxString = ""
                count += 1

Затем я читаю и сортирую данные в каждом алгоритме, используя тот же метод:

def roomiest(myReturnDict):
    """
    For each item find the box with the greatest remaining allowed weight that can support the item and place the item in that box
    :param boxList: The list of boxes in the class from the given file
    :param itemList: The list of items in the class from the given file
    :return: If boxes were able to fit all items(1); items in box with individual weights(2); Box name with max
    weight(3); items with their weights that were left behind(4)
    """
    itemData = list(myReturnDict.get("itemList"))
    boxData = list(myReturnDict.get("boxList"))

    sortedItemList = sorted(itemData, key=lambda x: x.weight, reverse=True)
    sortedBoxList = sorted(boxData, key=lambda x: x.remainingWeight, reverse=True)
        myReturn = {}

        myReturn['boxList'] = boxList
        myReturn['itemList'] = itemList
        return myReturn

Мои классы данных выглядят следующим образом:

@dataclass
class InventoryItem:
    name: str
    weight: float


@dataclass
class BoxInventory:
    name: str
    maxWeight: float
    remainingWeight: float
    contents: dict = ""


def itemWeight(item):
    print("Weight of", item.name, "is: ", item.weight, "\n")
    return item.weight


def remainWeight(box):
    print("Rem. weight in ", box.name, "is: ", box.remainingWeight, "\n")
    return box.remainingWeight
0 голосов
/ 30 октября 2018

Ваша функция ввода немного странная, поскольку вы храните объекты в списке длиной 1 внутри словаря. Итак, ваши данные выглядят так:

'Dishes': [InventoryItem(name='Dishes', weight=6)]

вместо

'Dishes': InventoryItem(name='Dishes', weight=6)

У вас может быть причина для этого, но изменение itemDict[itemName] = [item] на itemDict[itemName] = item делает ваш код немного легче для понимания (и то же самое для boxDict[boxName] = [box]). С этим изменением вы можете легко получить доступ к проанализированным данным с помощью следующего:

for item_name, item in itemList.items():
    print(item.name)
    print(item.weight)

Это перебирает словарь itemList, получая пары ключ-значение, которые в данном случае являются itemName, item (или [item] в вашем исходном коде. Если вы не хотите это менять, замените item на item [0 ] в коде выше). Затем вы можете получить доступ к атрибутам вашего класса напрямую, вызвав их метку.

Вы можете получить ящик с наибольшим количеством свободного места, используя

sorted_box_list = (sorted(boxList.values(), key=operator.attrgetter('remainingWeight'), reverse=True))
...