-2

I have a class:

class AlchemicalElement:

    def __init__(self, name: str):
        self.name = name

I then create a class that will be used to store the AlchemicalElement objects:

class AlchemicalStorage:

    def __init__(self):
        self.storage_list = []

I don't understand how to write this function:

def extract(self) -> list[AlchemicalElement]:
    """Return a list of all the elements from storage and empty the storage itself."""
    return []

So far I've only managed this:

def add(self, element: AlchemicalElement):
    if isinstance(element, AlchemicalElement):
        self.storage_list.append(element)
    else:
        raise TypeError()

This is what I try to achieve:

    storage = AlchemicalStorage()
    storage.add(AlchemicalElement('Water'))
    storage.add(AlchemicalElement('Fire'))
    storage.extract() # -> [<AE: Water>, <AE: Fire>]
    storage.extract() # -> []

Question

How do I write the .extract() method so that when first called it returns a list of elements in the storage_list, but an empty list on any call after?

Ian Thompson
  • 2,914
  • 2
  • 18
  • 31
fallguy
  • 25
  • 5
  • (1) Could you place all your code together at the end so we can see the structure? (2) do you want an empty list to be returned the second time you call `extract`? – Ian Thompson Nov 09 '22 at 17:06
  • 1
    Why does it "seems like even this is incorrect"? What problem are you having? – jarmod Nov 09 '22 at 17:08
  • (1) not sure what you are asking, that's pretty much all the code. (2) yes, because we already extracted everything – fallguy Nov 09 '22 at 17:12
  • @fallguy asking for the methods to be placed in their respective classes so we can copy and paste – Ian Thompson Nov 09 '22 at 17:13
  • 2
    I'm sorry, but what is your question exactly? What is the problem? – juanpa.arrivillaga Nov 09 '22 at 17:42
  • @juanpa.arrivillaga I don't understand how to write the extract() function – fallguy Nov 09 '22 at 17:44
  • What don't you understand? Your doc string tells you all you need to know: You need to "Return a list of all the elements from storage" (you already have a list of all elements) and then "empty the storage itself" (by setting it to an empty list?) Since you can't do anything _after_ you return, assign your original list to a new variable, reset the original list, then return the new variable you just created. – Pranav Hosangadi Nov 09 '22 at 17:48

1 Answers1

0

Assuming this is what you're starting with

class AlchemicalElement:

    def __init__(self, name: str):
        self.name = name


class AlchemicalStorage:

    def __init__(self):
        self.storage_list = []

    def add(self, element: AlchemicalElement):
        if isinstance(element, AlchemicalElement):
            self.storage_list.append(element)
        else:
            raise TypeError()

    def extract(self) -> list[AlchemicalElement]:
        """Return a list of all the elements from storage and empty the
        storage itself."""
        return []


if __name__ == "__main__":
    storage = AlchemicalStorage()
    storage.add(AlchemicalElement('Water'))
    storage.add(AlchemicalElement('Fire'))
    print(storage.extract())  # -> [<AE: Water>, <AE: Fire>]
    print(storage.extract())  # -> []

You'll currently get output that looks like this

[]
[]

Your first question is how do I make the .extract() method exhaust the .storage_list?

We could do something like this:

    def extract(self) -> list[AlchemicalElement]:
        """Return a list of all the elements from storage and empty the
        storage itself."""
        # copy the storage_list into out_list and then clear it
        # only works once!
        out_list = self.storage_list.copy()
        self.storage_list.clear()
        return out_list

Now if we run the script we should get the following:

[<__main__.AlchemicalElement object at 0x000001CB12CBBD00>, <__main__.AlchemicalElement object at 0x000001CB12CBBCA0>]
[]

Now maybe to answer another question, how to do I get it to return <AE: Water> instead of <__main__.AlchemicalElement object at ...>?

We can do that by adding a __repr__ method to the AlchemicalElement class

class AlchemicalElement:

    def __init__(self, name: str):
        self.name = name

    def __repr__(self):
        return f"<AE: {self.name}>"

All code together now looks like this

class AlchemicalElement:

    def __init__(self, name: str):
        self.name = name

    def __repr__(self):
        return f"<AE: {self.name}>"


class AlchemicalStorage:

    def __init__(self):
        self.storage_list = []

    def add(self, element: AlchemicalElement):
        if isinstance(element, AlchemicalElement):
            self.storage_list.append(element)
        else:
            raise TypeError()

    def extract(self) -> list[AlchemicalElement]:
        """Return a list of all the elements from storage and empty the
        storage itself."""
        # copy the storage_list into out_list and then clear it
        # only works once!
        out_list = self.storage_list.copy()
        self.storage_list.clear()
        return out_list


if __name__ == "__main__":
    storage = AlchemicalStorage()
    storage.add(AlchemicalElement('Water'))
    storage.add(AlchemicalElement('Fire'))
    print(storage.extract())  # -> [<AE: Water>, <AE: Fire>]
    print(storage.extract())  # -> []

And output looks like how you want

[<AE: Water>, <AE: Fire>]
[]

Note:

The __repr__ method should return a printable representation of the object, most likely one of the ways possible to create this object. source

Ian Thompson
  • 2,914
  • 2
  • 18
  • 31