Python Forum
Some questions regarding classes
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Some questions regarding classes
#1
task:
Create a Pets class that holds instances of dogs; this class is completely separate from the Dog class. In other words, the Dog class does not inherit from the Pets class. Then assign three dog instances to an instance of the Pets class.

solution:
# Parent class
class Dog:

    # Class attribute
    species = 'mammal'

    # Initializer / Instance attributes
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # instance method
    def description(self):
        return "{} is {} years old".format(self.name, self.age)

    # instance method
    def speak(self, sound):
        return "{} says {}".format(self.name, sound)

# Child class (inherits from Dog class)
class RussellTerrier(Dog):
    def run(self, speed):
        return "{} runs {}".format(self.name, speed)

# Child class (inherits from Dog class)
class Bulldog(Dog):
    def run(self, speed):
        return "{} runs {}".format(self.name, speed)
		
# Parent class
class Pets:
	
	dogs = [] 
	
	def __init__(self, dogs):
		self.dogs = dogs

my_dogs = [
    Bulldog("Tom", 6),
	RussellTerrier("Fletcher", 7),
	Dog("Larry", 9)
]

# Instantiate the Pets class
my_pets = Pets(my_dogs)
print(f'I have {len(my_pets.dogs)} dogs.')
for dog in my_pets.dogs:
	print(f'{dog.name} is {dog.age}')
print(f'And they\'re all {dog.species}s, of course.')
I have several questions regarding this solution:
1. why in class Pets it is necessary to open an empty list
dogs = []
2. this line confuses me:
print(f'I have {len(my_pets.dogs)} dogs.')
why my_pets.dogs? I don't see a connection. dogs is attribute of the class Pet. Does dogs represents names in my_dogs list methods?
3. in
for dog in my_pets.dogs:
what is dog? Doh
Reply
#2
(Jul-04-2018, 10:36 PM)Truman Wrote: 1. why in class Pets it is necessary to open an empty list
Can just delete has no function(yet) other than it's a empty list that belong to the class,the output will be same.
You can look at list at bye calling it with class name.
I have 3 dogs.
Tom is 6
Fletcher is 7
Larry is 9
And they're all mammals, of course.

# Call it
>>> Pets.dogs
[]

# The instance attributes has the same name "dogs",but it don't overwrite the class attribute dogs
>>> my_pets.dogs
[<__main__.Bulldog object at 0x03B2AE30>,
 <__main__.RussellTerrier object at 0x03B2AE70>,
 <__main__.Dog object at 0x03B2ADF0>]
>>> 
Quote:2. this line confuses me:
Python Code: (Double-click to select all)
print(f'I have {len(my_pets.dogs)} dogs.')
why my_pets.dogs? I don't see a connection. dogs is attribute of the class Pet. Does dogs represents names in my_dogs list methods?
It just used to count,so in the list there will be 3 new instances.
>>> my_pets.dogs
[<__main__.Bulldog object at 0x03B2AE70>,
 <__main__.RussellTerrier object at 0x03B2ADF0>,
 <__main__.Dog object at 0x03B2AD50>]

>>> len(my_pets.dogs)
3

# In the loop this happens when methods get called 
>>> my_pets.dogs[0].name
'Tom'
>>> my_pets.dogs[0].age
6
Quote:what is dog?
See if output is the same Wink
for dog in my_pets.dogs:
    print(f'{dog.name} is {dog.age}')

# Try
for rubberduck in my_pets.dogs:
    print(f'{rubberduck.name} is {rubberduck.age}')
Reply
#3
Yep, it's the same. I missed the basics of Py.
After removing
dogs = [] 
code can't be executed, it still looks a bit tricky for me.
Reply
#4
(Jul-05-2018, 10:08 PM)Truman Wrote: After removing
dogs = []
code can't be executed, it still looks a bit tricky for me
Code should work fine when remove that class attribute,as mention it has no function.
Here my output with line 33 dogs = [] is first deleted.
Output:
I have 3 dogs. Tom is 6 Fletcher is 7 Larry is 9 And they're all mammals, of course.
Reply
#5
It works on my end too but with an error
Error:
Traceback (most recent call last): File "C:\Python36\kodovi\pets_class.py", line 52, in <module> print(Pets.dogs) AttributeError: type object 'Pets' has no attribute 'dogs'
Reply
#6
It's not easy for my to see line 52 Shocked when you have only posted 49 lines.
If you remove line 33 the you will get AttributeError on print(Pets.dogs).
Just comment it out #print(Pets.dogs),but i dont know what's on line 50/51 Wink
Reply
#7
Here we go again:
# Parent class
class Dog:

    # Class attribute
    species = 'mammal'

    # Initializer / Instance attributes
    def __init__(self, name, age):
        self.name = name
        self.age = age
	
    # instance method
    def description(self):
        return "{} is {} years old".format(self.name, self.age)

    # instance method
    def speak(self, sound):
        return "{} says {}".format(self.name, sound)

# Child class (inherits from Dog class)
class RussellTerrier(Dog):
    def run(self, speed):
        return "{} runs {}".format(self.name, speed)

# Child class (inherits from Dog class)
class Bulldog(Dog):
    def run(self, speed):
        return "{} runs {}".format(self.name, speed)
		
# Parent class
class Pets:
	
	dogs = []
	
	def __init__(self, dogs):
		self.dogs = dogs

my_dogs = [
    Bulldog("Tom", 6),
	RussellTerrier("Fletcher", 7),
	Dog("Larry", 9)
]

# Instantiate the Pets class
my_pets = Pets(my_dogs)

print(f'I have {len(my_pets.dogs)} dogs.')
for dog in my_pets.dogs:
	print(f'{dog.name} is {dog.age}')
print(f'And they\'re all {dog.species}s, of course.')

print(Pets.dogs)
print(my_pets.dogs)
I just complicated without a reason, basically without dogs list I can't print Pets class and my_pets instance.
Reply
#8
Looks okay,if as test remove line 33 and 52,you are missing a empty list [] that's not used.
Reply
#9
I'm working on a similar code that looks like this:

class Pets:
	
	dogs = []
	
	def __init__(self, dogs):
		self.dogs = dogs
	
	def walk(self):
		for dog in self.dogs:
			print(dog.walk())


class Dog:
	
	species = 'mammal'
	
	def __init__(self, name, age):
		self.name = name
		self.age = age
		self.is_hungry = True
		
	def description(self):
		return self.name, self.age
		
	def speak(self, sound):
		return f'{self.name} says {self.sound}'
	
	def eat(self):
		self.is_hungry = False
	
	def walk(self):
		return f'{self.name} is walking!'
		
class RussellTerrier(Dog):
	def run(self, speed):
		return f'{self.name} runs {self.speed}'

class Bulldog(Dog):
	def run(self, speed):
		return f'{self.name} runs {self.speed}'

my_dogs = [
    Bulldog("Tom", 6),
	RussellTerrier("Fletcher", 7),
	Dog("Larry", 9)
]

my_pets = Pets(my_dogs)

print(f'I have {len(my_pets.dogs)} dogs.')

are_my_dogs_hungry = False
for dog in my_pets.dogs:
	if dog.is_hungry:
		are_my_dogs_hungry = True

if are_my_dogs_hungry:
	print("My dogs are hungry.")
else:
	print("My dogs are not hungry.")

my_pets.walk()
Let's focus on lines 8-10, 31-32, 62. I don't understand how are Pets and Dog class connected so that outcome of the line 62 is
Output:
Tom is walking! Fletcher is walking! Larry is walking!
Pets and Dog classes are not parent-child. How computer knows to pick up method walk() from both classes?
Reply
#10
Pets.walk is defined on line 8. When you call it on line 62, it in turn calls dog.walk (line 10) for each dog in self.dogs (line 9). So it knows to pick up the Dog class walk method because you told (programmed) it to.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020