Python Class Pet Program - python

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

Related

unpack from parent class

So I have been making an RPG game and run into some troubles with inheritance and unpacking.
I have tried to make a simple version of the problem I am having:
class Animal():
def __init__(self,name):
self.name = name
def say_noise(self):
noise = "I am an animal"
by_who = "Animal"
return noise,by_who
class Dog(Animal):
def __init__(self,name):
self.name = name
def say_noise(self):
Animal.say_noise(self)
animal = Animal("man")
doggy = Dog("name")
What I want to do is return the same 2 things in the Animal class and the Dog class.
Now when I do say_noise() with my Animal it works fine, as it returns:
('I am an animal', 'Animal')
However, it does not return anything when I do it with the Dog class, and I tried unpacking them as well (which is what I aim to do in my real code), but when I do this.
a,b =doggy.say_noise()
it just returns this:
TypeError: cannot unpack non-iterable NoneType object
How can I return the same thing with the same class method, by only inheriting it from the parent class?
It's because you are not returning anything from Dog classes say_noise method.
Update your code like this,
class Animal():
def __init__(self, name):
self.name = name
def say_noise(self):
noise = "I am an animal"
by_who = "Animal"
return noise, by_who
class Dog(Animal):
def __init__(self, name):
self.name = name
def say_noise(self):
return Animal.say_noise(self)
animal = Animal("man")
doggy = Dog("name")
a, b = doggy.say_noise()

How do I write a Python class taking other super class objects as parameters

Lets assume that I have a class called Person, and a class that inherits this called Group. Person has an attribute called name and one called age. When I create a Group I want to pass n person objects and their new name is a combo of names, and their new age is their combined age.
also for the hell of it, going to keep track of how many people, and how many groups there are separately (just so inheriting makes any sense in this example.)
class Person:
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
self.id = make_person() # count is also the person's id in this example
def __str__(self):
return f'Name: {self.name} Age: {self.age}'
#classmethod
def make_person(cls):
cls.count += 1
return cls.count
class Group(Person):
def __init__(self, *people):
#not sure how to do this, Below Does Not Work, something like
new_name = self.make_group(people)
new_age = self.new_age(people)
self.name = new_name
self.age = new_age
super().__init__(self.new_name, self.new_age)
def make_group(self, *people):
return (' & ').join([person.name for person in People])
def new_age(self, *people):
return sum([person.age for person in people])
then you would think i could write
anne = Person('Anne', 20)
bob = Person('Bob', 20)
carl = person('Carl', 25)
couple = Group(anne, bob)
threesome = Group(anne, bob, carl)
print(couple)
print(threesome)
but this doesnt work. For some reason the group class isnt getting the people object i pass, or i'm defining it wrong...any ideas?
What you have written is that a Group is a particular type of Person. This doesn't seem quite right to me. Regardless, here is a version that will run and give the desired output:
class Person:
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
self.id = Person.make_person() # count is also the person's id in this example
def __str__(self):
return f'Name: {self.name} Age: {self.age}'
#classmethod
def make_person(cls):
cls.count += 1
return cls.count
class Group(Person):
def __init__(self, *people):
#not sure how to do this, Below Does Not Work, something like
new_name = self.make_group(*people)
new_age = self.new_age(*people)
self.name = new_name
self.age = new_age
super().__init__(self.name, self.age)
def make_group(self, *people):
return (' & ').join([person.name for person in people])
def new_age(self, *people):
return sum([person.age for person in people])
anne = Person('Anne', 20)
bob = Person('Bob', 20)
carl = Person('Carl', 25)
couple = Group(anne, bob)
threesome = Group(anne, bob, carl)
print(couple)
print(threesome)
Changes from your code:
some typos with capital letters
put a * before people when passing it
take care of variable scope

Return subclass when calling parent class

I want to get instance of one of subclasses when trying get instance of a superclass (parent class) depending on arguments. For example, I have parent class(I'm using python3):
class Man:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
print("Hello! My name is {}.".format(self.name))
And subclass:
class YoungMan(Man):
def say_hello(self):
print("Hey, man! Wazap?")
If age of Man less 30, I want it become YoungMan:
John = Man('John', 25)
type(John) #<class '__main__.YoungMan'>
John.say_hello() #Hey, man! Wazap?
I tried solve it with Man.__new__():
class Man:
def __new__(cls, name, age):
if age < 30:
return YoungMan(name, age)
else:
return super(Man, cls).__new__()
...
But John.say_hello() returns Hello! My name is John. So Man methods override YoungMan methods. After I tried use metaclass for Man:
class ManFactory(type):
def __call__(self, name, age):
if age < 30:
return YoungMan(name, age)
class Man(metaclass=ManFactory):
...
But it lached on ManFactory.__call__().
I understand that I can use a funtion John = get_Man(name, age) which returns right class, but it isn't so handsome. My question is about how do it like this:
John = Man('John', 25)
type(John) #<class '__main__.YoungMan'>
John.say_hello() #Hey, man! Wazap?
Brad = Man('Brad', 54)
type(Brad) #<class '__main__.Man'>
Brad.say_hello() #Hello! My name is Brad.
Not sure if this is good practice but you could set self.__class__:
class Man:
def __init__(self, name, age):
if age < 30: self.__class__ = YoungMan
self.name = name
self.age = age
def say_hello(self):
print("Hello! My name is {}.".format(self.name))
class YoungMan(Man):
def say_hello(self):
print("Hey, man! Wazap?")
a = Man("Brad", 15)
print(type(a))
>>><class '__main__.YoungMan'>
a.say_hello()
>>>Hey, man! Wazap?
The main problem with this method is that the YoungMan would still be constructed by Man.__init__() so the classes would have to be compatible. Creating a function get_man() is still the best solution.

Object not inheretinting functions from super class?

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

Python3 Bound method

Hi i have a python file that contains the class pets and a file conatins the class people and a main file
the code is this:
the pets code:
class Pet:
def __init__(self, name, age, sound, type):
self.name = name
self.age = age
self. sound = sound
self. type = type
class Dog(Pet):
def __init__(self, name, age):
super().__init__(name, age, "How How", "Dog")
class Cat(Pet):
def __init__(self, name, age):
super().__init__(name, age, "Mewo", "Cat")
this is the peoples file:
import Pets
class Person:
def __init__(self, gender, name, age):
self.gender = gender
self.name = name
self.age = age
self.pets = []
def addPet(self, pet):
if isinstance(pet, Pets.Pet):
self.pets.append(pet)
else:
print("This is not a pet pls try again.")
def printPets():
print("He has:")
for pet in self.pets:
print("A: " + pet.type+ " Named: " + pet.name)
And this is the Main file:
from Person import Person
import Pets
def Main():
p1 = Person("Male", "Bob", 18)
p1.addPet(Pets.Cat("Mitzi", 2))
p1.addPet(Pets.Dog("Rexi", 5))
print(p1.printPets)
if __name__ == "__main__":
Main()
the output that i get is:
<bound method Person.printPets of <Person.Person object at 0x7f413e3604e0>>
what is this and how do i fix it ??
thanx.
What you need is print(p1.printPets())
You need to invoke the method.
Else what you are doing is printing the method and what Python gives you is the method type (bound), instance type to which it belongs and address of the instance.
You just need to include () inside print() like this:
print(s1.avg())

Categories