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.
Related
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.
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())
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.
So I keep getting the
error: " AttributeError: 'Dog' object has no attribute '_Dog__name'"
The thing is print(spot.get_name()) works fine. Also when I tried spot.multiple_sounds() that fails similarly. I think the issue is when I try to call object attributes from the super class in functions in object definition. I can't understand why though. I'm doing all this from a tutorial and the code is identical to his. I think it may be because he's using python2.x and I'm using spyder python3.x but I have no idea. Any help is greatly appreciated.
import random
import os
import sys
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.__height)
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 {} cm tall and {} kilograms and says {}".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().__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 and {} kilograms says {} and his owner is {}".format(self.__name, self.__height, self.__weight, self.__sound, self.__owner)
def multiple_sounds(self, how_many=None):
if how_many is None:
print(self.getsound())
else:
print(self.getsound()*how_many)
spot = Dog("Spot", 53, 27, "Ruff", "Some Guy")
print(spot.get_name())
print(spot.toString())
In python, __fieldName emulates the private field, means two underscores that in field name. So such fields can not be reached from derived classes, but you still can get them using getter.
Any attribute or method that begins with '__' is only accessible by that name from functions in that same class. Not from other classes, not even from subclasses.
class A:
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
class B(A):
def get_name_capitalized(self):
return self.__name.upper()
b = B('Bob')
print(b.get_name()) # prints 'Bob'
print(b.get_name_capitalized()) # fails
In the code above, calling A.get_name() accesses the A instance's __name attribute successfully. But B.get_name_capitalized() fails with the error "AttributeError: 'B' object has no attribute '_B__name'
". "__" names get mangled by the compiler so that they are not accessible as-is. If the code in get_name_capitalized is changed to:
return self._A__name.upper()
then it would work, so these attributes are accessible, but you have to use the mangled name to get at them.
That is how Python has been since 1.x, and is nothing new with Python 3.
Names that begin with double-underscores and end with zero or 1 underscore are python's answer to private variables. Python munges them to be __Class_name to make them private to the class and not its inherited subclasses. The idea is to let you have intra-class names without subclasses messing with them. Obviously this is easily subverted by using the well-known munged name, but then, python is a dynamic language.
See Private Variables
I am working on an assignment for Python Programming 157 at my school.
I need to write a class called Pet that has the following data attributes:
__name (for the name of the pet)
__animal_type (Examples: "Cat", "Dog", and "Hamster" )
__age (for the pet's age)
__height (for the pet's height)
It needs to include
set_name
get_name
I have tried like 4 times and cannot seem to get it right... any clues on getting it started?
# The Pet Program.
class PetProgram:
# The __init__ method accepts an argument for the program
# and adds it to the __pets attribute.
def __init__(self, pet):
self.__pets = pet
# The name will add to the pet attribute.
def name(self, name):
self.__pets = name
def age(self, age):
self.__pets = age
def animal(self, animal):
self.__pets = animal
def height(self, height):
self.__pets = height
# The pets_return will show you the list.
def pets_return(self):
return self.__pets
# The Pet Program.
import petsprogram
def main():
# Enter the name.
petname = input('What is the name of the pet: ')
print 'This will be added to the record.'
savings.name(petname)
# Display the list.
print petsprogram
main()
Above is my latest try...no such luck...any help? Thanks in advance...
A class is not a program, a class should model a thing, like a pet. Therefore, to start off, you should name your class appropriately.
class Pet(object): # Pet derives from the object class, always do this
Now I think you want a constructor that takes the name of the pet, and perhaps the type of pet as well, so we'll define that.
def __init__(self, pet_name, pet_type):
self.pet_name = pet_name
self.pet_type = pet_type
You also need a get and set for the name:
def get_name(self):
return self.pet_name
def set_name(self, pet_name):
self.pet_name = pet_name
To use this class, you instantiate it into an instance of the class:
puppy = Pet('Rover', 'Dog')
puppy.get_name() # prints Rover
I hope that's enough to get you going. You should read up on OOP in Python as mentioned in the comments.
First, why are you using "private" __attributes? That doesn't seem warranted.
Second, you're assigning all your properties to the same instance variable:
self.__pets = pet
self.__pets = name
self.__pets = age
self.__pets = animal
self.__pets = height
You should be using something like
def __init__(self, pet, name, age, animal, height):
self.pet = pet
self.name = name
self.age = age
self.animal = animal
self.height = height
and you should definitely read the tutorial on classes before venturing any further.
I'm not sure where the __pets binding comes into play. Your initial description doesn't say anything about that. I would not have expected an object that represents a pet, as in, a singular pet, to have an attribute that was a list of pets. I would expect something like:
class PetProgram:
def __init__(self, name ='', age=0, type='Unknown', height=0):
self.__name = name
self.__age = age
self.__animal_type = type
self.__height = height
def get_name(self):
return self.__name
def set_name(self, name):
self.__name = name
I'm also not sure where the imports petprogram comes from... is that perchance what your supposed to call your module, and then the instructor has provided that as something you're supposed to run to test it?
(also, what's with all the __under_scores? is this something your teacher is encouraging?)
How does something like this look?
>>> class Pets:
def set_Name(self,name):
self.name=name
def get_Name(self):
return self.name
def set_Atype(self,atype):
self.atype=atype
def get_Atype(self):
return self.atype
def set_Age(self,age):
self.age=age
def get_Age(self):
return self.age
def set_Height(self,height):
self.height=height
def get_Height(self):
return self.height