0
class Amenity():
  def __init__(self, itemCode, description, price):
    self._itemCode = itemCode
    self._description = description
    self._price = price

  def __str__(self):
    return "{}, {}, ${:.2f}".format(self._itemCode, self._description, self._price)

class Room():
  def __init__(self):
    self._amenities = []

  def addAmenity(self, newItem):
    if newItem in self._amenities:
      return "Duplicate found"
    else:
        self._amenities.append(newItem)

  def __str__(self):
    amenityListing = "\n".join(str(amenity) for amenity in self._amenities)
    return "{} ".format(amenityListing)

def main():
    room2 = Room()
    room2Amenity1 = Amenity("GYM-PEP","Per entry pass to gym (Level 4-01)",1.00)
    room2Amenity2 = Amenity("FRIDGE","Mini Fridge (50L)",4.59)
    room2Amenity3 = Amenity("WI-FI","One-day Wi-Fi access",1.00)
    room2Amenity4 = Amenity("GYM-PEP","Per entry pass to gym (Level 4-01)",1.00)
    room2.addAmenity(room2Amenity1)
    room2.addAmenity(room2Amenity2)
    room2.addAmenity(room2Amenity3)
    print(room2)
    print()
    room2.addAmenity(room2Amenity4)
    print(room2)

Output

GYM-PEP, Per entry pass to gym (Level 4-01), $1.00
FRIDGE, Mini Fridge (50L), $4.59
WI-FI, One-day Wi-Fi access, $1.00

GYM-PEP, Per entry pass to gym (Level 4-01), $1.00
FRIDGE, Mini Fridge (50L), $4.59
WI-FI, One-day Wi-Fi access, $1.00
GYM-PEP, Per entry pass to gym (Level 4-01), $1.00

Expected Output

GYM-PEP, Per entry pass to gym (Level 4-01), $1.00
FRIDGE, Mini Fridge (50L), $4.59
WI-FI, One-day Wi-Fi access, $1.00

GYM-PEP, Per entry pass to gym (Level 4-01), $1.00
FRIDGE, Mini Fridge (50L), $4.59
WI-FI, One-day Wi-Fi access, $1.00
Duplicate found

  • 2
    `room2Amenity1` is not the same object as `room2Amenity4`, so it's not going to be found by `in`. If you add `room2Amenity1` again, it will work as you expect. – Tim Roberts Apr 23 '23 at 05:57
  • 1
    You probably want to [override `__eq__`](https://stackoverflow.com/questions/390250/elegant-ways-to-support-equivalence-equality-in-python-classes) – Guy Apr 23 '23 at 06:01
  • `room2Amenity1 != room2Amenity4` – Nikolaj Š. Apr 23 '23 at 06:04
  • If you don't need to print the error message, you might consider using a `set` rather than a `list`. But you'll still need to deal with the equality issue. – Chris Apr 23 '23 at 06:11

2 Answers2

1

When the in operator searches the list, what it actually does behind the scenes is look for any object in the list that is equal to the object you ask it to look for. The default "equality" for objects in python is their id, an effectively arbitrary value that's different for each instance. Two instances of the class will have different ids, even if all of their attributes are equal. That's what's happening here - your two equal objects are still getting treated as different objects.

You can define your own "equality" for your custom classes by overriding the __eq__() method:

class Amenity():
  ...
  def __eq__(self, other):
    if isinstance(other, Amenity):
      return (self._itemCode, self._description, self._price) == (other._itemCode, other._description, other._price)
      # alternatively, less verbose: return str(self) == str(other)
    else:
      return False
Green Cloak Guy
  • 23,793
  • 4
  • 33
  • 53
0

In your code, room2Amenity4 is not the same object as room2Amenity1. They are separate objects.

The self._amenities = [] list in room2Amenity4 only has one value, so, addAmenity doesn't print Duplicate found.

If you try to add room2.addAmenity(room2Amenity1) again, then the self._amenities = [] list in room2Amenity1 will have two same values, then addAmenity function will print Duplicate found.

To solve the problem, you can use the following code in your Amenity class:

class Amenity():
  def __init__(self, itemCode, description, price):
    self._itemCode = itemCode
    self._description = description
    self._price = price

  def __str__(self):
    return "{}, {}, ${:.2f}".format(self._itemCode, self._description, self._price)

  #Override the __eq__ function
  def __eq__(self, other_object):
    #Check if two same values are passed to two objects
    if isinstance(other_object, Amenity):
      return (self._itemCode, self._description, self._price) == (other_object._itemCode, other_object._description, oother_objectther._price) 

    else:
      return NotImplemented

In the above code, we have overriden the eq function to check if values passed to different objects are equal.

Dinux
  • 644
  • 1
  • 6
  • 19