AttributeError: 'Dog' object has no attribute 'get_height' - python

Should you need it, the tutorial I am following is Python Programming by #Derek Banas:
This lesson is demonstrating class object inheritance
class Animal:
__name = ""
__height = 0
__weight = 0
__sound = 0
def __init__(self, name, height, weight, sound):
self.__name = name
self.__height = height
self.__weight = weight
self.__sound = sound
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
def get_type(self):
print("Animal")
def toString(self):
return "{} is {} cm tall and {} kilograms and {}".format(self.__name,
self.__height,
self.__weight,
self.__sound)
cat = Animal('Whiskers', 33, 10, 'Meow')
print(cat.toString())
class Dog(Animal):
__owner = ""
def __init__(self, name, height, weight, sound, owner):
self.__owner = owner
super(Dog, self).__init__(name, height, weight, sound)
def set_owner(self, owner):
self.__owner = owner
def get_owner(self):
return self.__owner
def get_type(self):
print("Dog")
def toString(self):
return "{} is {} cm tall & {} kgrms and {} hi
{}".format(self.get_name(),
self.get_height(),
self.get_weight(),
self.get_sound(),
self.get_owner())
""" I am getting this runtime error message python version 3.6
Here is the error:
File "C:/Watson/HDM/tutorial_py1.py", line 192, in toString
self.get_height(),
AttributeError: 'Dog' object has no attribute 'get_height' """

Dog object is not having any attribute 'get_height' as get_height() function is not declared in the class before. You need to add the method in the class:
def get_height(self, name):
return self.__height

Related

Why do I keep getting this Attribute Error?

Every time I run my code it pops up the message saying "'ICU' object has no attribute '_name'. Did you mean: 'name'?" I can not figure out how to fix it. I've tried changing the name of the accessors and mutators but still can't figure out how to solve it. Any suggestions?
Here's my code:
class Patient:
def __init__(self, name, age):
self.name = name
self.age = age
self.weight = 150
#property
def age(self):
return self._age
#age.setter
def age(self, newValue):
if newValue > 0:
self._age = newValue
else:
self._age = 0
#property
def weight(self):
return self._weight
#weight.setter
def weight(self, newValue):
if newValue >=0 and newValue <= 1400:
self._weight = newValue
#IncreaseAge
def increaseAge(self):
self.age = self.age + 1
class In(Patient):
def __init__(self, name, age, stay):
self.name = name
self.age = age
self.stay = stay
#property
def stay(self):
return self._stay
#stay.setter
def stay(self, value):
self._name = value
def __str__(self):
print("IN-" + self._name + self._age + self.weight + self._stay)
class Out(Patient):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
print("OUT-" + self._name + self._age + self._weight)
class ICU(In):
def __init__(self, name, age):
self.name = name
self.age = age
self.days = 5
class CheckUp(Out):
def __init__(self, name, age):
self.name = name
self.age = age
Here's the rest of the instance:
# Create three patient objects and print them out
p1 = ICU("Ben Dover", 0)
p2 = ICU("Helen Hywater", -15)
p3 = CheckUp("Amanda Lynn", 45)
p4 = ICU("Chester Minit", 12)
p5 = In("Don Keigh", 89, 10)
p6 = Out("Kay Oss ", 45)
print ("\tStatus\tName\t\tAge\tWeight\tStay")
print ("-" * 55)
print ("p1:\t{}".format(p1))
print ("p2:\t{}".format(p2))
print ("p3:\t{}".format(p3))
print ("p4:\t{}".format(p4))
print ("p5:\t{}".format(p5))
print ("p6:\t{}".format(p6))
print ("-" * 55)
# Change their ages and print them out
p1.age = -5
p2.age = 100
for i in range(6):
p3.increaseAge()
p4.age = 0
p5.increaseAge()
p6.age = 42
print ("p1:\t{}".format(p1))
print ("p2:\t{}".format(p2))
print ("p3:\t{}".format(p3))
print ("p4:\t{}".format(p4))
print ("p5:\t{}".format(p5))
print ("p6:\t{}".format(p6))
print ("-" * 55)
# Change other instance variables and print them out
p1.weight = 2000
p1.stay = 3
p2.name = "Justin Thyme"
p2.weight = 220
p2.stay = 0
p3.weight = -50
p4.weight = 1400
p5.weight = 0
p5.stay = 21
p6.weight = 1401
print ("p1:\t{}".format(p1))
print ("p2:\t{}".format(p2))
print ("p3:\t{}".format(p3))
print ("p4:\t{}".format(p4))
print ("p5:\t{}".format(p5))
print ("p6:\t{}".format(p6))
print ("-" * 55)
It's because your variable name is different.
Replace you code from:
#stay.setter
def stay(self, value):
self._name = value
To:
#stay.setter
def stay(self, value):
self.name = value
In Python, constructors - like all other methods - can be overridden. That is once you define __init__ in child classes, the base class method is never called. This is what's causing the error.
You need to explicitly call the base class like like this:
class ICU(In):
def __init__(self, name, age):
self.name = name
self.age = age
self.days = 5
In.__init__(self, name, age, 10) # stay = 10 since it's not an input parameter in the ICU __init__ method.
This needs to be done in every base class. So you'd do something similar in the In class as well.
The problem comme to the fact that "format" is calling "__ str__" on your instances but when "__ str__" get called, some of your instance doesn't have a value for "_name" or "_stay" or "_weight"...see your " __ init __ " method for each instance and execute " __ str __" after you will see the problem. so to handle this case you have the following simple solution
class In(Patient):
def __init__(self, name, age, stay):
self.name = name
self.age = age
self.stay = stay
#property
def stay(self):
return self._stay
#stay.setter
def stay(self, value):
self._name = value
def __str__(self):
x = (
getattr(self, '_name', ''),
getattr(self, '_age', ''),
self.weight or ''
getattr(self, '_stay', ''),
)
return ("IN-%s %s %s %s")%(*x)
class Out(Patient):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
x = (
getattr(self, '_name', ''),
getattr(self, '_age', ''),
getattr(self, '_stay', ''),
)
return "OUT- %s %s %s"%(*x)
But your classes are not well designed, see below something interesting
class Patient:
def __init__(self, name, age, weight=150):
self._name= name
self._age = age
self._weight = weight
#property
def name(self):
return self._name
#name.setter
def name(self, value):
assert isinstance(value, str)
self._name = value
#property
def age(self):
return self._age
#age.setter
def age(self, value):
assert isinstance(value, int)
self._age = value
#property
def weight(self):
return self._weight
#weight.setter
def weight(self, value):
assert isinstance(value, int)
self._weight = value
def __str__(self):
return f"{self.__class__.__name__.upper()}-{self.name} {self.age} {self.weight}"
class Out(Patient):
pass
class In(Patient):
def __init__(self, name, age, stay, weight=150):
super().__init__(name, age, weight=weight)
self._stay = stay
#property
def stay(self):
return self._stay
#stay.setter
def stay(self, value):
assert isinstance(value, int)
self._stay = value
def __str__(self):
return f"{super().__str__()} {self.stay}"
class ICU(In):
def __init__(self, name, age):
super().__init__(name, age, 5)
class CheckUp(Out):
def __init__(self, name, age):
super().__init__(name, age)
Also note that "increaseAge" method is not defined on your instances

How to define a method which return attributes from other class

In my program I have the following question. How can I define a method in the class 'Mouse' 'Keyboard' and 'Screen' so that they return the room and the computer they belong to + the associated attribute of the class (so for the keyboard class this would be: 'The computer {} is located in the room {} and has the language {} ') Can someone tell me how I can define such a method for these 3 classes without changing the program itself? The method should be defined for each class seperated. The exact task is "Extend the output of maus, screen and tastatur so that the user knows which computer in which room they belong".
I've tried to define the following method:
def as_text(self):
return "{} an {} in {}".format(self.__name, self.__computer, self.__computer.__room)
In my three classes I have build in a reference to computer. My Class Computer has a reference to room, so I've tried to call it with self.__computer.__room but that doesn't work and I'm not sure how to call this attribute.
Here is my code:
class Room:
__name = "unknown"
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
class Device:
__name = "Device"
def __init__(self, name):
self.__name = name
def as_text(self):
return "%s" % (self.__name)
class Computer(Device):
__ip = "unknown"
def __init__(self, name, ip, room):
super().__init__(name)
self.__ip = ip
self.__room = room
def as_text(self):
return "%s with ip=%s" % (super().as_text(), self.__ip)
class Laptop(Computer):
def __init__(self, name, room, ip, with_case = True):
super().__init__(name, room, ip)
self.__with_case = with_case
def as_text(self):
if (self.__with_case):
return "%s with case" % super().as_text()
else:
return super().as_text()
class Screen(Device):
__width = "1920"
__height = "1080"
def __init__(self, name, width, height, computer):
super().__init__(name)
self.__width = width
self.__height = height
self.__computer = computer
def as_text(self):
return "{} an {}".format(self.__name, self.__computer)
class Tastatur(Device):
__language = 'English'
def __init__(self, name, language, computer):
super().__init__(name)
self.__language = language
self.__computer = computer
class Maus(Device):
__type = 'Gaming Mouse'
def __init__(self, name, type, computer):
super().__init__(name)
self.__type = type
self.__computer = computer
Your request is not particularly clear, here what I got.
This is my method for the Screen Class:
def as_text(self):
return "{} an {} in {}".format(super().as_text(), self.__computer.as_text(), self.__computer.display_room())
super().as_text()
This calls the method as_text from the parent class Device.
self.__computer.as_text()
This calls the as_text() method from an instance of the Computer class, which is an attribute of your class Screen.
self.__computer.display_room()
This calls the method display_room() from the Computer class, I created it and returns the Room's name.
def display_room(self):
return self.__room.get_name()
Now you should be able to write methods for Tastur and Maus yourself.

Python - TypeError: module.__init__() takes at most 2 arguments (3 given)

Trying my hand at Python inheritance. I need your help on how to fix an error.
I have 2 classes: Person (super class )& Contact (sub class).
I get the following error when trying to run Contact:
"Contact.py", line 3, in <module>
class Contact(Person):
TypeError: module.__init__() takes at most 2 arguments (3 given)
Thanks in advance
Below is my code:
class Person:
__name=""
__age=0
def __init__(self, name, age):
self.__name = name
self.__age = age
def set_name(self, name):
self.__name = name
def set_age(selfself, age):
self.__age = age
def get_name(self):
return self.__name
def get_age(selfself):
return self.__age
def getInfo(self):
return "Name is: {} - Age is: {}".format(self.__name, self.__age)
# ----------------------------------------------------
import Person
class Contact(Person):
__method=""
def __init__(self, name, age, method):
super().__init__(name, age)
self.__method = method
def set_method(self, method):
self.__method = method
def get__method(self):
return self.__method
def getInfo(self):
return "Name is: {} - Age is: {} - Contact Info: {}".format(self.__name, self.__age, self.__method)
person2 = Contact("Adam Smith", 19, "Email: adam.smith#abcde.net")
print(person2.getInfo())
First of all, the indentation is messed up!
If Person is in a separate file, import the file name without extension, like this:
class Person:
def __init__(self, name, age):
self.__name = name
self.__age = age
def set_name(self, name):
self.__name = name
def set_age(self, age):
self.__age = age
def get_name(self):
return self.__name
def get_age(self):
return self.__age
def getInfo(self):
return "Name is: {} - Age is: {}".format(self.__name, self.__age)
# ----------------------------------------------------
from person import Person # assumed your Person class is in person.py
class Contact(Person):
__method=""
def __init__(self, name, age, method):
super().__init__(name, age)
self.__method = method
def set_method(self, method):
self.__method = method
def get__method(self):
return self.__method
def getInfo(self):
return "Name is: {} - Age is: {} - Contact Info: {}".format(self.get_name(), self.get_age(), self.__method)
person2 = Contact("Adam Smith", 19, "Email: adam.smith#abcde.net")
print(person2.getInfo())
Access the parent class's private fields through its methods.

How to get class inheritence working in Python?

I am supposed to create a class called Dog(Animal) which is inheriting from Class Animal. However after I run this code, I got errors that I do not understand:
The problem is solved, no further questions that I see at the moment
class Animal:
__name = ""
__height = 0
__weight = 0
__sound = 0
def __init__(self, name, height, weight, sound):
self.__name = name
self.__height = height
self.__weight = weight
self.__sound = sound
#def set_name(self, name):
#self.__name = name
def get_name(self):
return self.__name
def get_height(self):
return str(self.__height)
def get_weight(self):
return str(self.__weight)
def get_sound(self):
return self.__sound
def get_type(self):
print("Animal")
def toString(self):
return "{} is {} cm tall and {} kilograms and says{}".format(self.__name,
self.__height,
self.__weight,
self.__sound)
cat = Animal('pussy', 33, 10, 'meow')
print(cat.toString())
print(cat.get_type())
print(cat.get_sound())
class Dog(Animal):
__owner = ""
def __init__(self, name, height, weight, sound, owner):
self.__owner = owner
super(Dog, self).__init__(name, height, weight, sound)
def set_owner(self, owner):
self.__owner = owner
def get_owner(self):
return self.__owner
def get_type(self):
print("Dog") # Dog object
def toString(self):
return "{} is {} cm tall and {} kilograms and says{} its owner is {}".format(self.__name,
self.__height,
self.__weight,
self.__sound,
self.__owner)
spot = Dog("kaili", 22, 33, "woof", "Jiahui")
print(spot.toString())
Change this line:
class Animal:
to this:
class Animal(object):
This post explains it quite well.
After I added metaclass = type at the beginning, the problem is solved. I am not quite sure but seems the metaclass allows python2.7 to access python3's library.

this constructor takes no arguments: python

import random
import sys
import os
class Animal :
__name=""
__height=0
__weight=0
__sound=0
def __init__(self, name, height, weight, sound):
self.__name=name
self.__height=height
self.__weight=weight
self.__sound=sound
def set_name(self,name):
self.__name =name
def get_name(self):
return self.__name
def set_height(self,height):
self.__height =height
def get_height(self):
return str(self.__height)
def set_weight(self,weight):
self.__weight =weight
def get_weight(self):
return str(self.__weight)
def set_sound(self,sound):
self.__sound =sound
def get_sound(self):
return self.__sound
def get_type(self):
print("Animal")
def toString(self):
return"{} is {} cm tall and {} kilograms and say{}".format(self.__name, self.__height,self.__weight,self.__sound)
cat = Animal('ruby',33,10,'meow')
print(cat.toString())
Error message:
Traceback (most recent call last):
File "python", line 37, in <module>
TypeError: this constructor takes no arguments
class methods should be indented to be within the class
import random
import sys
import os
class Animal :
__name=""
__height=0
__weight=0
__sound=0
def __init__(self, name, height, weight, sound):
self.__name=name
self.__height=height
self.__weight=weight
self.__sound=sound
def set_name(self,name):
self.__name =name
def get_name(self):
return self.__name
def set_height(self,height):
self.__height =height
def get_height(self):
return str(self.__height)
def set_weight(self,weight):
self.__weight =weight
def get_weight(self):
return str(self.__weight)
def set_sound(self,sound):
self.__sound =sound
def get_sound(self):
return self.__sound
def get_type(self):
print("Animal")
def toString(self):
return"{} is {} cm tall and {} kilograms and say{}".format(self.__name, self.__height,self.__weight,self.__sound)
cat = Animal('ruby',33,10,'meow')
print(cat.toString())
This results in
ruby is 33 cm tall and 10 kilograms and saymeow
classes have to be defined in one block. Also getters and setters are disadvised. The class-attributes should be deleted, because they are set as instance attributes.
class Animal:
type = "Animal"
def __init__(self, name, height, weight, sound):
self.name = name
self.height = height
self.weight = weight
self.sound = sound
def __str__(self):
return "{0.name} is {0.height} cm tall and {0.weight} kilograms and say {0.sound}".format(self)
cat = Animal('ruby',33,10,'meow')
print(cat)

Categories