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?
CodePudding user response:
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