Ex42 fill-in-the-blanks

question is i’m bit confused about the fill-in-the-blanks assignment given in ex42

## Animal is-a object (yes, sort of confusing) look at the extra credit
class Animal(object):
	pass

## ?? Dog is-a Animal
class Dog(Animal):

	def __init__(self, name):
		## ?? Dog has-a name
		self.name = name

## ?? Cat is-a Animal
class Cat(Animal):

	def __init__(self, name):
		## ?? Cat has-a name
		self.name = name

## ?? Person is-a object
class Person(object):

	def __init__(self, name):
		## ?? Person has-a name
		self.name = name

		## Person has-a pet of some kind
		self.pet = None

## ?? Employee is-a Person
class Employee(Person):

	def __init__(self, name, salary):
		## ?? hmm what is this strange magic?
		super(Employee, self).__init__(name)
		## ?? Employee has-a salary
		self.salary = salary

## ?? Fish is-a object
class Fish(object):
	pass

## ?? Salmon is-a Fish
class Salmon(Fish):
	pass

## ?? Hailbut is-a Fish
class Halibut(Fish):
	pass


## rover is-a Dog
rover = Dog("Rover")

## ?? satan is-a Cat
satan = Cat("Satan")

## ?? mary is-a Person
mary = Person("Mary")

## ?? 
mary.pet = satan

## ?? frank is-a employee
frank = Employee("Frank", 120000)

## ??
frank.pet = rover

## ?? flipper is-a Fish
flipper = Fish()

## ?? crouse is-a Salmon
crouse = Salmon()

## ?? harry is-a Hailbut
harry = Halibut()

as you can see i have fill most of them but not on the line 60 and 66
what i would wright is
on line 60: mary has-a pet Cat named Satan
on line 66: frank has-a pet Dog named Rover

is that right?
because i think that mary and frank both are having pet
and all other fill ups are right or not
i appreciate your explanation on the same

Hi @divyang_patel.

I will try to do the best I can on this one.

In the example mary has become an instance of the Person class.
I don’t know if one also can call mary an object (please correct me if I am wrong).
You can connect attributes to the object.
Like name in the Person class .

mary “got her name” like this.

mary = Person('Mary')

There is also a attribute called pet in the Person class.
In the class pet is set to None
Later it is set to ‘satan’ (which is also an instance of Cat)
But you can choose whatever you like (perhaps ‘Angel’ :slight_smile:)

mary.pet = 'Angel'

Perhaps ‘Mary’ want to have a car.
Add to the class the attribute: car.

self.car = None

Then give Mary the car :smiling_face_with_three_hearts:

mary.car = 'Tesla'

If you want to print it out type:

print(f"{mary.name} has a {mary.car} and a cat called {mary.pet}")
# the f-string is for Python 3.6 or higher.

=

Mary has a Tesla and a cat called Angel

thank you for your reply

as you said that mary is an instance ie the object of class Person and class Person has a attributes name and pet
pet is assign to None and we are passing value of name attribute Mary while creating instance of Person class which is mary
now here the thing that satan is an instance of Cat class and now value of attribute pet of an instance mary is set to satan
so what should happen
class Cat should run again and pass that name attribute of Cat class to an pet attribute an instance mary
i think it’s not
then what’s the point
why there is need to set an satan instance of Cat to an attribute pet of an instance mary
what is happening there, what is that line 61 doing and what you will right in fill up on line 60

Hello.

I actually dont know. Zed has to answer that.

And I dont know if this works as intended.
When setting mary.pet = satan I got:

print(mary.pet)
<main.Cat object at 0x108ceed68&gt>

If I want mary.pet = satan be equal to ”Satan”
I have set it to mary.pet = satan.name

hey
i realized that i’m asking wrong question when you pointed out

i think i am just over thinking about setting satan to mary.pet
because the way zed said to find the relation between both so i think that Cat class will run again and there will be relation
but one thing that now mary.pet is also an object of Cat class, right?

Hi @divyang_patel

Yes. When you set mary.pet to satan.
Because satan is an instance of Cat.
That would be the relation.
You can check it with

mary.__class__

mary.pet = ”Angel” would be a Person object because pet is a attribute of Person.
No other relations in here.

yes i did and it showing this


as you can see mary.pet is instance of Cat class

before you said to do

i did this
print

Hi @divyang_patel

I guess both of us have learned more from this.
At least I did. I hope you did too.

:grinning: yes
i rather not say that we learned something,
it’s something we seen that we don’t know
that’s weird :joy::joy::joy:
but we are still not sure what is happening, at least i am not

There is a saying i Sweden (perhaps elsewhere too) that the bumblebee doesn´t know it cannot fly.
So it flies around happily anyway.

Perhaps its the same with my coding in Python :sweat_smile:

Perhaps @zedshaw will put some comments in here about this.
That will tell if we are on the track or not.

Thanks for the conversation.

@ulfen69 thank you for sticking with me through strange time :grin:
i also think zed can show us something more on “strange” thing :sweat_smile:
until
have a great day :+1:

Just to clarify here @divyang_patel, but when you do this:

mary.pet = satan

Are you thinking that this creates a new Cat object? It actually just makes a link–aka a reference–to the original satan object. It doesn’t re-rerun Cat().

Thank you @zedshaw for clearing my doubt
yes earlier i was thinking that satan will run Cat but later i figured that there is no Class call, it’s just an object assignment

1 Like

Here is my attempt at filling out the blanks. Figure I build on this thread. I could not figure out how to edit it as nice as divyang_patel.

# Animal is-a object
class Animal(object):
    pass
# Dog is-a animal
class Dog(Animal):
    # Dog has-a __init__ function with params self and name 
    def __init__(self, name):
        # Dog has-a name
        self.name = name

class Cat(Animal):

    def __init__(self, name):
        self.name = name
# Person is-a objecty
class Person(object):

    def __init__(self, name):
        # Person has-a component variable called name
        self.name = name
        # Person has-a component variable called pet
        self.pet = None

class Employee(Person):

    def __init__(self, name, salary):
        # Employee has-a inherited function super with params employee and self, called by __init__ with param name
        super(Employee, self).__init__(name)
        # Employee has-a salary
        self.salary = salary

# Fish is-a object
class Fish(object):
    pass
# Salmon is-a Fish
class Salmon(Fish):
    pass
# Halibut is-a Fish
class Halibut(Fish):
    pass
    
# Rover is-a Dog
rover = Dog("Rover")

# Satan is-a cat
satan = Cat("Satan")

# Mary is-a person
mary = Person("Mary")
# From pet, get Mary function, call it with paramentes self, satan
mary.pet = satan

# Frank is-a employee with parameters Frank and 120000
frank = Employee("Frank", 120000)
# from pet get the frank function, call it with params self and rover
frank.pet = rover

# Flipper is-a Fish
flipper = Fish()

# crouse is-a salmon
crouse = Salmon()

# harry is-a halibut
harry = Halibut()

From a quick glance @dansmit that looks right, but instead of “component variable” you’d say “attribute”. You also have this:

# From pet, get Mary function, call it with paramentes self, satan
mary.pet = satan

But, it’s not getting the anything from pet. You’ve made 3 errors here:

  1. Get the pet attribute from mary. You have this backwards, so can you explain why?
  2. Mary is not a function. Again, try to explain why you thought this.
  3. You aren’t calling with parameters self, you are assigning it to the attribute pet of mary. Try to explain why you thought this.

I’m asking you to explain your thinking since that will help you figure out how you misunderstand what’s going on and get you to go back and look at the exercises that will help.

1 Like

Thank you Zed for taking the time to review my answer.

Re-looking at it I do not know why I made that mistake. I think I have a hard time understanding attributes and when/who/why use the period. I have come across many hurdles because of placing the period in the wrong place. Most of the time I eventually “fall into” the correct iteration and can move on, but I am clearly missing something. Do you have a suggestion to review attributes or period use? I went on YouTube and found all sort of unhelpful videos.

I believe the correct explanation would be:
From mary, get the pet attribute and set it to satan.

Ok so let’s see if you get dictionaries (dict) first. What’s this code print out:

names = {
  'zed': 46,
  'dan': 0,
}

print(names['zed'])

Next, make one of the objects from this exercise, say person, and do this:

frank = Person('frank')
print(frank.__dict__)

You’ll see the name and age attributes in there. Now, try this:

print(frank.__dict__['name'])
print(frank.name)

All the . (dot) operator does is translate to dictionary syntax by going into the secret .__dict___ dictionary. It’s just saving you the trouble of typing .dict all the time. When you get into multiple inheritance it gets more complicated, but all the dot does is access a dict with some magic for you.

And the magic is just it looks in dict and a few other places.

Here’s me doing it:

>>> class Person(object):
...   def __init__(self, name):
...     self.name = name
...
>>> frank = Person('frank')
>>> frank.__dict__
{'name': 'frank'}
>>> frank.__dict__['name']
'frank'
>>> frank.name
'frank'
>>>
2 Likes

Thank you, this makes sense now, but I after 3 more exercises I sometimes forget where is what and why. I will read more on dictionary.

1 Like

Yes, read, but use it more. Come up with a couple of problems you can solve with dictionaries and write little programs.

And then just memorize that thing.member means "from thing get member". It’s a common syntax you’ll find in many many languages.

In a few months you’ll be amused that you ever had problems with this. :wink: