'Art' object has no attribute 'art' what am i doing wrong?

hi,
i’m working on the market place veener exercie
here is the link
https://www.codecademy.com/paths/computer-science/tracks/cspath-cumulative-art-marketplace/modules/cspath-veneer/projects/veneer

I’m getting this error message but can’t figure out what’s wrong in the code.

here is my code

class Owner:
  def __init__(self, name, location):
    self.name = name
    self.location = location
  
  def sell_artwork(self, artwork, price):
    if artwork.owner == self:
      new_listing = Listing(artwork, price, self)
      veneer.add_listing(new_listing)

class Client:
  def __init__(self, name, location, is_museum):
    self.name = name
    self.is_museum = is_museum
    if self.is_museum == True :
      self.location = location
    else:
      self.location = 'Private Collection'
      
  def sell_artwork(self, artwork, price):
    if artwork.owner == self:
      new_listing = Listing(artwork, price, self)
      veneer.add_listing(new_listing)
   
  def buy_artwork(self, artwork):
    if artwork.owner != self:
      for listing in veneer.listings:
        if listing.art == artwork:
          art_listing = artwork
      artwork.owner = self
      veneer.remove_listing(art_listing)

class Art:
  def __init__(self, artist, title, medium, year, owner):
    self.artist = artist
    self.title = title
    self.medium = medium
    self.year = year
    self.owner = owner
    
  def __repr__(self):
  	return '%s. "%s". %s, %s. %s, %s.' %(self.artist, self.title, self.year, self.medium, self.owner.name, self.owner.location )

class Marketplace:
  def __init__(self, listings):
  	self.listings = listings
    
  def add_listing(self, new_listing):
    self.listings.append(new_listing)
  
  def remove_listing(self, expired_listing):
  	self.listings.remove(expired_listing)
  
  def show_listings(self):
    if len(self.listings) > 0:
      for listing in self.listings:
        print("---")
        print(listing)
        print("*******************************")
    else:
      print("There is no art work in the list")
      
class Listing:
  def __init__(self, art, price, seller):
    self.art = art
    self.price = price
    self.seller = seller
  
  def __repr__(self):
    to_print = '{}, {}'.format(self.art, self.price)
    return to_print

marc = Owner('Marc Lafarge', 'Filadelphia')
first_painting = Art('Monet, Claude', 'Vtheuil in the Fog', 'oil', 1879, marc)

#print(girl_with_mandolin)
#creating the main marketplace

# first client
edytta = Client('Edytta Halpirt', None, False)
moma = Client('The MOMA', 'New York', True)
#print(edytta.is_museum)
girl_with_mandolin = Art('Picasso, Pablo', 'Girl with a Mandolin (Fanny Tellier)', 'oil on canvas', 1910, marc)

veneer = Marketplace([first_painting, girl_with_mandolin])
veneer.show_listings()
print("After the sell:")
marc.sell_artwork(girl_with_mandolin, '6$ Million(USD)')
#listing of the artwork
veneer.show_listings()
moma.buy_artwork(girl_with_mandolin)

And this is what i’m getting as result on the .buy_artwork() methode

Traceback (most recent call last):
  File "script.py", line 95, in <module>
    moma.buy_artwork(girl_with_mandolin)
  File "script.py", line 28, in buy_artwork
    if listing.art == artwork:
AttributeError: 'Art' object has no attribute 'art'

Thanks for the help

1 Like

It appears art is an attribute of a Listing class instance but we do not see any instantiation.

1 Like
class Listing:
  def __init__(self, art, price, seller):
    self.art = art
    self.price = price
    self.seller = seller

I put the Linsting class first but it still the same error.
Something i don’t understand maybe.

1 Like

Did you declare an instance of Listing?

new_listing = Listing(...)
1 Like

Yes, when i call the method .sell_art_work() it creates a new one.

  def sell_artwork(self, artwork, price):
    if artwork.owner == self:
      new_listing = Listing(artwork, price, self)
      veneer.add_listing(new_listing)
1 Like

D’oh! How did I not see that? Question: Are these all meant to be standalone classes or are any of them subclasses?

1 Like

they are all standalone classes :slight_smile:

1 Like

Should this line be,

if artwork.owner == self.owner:

?

1 Like

self in this case is for the owner class. So we are just checking if the name on the artwork is the owner to make sure he can sell it.

1 Like

The error comes from here

  def buy_artwork(self, artwork):
    if artwork.owner != self:
      for listing in veneer.listings:
        if listing.art == artwork:
          art_listing = artwork
        artwork.owner = self
        veneer.remove_listing(art_listing)
1 Like

I’m working my way through this project and should get caught up to where you are presently. Bear with me. If you solve it in the meantime, let us know, please.

1 Like

I’ve gotten this far, but segued so as to explore exception handling when objects of the wrong class are passed in. Obviousely not working, but we can zero in on the cause of the exception that is raised. That clue will help us along this path.

#import sys
#print (sys.version)
class Art:
  def __init__(self, artist, title, year, medium, owner):
    self.artist = artist
    self.title = title
    self.year = year
    self.medium = medium
    self.owner = isinstance(owner, Client) and owner or False
  def __repr__(self):
    return '\
    {last}, {first}.\
    \n"{title}".\
    \n{year}, {medium}.\
    \nOwner: {owner}.\
    \nLocation: {location}.\
    \n{collection}.'.format(
      last = self.artist.split()[1],
      first = self.artist.split()[0],
      title = self.title,
      year = self.year,
      medium = self.medium,
      owner = self.owner.name,
      location = self.owner.location,
      collection = ['Private Collection', 'Museum'][self.owner.is_museum]
    )
class Marketplace:
  def __init__(self):
    self.listings = []
  def add_listing(self, new_listing):
    self.listings.append(new_listing)
  def remove_listing(self, listing):
    self.listings.remove(listing)
  def show_listings(self):
    for listing in self.listings:
      print(listing)
      
veneer = Marketplace()
veneer.show_listings()
class Client:
  def __init__(self, name, location, is_museum):
    self.name = name
    self.location = location
    self.is_museum = is_museum
    
edytta = Client('Edytta Halpirt', 'New York', 0)
moma = Client('The MOMA', 'New York', 1)

girl_with_mandolin = Art('Pablo Picasso', 'Girl with a Mandolin (Fanny Tellier)', 1910, 'oil on canvas', edytta)

print (girl_with_mandolin)
andy = {
  'name': 'Andy Warhol', 
  'location': 'New York',
  'is_museum': 0
}
campbell_soup = Art('Andy Warhol', 'Campbell Soup Tin', 1960, 'oil on canvas', andy)
print (campbell_soup)

Picasso, Pablo.
"Girl with a Mandolin (Fanny Tellier)".
1910, oil on canvas.
Owner: Edytta Halpirt.
Location: New York.
Private Collection.
Traceback (most recent call last):
  File "script.py", line 55, in <module>
    print (campbell_soup)
  File "script.py", line 18, in __repr__
    owner=self.owner.name,
AttributeError: 'bool' object has no attribute 'name'

This traces back to andy not being a Client instance.

All a part of making decisions along the way. Do we solve this? Or do we pour on?


I am not comfortable moving forward. The introduction of the owner created a dependency that might well be accommodated as a parameter to a method without including the attribute in this class. There is contamination, as I see it, if we infuse the owner attribute at this point. Well and good we hope to play this out.

1 Like

OK well first i found the problem from my previous code:

Marketplace does not take arguments beside self.

class Marketplace:
  def __init__(self):
  	self.listings = []
1 Like

Andy here is not declared as a client

andy = Client('Andy Warhol', 'New York', 0)
1 Like

Thanks for the help ! I appreciate :slight_smile:

1 Like

That was on purpose so we could see the effect and work out an avenue of approach to detect and flag it.

1 Like