Python - passing class instantiation to a function - python-3.x

I need to pass the class instantiation to a function.
This is what i wrote so far:
def func(dog):
print(dog.get_name)
def main():
new_dog = dog(name, age, weight)
func(new_dog)
but when i try to execute it i get the following error message:
<bound method animal.get_name of <classes.dog object at 0x7f9611002b70>
Basically i have a class file with the following classes:
animal - Mother class(it include the name getter)
dog - Child class of animal
cat - Child class of animal
What i'm doing wrong?
--EDIT--
Structure of the classes:
class animal:
# public vars
name = ""
age = 0
weight = 0.00
animal_type = ""
# public constructor
def __chars(self):
print("His name is: " + self.name)
print("He is: " + str(self.age) + " y.o.")
print("His weight: " + str(self.weight) + " Kg")
def __init__(self, name, age, weight, animal_type):
self.name = name
self.age = age
self.weight = weight
self.animal_type = animal_type
print("A new animal has been created!")
self.__chars()
# public methods
def eat(self):
print("The animal eat!")
def drink(self):
print("The animal drink!")
def play(self):
print("The animal plays!")
def get_name(self):
return self.name
# public destructor
def __del__(self):
print('\n' + self.name + "has died :(")
# Child classes
class dog(animal):
__dlevel = None # dangerous level, it can be 0, 1 or more, it's private
# private methods
def set_dlevel(self, dlevel):
self.__dlevel = dlevel
print("Dangerous level set!")
def get_dlevel(self):
# CHeck if the level is define
if not self.__dlevel:
print("Dog dangerous level not found")
sys.exit(1)
# if is equal or more than 1 is dangerous
if int(self.__dlevel) >= 1:
print("The dog is dangerous, be careful while playing with him!")
# otherwise it's a quiet dog
elif int(self.__dlevel) <= 0:
print("The dog isn't dangerous")

I figured out the real problem: i was printing the function, not calling it.
So instead i've used
def func(animal):
print(animal.get_name())
def main():
new_dog = dog("max", 14, 11, "dog")
func(new_dog)

Related

How can I print the method from within a Class?

I have created two separate classes with the intent of creating instances of those Classes and accessing the methods within the Classes. However, when I run this code, I cannot print out the list of grades in the print.grades method.
'''
class Student:
def __init__(self, name, year):
self.name = name
self.year = year
self.grades = []
def add_grade(self, grade):
if type(grade) == Grade:
self.grades.append(grade)
else:
pass
def get_average(self):
sum_score = 0
for i in self.grades:
sum_score += i
ave = sum_score / len(grades)
return ave
def print_grades(self):
for i in self.grades:
print(i)
roger = Student("Roger van der Weyden", 10)
sandro = Student("Sandro Botticelli", 12)
pieter = Student("Pieter Bruegel the Elder", 8)
class Grade:
def __init__(self, score):
self.score = score
def is_passing(self, grade):
if grade >= self.minimum_passing:
return "Passing!"
else:
return "Not Passing"
minimum_passing = 65
new_Grade = Grade(100)
pieter.add_grade(new_Grade)
print(new_Grade.is_passing(100))
pieter.add_grade(90)
pieter.add_grade(100)
pieter.print_grades
'''

How can I return all values inside of a class variable?

I'm writing a text adventure game in Python and I'm curious on how I can go about listing all the items inside of the Room class
I'm very new to Python and have very limited practice.
# Declaring items and assigning them rooms
dingus = Item("Dingus", "This really dings.")
room["garden"].add_item(dingus)
flippers = Item("Flippers", "Webbed in nature.")
room["garden"].add_item(flippers)
# Declare all the rooms
room = {
'garden': Room("Garden",
"""The flowers are blooming wonderfully. To the south lies a dark path.""")
}
class Room:
def __init__(self, title, description):
self.title = title
self.description = description
self.items = []
self.items_in_room = ''
def __repr__(self):
print(f"-" * 40)
return (f"You are at the {self.title}.")
def add_item(self, item):
return self.items.append(item)
def list_items_in_room(self):
for item in self.items:
self.items_in_room += item
', '.split(self.items)
return self.items
class Item:
def __init__(self, name, description):
self.name = name
self.description = description
def __str__(self):
return f'{self.name} - {self.description}' + '\n' + "-" * 40
I'm expecting Room.list_items_in_room to list all the items in the room in a comma separated string.
I have re-arranged your code and also changed the function list_items_in_room. Also, have changed the __str__ function to __repr__ and removed the '-' * 40 (I couldn't understand why that's there).
class Room:
def __init__(self, title, description):
self.title = title
self.description = description
self.__items = []
# __ so that it's not modifiable without getter and setter functions
def __repr__(self):
print(f"-" * 40)
return (f"You are at the {self.title}.")
def add_item(self, item):
return self.__items.append(item)
def list_items_in_room(self):
return self.__items
class Item:
def __init__(self, name, description):
self.name = name
self.description = description
def __repr__(self):
return f'{self.name} - {self.description}'
# Declare all the rooms
room = {
'garden': Room("Garden",
"""The flowers are blooming wonderfully. To the south lies a dark path.""")
}
dingus = Item("Dingus", "This really dings.")
room["garden"].add_item(dingus)
flippers = Item("Flippers", "Webbed in nature.")
room["garden"].add_item(flippers)
print(room['garden'].list_items_in_room())
Output:
[Dingus - This really dings., Flippers - Webbed in nature.]

In OOP in python, are different instances of an object when initialised with a default value the same?

I am trying to understand object oriented programming. I am doing this by creating a small poker like program. I have come across a problem whose minimal working example is this:
For this code:
import random
class superthing(object):
def __init__(self,name,listthing=[]):
self.name = name
self.listthing = listthing
def randomlyadd(self):
self.listthing.append(random.randint(1,50))
def __str__(self):
return '\nName: '+str(self.name)+'\nList: '+str(self.listthing)
Aboy = superthing('Aboy')
Aboy.randomlyadd()
print(Aboy)
Anotherboy = superthing('Anotherboy')
Anotherboy.randomlyadd()
print(Anotherboy)
I expect this output :
Name: Aboy
List: [44]
(some number between 1 and 50)
Name: Anotherboy
List: [11]
(again a random number between 1 and 50)
But what I get is:
Name: Aboy
List: [44]
(Meets my expectation)
Name: Anotherboy
List: [44,11]
(it appends this number to the list in the previous instance)
Why is this happening? The context is that two players are dealt a card from a deck. I am sorry if a similar question exists, if it does, I will read up on it if you can just point it out. New to stack overflow. Thanks in advance.
For the non minimal example, I am trying this:
import random
class Card(object):
def __init__(self, suit, value):
self.suit = suit
self.value = value
def getsuit(self):
return self.suit
def getval(self):
return self.value
def __str__(self):
if(self.suit == 'Clubs'):
suitstr = u'\u2663'
elif(self.suit == 'Diamonds'):
suitstr = u'\u2666'
elif(self.suit == 'Hearts'):
suitstr = u'\u2665'
elif(self.suit == 'Spades'):
suitstr = u'\u2660'
if((self.value<11)&(self.value>1)):
valuestr = str(self.value)
elif(self.value == 11):
valuestr = 'J'
elif(self.value == 12):
valuestr = 'Q'
elif(self.value == 13):
valuestr = 'K'
elif((self.value == 1)|(self.value == 14)):
valuestr = 'A'
return(valuestr+suitstr)
class Deck(object):
def __init__(self,DeckCards=[]):
self.DeckCards = DeckCards
def builddeck(self):
suits = ['Hearts','Diamonds','Clubs','Spades']
for suit in suits:
for i in range(13):
self.DeckCards.append(Card(suit,i+1))
def shuffle(self):
for i in range(len(self)):
r = random.randint(0,len(self)-1)
self.DeckCards[i],self.DeckCards[r] = self.DeckCards[r],self.DeckCards[i]
def draw(self):
return self.DeckCards.pop()
def __str__(self):
return str([card.__str__() for card in self.DeckCards])
def __len__(self):
return len(self.DeckCards)
class Player(object):
def __init__(self,Name,PlayerHandcards = [],Balance = 1000):
self.Name = Name
self.Hand = PlayerHandcards
self.Balance = Balance
def deal(self,deck):
self.Hand.append(deck.draw())
def __str__(self):
return 'Name :'+str(self.Name)+'\n'+'Hand: '+str([card.__str__() for card in self.Hand])+'\n'+'Balance: '+str(self.Balance)
deck1 = Deck()
deck1.builddeck()
deck1.shuffle()
Alice = Player('Alice')
Alice.deal(deck1)
print(Alice)
Bob = Player('Bob')
Bob.deal(deck1)
print(Bob)
And after dealing to Bob they both have the same hands. If you have some other suggestions regarding the code, you are welcome to share that as well.
This is a duplicate of “Least Astonishment” and the Mutable Default Argument as indicated by #Mad Physicist. Closing this question for the same.

How to create addPlayer() method. (Python 3)

I'm currently working on an OOP project in my CSI class in which I have to create various sports team and athlete objects as well as a method addPlayer() for adding the athletes to a roster. This is what I have so far.
class Athlete:
def __init__(self, name, number):
self.name = name
self.number = number
def __str__(self):
return "Athlete(" + self.name + ", " + self.number + ")"
def name(self):
return self.name
def number(self):
return self.number
from Athlete import *
class SportsTeam:
roster = []
def __init__(self, city, name, colors):
self.city = city
self.name = name
self.colors = colors
SportsTeam.roster = roster
def __str__(self):
return "SportsTeam(" + self.city + ", " + self.name + \
", " + str(self.colors) + ", " + ")"
def getcity(self):
return self.city
def getname(self):
return self.name
def getcolors(self):
return self.colors
def getRoster(self):
return SportsTeam.roster
def printRoster(self):
for player in roster:
print("Current Team Roster: " + str(SportsTeam.roster))
def addPlayer(self, player):
SportsTeam.roster.append(player)
return SportsTeam.roster
The thing is when I try to use the addPlayer() method I created, I get an error message telling me that list has no attribute. Not sure what needs to be added to fix this.
P.S I have only been programming for a couple of months, so I apologize if the solution is obvious
When you are dealing with classes, you have your instance variables (like self.city = city) and your class variables (like roster = []).
Instance variables are tied to an instance of the class. So if you create 2 SportsTeam objects, they each have their own city.
Class variables are a little different. They are not tied to an instance of the class; meaning, no matter how many SportsTeam objects you create, there will only be one roster variable.
To me, roster being a class variable seems a bit odd because each SportsTeam should have its own roster. However, if you are required to use class variables for you CSI class, maybe you could keep a list of all_teams and/or all_players.
Taking this into consideration:
class SportsTeam:
all_teams = []
all_players = []
def __init__(self, city, name, colors):
self.city = city
self.name = name
self.colors = colors
self.roster = []
SportsTeam.all_teams.append(self)
def __str__(self):
return "SportsTeam(" + self.city + ", " + self.name + ", " + str(self.colors) + ")"
def getCity(self):
return self.city
def getName(self):
return self.name
def getColors(self):
return self.colors
def getRoster(self):
return self.roster
def printRoster(self):
# the for loop was unnecessary
print("Current Team Roster:", str(self.roster))
def addPlayer(self, player):
SportsTeam.all_players.append(player)
self.roster.append(player)
return self.roster
If you would like to keep roster as a class variable, leave a comment and I can help you adjust the code to accommodate for this.

I can't figure out what's wrong with the python code below. It keeps giving me Attribute error: 'Dog' object has no attribute '_Dog_name'

class Animal:
__name = None
__height = 0
__weight = 0
__sound = 0
We call a constructor, a constructor is called to setup/initialize an object
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, height):
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 in weight and makes the sound {}".format(self.__name, self.__height,
self.__weight, self.__sound)
cat = Animal('Whiskers', 33, 20, 'meow')
print(cat.get_name())
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 and weighs {}. He says {} and his owner is {}".format(self.__name,
self.__height,
self.__weight,
self.__sound,
self.__owner)
Spot = Dog("Spot",45,77,"Ruff","Amit")
print(Spot.toString())
Here the class Animal is being called in to use its attributes. I saw this on a tutorial video, it seems to be running fine in the video but not when I try it
The issue is with "name mangling" (c.f. https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references). If you wish to access super class variables with double underscores, you should prefix them with the class name:
def toString(self):
return"{} is {} cm tall and weighs {}. He says {} and his owner is {}".\
format(self._Animal__name,
self._Animal__height,
self._Animal__weight,
self._Animal__sound,
self.__owner)
Alternatively you could call the getters from Animal such as self.get_name().

Resources