How to get class inheritence working in Python? - 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.

Related

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.

How can I define a method where I need attributes from different classes?

I got a program from my professor where I had to do some tasks. Since we're currently learning "inheritance with classes", I'm not that good at it yet. We had been given a task where it says "Extend the output of mouse, screen and keyboard so that the user knows which computer in which room they belong to". I did this, but I'm not sure if it's true or if there is a better solution. Can anyone explain to me whether the whole thing can be solved better and if so, why? I have defined a method in each class where I get this as an output, but is there a better way where I only have to define a method once and this applies to all other classes? Thanks in advance
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, room, width, height, computer):
super().__init__(name)
self.__room = room
self.__width = width
self.__height = height
self.__computer = computer
def as_text(self):
return "%s with resolution %dx%d" % (super().as_text(), self.__width, self.__height)
def screen_location_computer(self):
return 'The screen with the height {} and width {} is located in Room {} and belongs to the computer {}'.format(self.__height, self.__width , self.__room.get_name(), self.__computer)
class Keyboard(Device):
__language = 'English'
def __init__(self, name, room, language, computer):
super().__init__(name, room)
self.__language = language
self.__computer = computer
def keyboard_location_computer(self):
return 'The keyboard with the language {] is located in Room {} and belongs to the computer {}'.format(self.__language, self.__room.get_name(), self.__computer)
class Mouse(Device):
__type = 'Gaming Mouse'
def __init__(self, name, room, type, computer):
super().__init__(name, room)
self.__type = type
self.__computer = computer
def mouse_location_computer(self):
return 'The mouse with the type {] is located in Room {} and belongs to the computer {}'.format(self.__type, self.__room.get_name(), self.__computer)
You should try to regroup all common attributes and methods in the super class and leave only the specialized attributes in the subclasses, this way you can minimize the need of methods and arguments.
Idem for the method I renamed 'description' : one part is common to all instances (the end) while another (the beginning) is specific. Let super handle the common part and pass it the specialized part to assemble the whole string.
(I removed some classes and attributes for the simplicity of the example)
class Device():
__computer = None
__name = None
__room = None
def __init__(self, name, computer, room):
self.__name = name
self.__computer = computer
self.__room = room
def room(self):
return self.__room
def name(self):
return self.__name
def description(self, str):
return '{} is located in Room "{}" and belongs to the computer "{}"'.format(str, self.__room, self.__computer.name())
class Computer(Device):
def __init__(self, name, room):
super().__init__(name, self, room)
class Screen(Device):
__width = "1920"
__height = "1080"
def __init__(self, name, computer, width, height):
super().__init__(name, computer, computer.room())
self.__width = width
self.__height = height
def description(self):
return super().description('The screen with the height {} and width {}'.format(self.__height, self.__width))
class Mouse(Device):
__type = 'Gaming Mouse'
def __init__(self, name, computer, type):
super().__init__(name, computer, computer.room())
self.__type = type
def description(self):
return super().description('The mouse with the type {}'.format(self.__type))
cpt = Computer("Acer", "Classroom 12")
cpt2 = Computer("iMac 15", "Classroom 38")
screen = Screen("27 inch", cpt2, 1920, 1080)
mouse = Mouse("Mouse", cpt, "Gaming")
print (screen.description())
print (mouse.description())

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

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

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)

Python Inheritance - Instance Has No Attribute

I'm new to python and just trying to test the syntax and get to know it.
The code below works fine except for when I get to inheritance. The final command "toString" function is not working and I can't for the life of me figure out why.
I'm sure I'm not doing something the most efficient way, but even if there's a more efficient way I'd first like to understand why what I'm doing is wrong. thanks a lot. Please let me know if I need to clarify anything
#!/bin/python
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 self.__heiight
def set_weight(self,weight):
self.__weight=weight
def get_weight(self):
return 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 {} inches tall, {} lbs, and says {}".format(self.__name, self.__height,self.__weight,self.__sound))
objCat = Animal('Whiskers', 33, 10, 'Meow')
print (objCat.toString())
# Attempt Inheritance
class cDog(Animal):
__owner=""
def __init__(self,name,height,weight,sound,owner):
self.__owner=owner
Animal.__init__(self,name,height,weight,sound)
def __str__(self):
return ("{}".format(self.__height))
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 {} inches tall, {} lbs, says {}, and is owned by, {}".format(self.__name,self.__height,self.__weight,self.__sound,self.__owner))
objDog = cDog('Brewsky', 20, 75, 'Ruff', 'Jared')
print (objDog.toString())
In your Animal class, the double underscore before the name of the attributes has made them (sort of) private.
Just delete the double underscore (or change it to one underscore, if you want to keep a weak indicator) and it will be fixed.
See this question for more information.

Categories