How can I print the method from within a Class? - python-3.x

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
'''

Related

Why the type of a parameter of a function in a class would change into list?

class Employee:
num_of_emps = 0
raise_amount = 1.04
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.pay = pay
self.email = first + last + '#gmail.com'
Employee.num_of_emps += 1
def fullname(self):
return f'I am {self.first} {self.last}'
def apply_raise(self):
self.pay = int(self.pay * Employee.raise_amount)
#classmethod
def set_raise_amt(cls, amount):
cls.raise_amount = amount
#classmethod
def from_string(cls, emp_str):
first, last, pay = emp_str.split('-')
return cls(first, last, pay)
#staticmethod
def is_workday(day):
if day.weekday() == 5 or day.weekday() == 6:
return False
return True
class Developer(Employee):
raise_amount = 1.50
def __init__(self, first, last, pay, prog_lang):
super().__init__(first, last, pay)
self.prog_lang = prog_lang
class Manager(Employee):
def __init__(self, first, last, pay, employees=None):
super().__init__(first, last, pay)
if employees is None:
self.employees = []
else:
self.employees = employees
def add_emp(self,emp):
if emp not in self.employees:
self.employees.append(emp)
def remove_emp(self,emp):
if emp in self.employees:
self.employees.remove(emp)
def print_emps(self):
for emp in self.employees:
print('--->', emp.full_name())
dev_1 = Developer('John','Doe',30000, 'Python')
dev_2 = Developer('Emily','Smith',23000, 'Java')
# print(help(Developer))
print(dev_1.email)
print(dev_2.email)
print(dev_1.pay)
dev_1.apply_raise()
print(dev_1.pay)
mgr_1 = Manager('Sarah','Smith',34000, [dev_1])
print(type(mgr_1.employees))
print(mgr_1.employees)
print(type(dev_1))
print(type([dev_1]))
print([dev_1])
mgr_1.print_emps()
I recently studied this code on youtube. So basically this code started with a class named 'Employee' at the beginning, and then a subclass called 'Developer' was created. I still able to catch up with the logic behind the code at the moment, but after another subclass called 'Manager' was created, I lost.
I don't know why the parameter,'employees' in the class 'Manager' would suddenly become a list in the end
And I also don't know why the for loop could be able to run
Please help, thank you so much
mgr_1 = Manager('Sarah','Smith',34000, [dev_1])
first='Sarah', last='Smith', pay=34000, employees=[dev_1]
Your parameter is an list

How in Pyhton's OOP a class's method access to another class's method?

I am new to Python OOP and I am trying to learn the basics of Python OOP and I came across a video on YouTube that teaches the basics of it. The code is an example code from the video. I understood all of it but I am not able to understand how the class "Course's" "get_average_grade()" method is accessing the class "Student's" "get_grade()" method? Any help is highly appreciated.
class Student:
def __init__(self, name, age, grade):
self.name = name
self.age = age
self.grade = grade # 0-100
def get_grade(self): #<---- This method was used inside the Course class
return self.grade
class Course:
def __init__(self, name, max_students):
self.name = name
self.max_students = max_students
self.students = []
def add_student(self, student):
if len(self.students) < self.max_students:
self.students.append(student)
return True
return False
def get_average_grade(self):
value = 0
for student in self.students:
value = value + student.get_grade() #<---- This Method is from the Student class
return value / len(self.students)
s1 = Student("Tim", 19, 95)
s2 = Student("Bill", 19, 75)
s3 = Student("Jill", 19, 65)
course = Course("Science", 2)
course.add_student(s1)
course.add_student(s2)

Python 3 TypeError: 'int' object is not callable, but what is the fault here?

currently I am leraning Python 3 and I am facing here the following problem within my blackjack card game code.
The output is the result of the player.points() function, I was testing it outside of the written code and it worked well like that, so I dont get it where the Error Message comes from, any hints or ideas?
```
from IPython.display import clear_output
import time
import random
import emoji
class Player():
def __init__(self, account,name):
self.name = name
self.account = account
self.betbox = 0
self.cards = [[]]
self.points = 0
self.status = True # True -> Player, False -> Spectator
def bet(self,bet):
self.betbox = int(bet)
self.account -= int(bet)
def get_card(self, card, deck_of_cards=0):
self.cards[deck_of_cards].append(card)
def points(self):
for i,cards in enumerate(self.cards):
for card in self.cards[i]:
print(card)
def __str__(self):
player_string = ""
name_string = "Player: "+ str(self.name)
cards_string = ""
account_string = "Account: "+ str(self.account)
betbox_string = "Betbox: "+ str(self.betbox)
points_string = "points to be calculated"
for i,deck_of_cards in enumerate(self.cards):
for j,card in enumerate(deck_of_cards):
cards_string += str(self.cards[i][j]) +" "
return "\n\n"+ name_string +"\n"+ cards_string +"\n"+ account_string +"\n"+ betbox_string +"\n"+ points_string
class Dealer(Player):
def __init__(self,account,name):
Player.__init__(self, account,name)
self.stack = []
def __str__(self):
player_string = ""
name_string = "Dealer: "+ str(self.name)
cards_string = ""
account_string = "Account: "+ str(self.account)
betbox_string = "Betbox: "+ str(self.betbox)
points_string = "points to be calculated"
for i,deck_of_cards in enumerate(self.cards):
for j,card in enumerate(deck_of_cards):
cards_string += str(self.cards[i][j]) +" "
return "\n\n"+ name_string +"\n"+ cards_string +"\n"+ account_string +"\n"+ betbox_string +"\n"+ points_string
def new_stack_of_cards(self):
value=["2","3","4","5","6","7","8","9","10","Jack","Queen","King","Ace"]
color=[emoji.emojize(':heart_suit:'), emoji.emojize(':spade_suit:'), emoji.emojize(':club_suit:'), emoji.emojize(':diamond_suit:')]
i = 0
while i < 4:
for v in value:
for c in color:
self.stack.append(Card())
self.stack[-1].new(v,c)
i += 1
random.shuffle(self.stack)
def card(self):
return self.stack.pop()
class Table():
def __init__(self):
self.table = []
def initialize(self):
input_string = ""
name_strings = []
while True:
input_string = input()
if input_string == "q":
break
name_strings.append(input_string)
return name_strings
def view(self):
table = ""
for player in self.table:
table += str(player)
time.sleep(5)
clear_output()
print(table)
class Card():
def __init__(self):
self.value = "2"
self.color = emoji.emojize(':heart_suit:')
def new(self, value, color):
self.value = value
self.color = color
def __str__(self):
return str(self.color) + str(self.value)
blackjack = Table()
dealer = Dealer(1000000,"d")
dealer.new_stack_of_cards()
name_strings = blackjack.initialize()
for i,player in enumerate(name_strings):
blackjack.table.append(Player(10000,name_strings[i]))
blackjack.table.append(dealer)
for player in blackjack.table[:-1]:
player.bet(input())
for player in blackjack.table:
player.get_card(dealer.card())
blackjack.view()
for player in blackjack.table[:-1]:
player.get_card(dealer.card())
blackjack.view()
for player in blackjack.table:
player.points()
output:
Player: 1
♥10 ♥2
Account: 9999
Betbox: 1
points to be calculated
Player: 2
♣10 ♣Jack
Account: 9998
Betbox: 2
points to be calculated
Dealer: d
♥Ace
Account: 1000000
Betbox: 0
points to be calculated
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-1a19c3780b6f> in <module>
25
26 for player in blackjack.table:
---> 27 player.points()
28
29
TypeError: 'int' object is not callable
In your Player class, points is an integer, and cannot be called. I see that the method points has been commented out.
for player in blackjack.table:
player.points()
From this code, it looks like you want to call the method points, but you are instead trying to call an integer stored in the points attribute.
Uncomment the method, and change the name of either the method or the attribute.

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.

Python - passing class instantiation to a function

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)

Resources