builtins.TypeError: unsupported operand type(s) for *: 'int' and 'method' - python-3.x

I'm writing some code from a YouTube tutorial and I keep running into a type error. Why?
class Employee():
''' keeps track of company employees'''
raise_amount = 1.04
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.pay = pay
self.email = last + '.' + first +'#tech.com'
def fullname(self):
return self.first +' ' + self.last
def Email(self): #not needed bc its already an attribute
return self.email
def raise_amount(self):
return ((self.pay * self.raise_amount) - self.pay)
def annual_raise(self):
self.pay = int(self.pay * self.raise_amount)
return pay

Here , You have used the same name raise_amount for method and the class variable. When you execute the below code
def raise_amount(self):
return ((self.pay * self.raise_amount) - self.pay)
self.raise_amount will point to the method raise_amount. So the multiplication operation fails as it expects its arguments as numbers. You can either change class variable name or method name.
If you are changing class variable name, change the code as below:
raise_amount_value = 1.04
inside the method :
def raise_amount(self):
return ((self.pay * self.raise_amount_value) - self.pay)
def annual_raise(self):
self.pay = int(self.pay * self.raise_amount_value)
return pay

class Employee():
''' keeps track of company employees'''
raise_amount = 1.04
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.pay = pay
self.email = last + '.' + first +'#tech.com'
def fullname(self):
return self.first +' ' + self.last
def Email(self): #not needed bc its already an attribute
return self.email
def raise_amount(self):
return ((self.pay * self.raise_amount) - self.pay)
def annual_raise(self):
self.pay = int(self.pay * self.raise_amount)
return pay
emp_1 =Employee("Joshua", "Ozoya", 9000)
print(emp_1.fullname())
your programme is running fine.
emp_1 =Employee("Joshua", "Ozoya", 9000)
print(emp_1.fullname())
Add those two lines of code to get the result.
And also, specify the error you were getting.

Related

How can I access actual output instead of location index when I call methods in another method in a python class

def get_all_values(self):
values_list = [self.get_input_cable, self.get_output_cable, self.get_color, self.get_price]
return values_list
This is the output when I called out the methods into a list and printed it.
\[\<bound method Charger.get_input_cable of \<__main__.Charger object at 0x1030b4e10\>\>, \<bound method Charger.get_output_cable of \<__main__.Charger object at 0x1030b4e10\>\>, \<bound method Charger.get_color of \<__main__.Charger object at 0x1030b4e10\>\>, 600\]
I have tried the below code:
class Charger(object):
def __init__(self, input_cable, output_cable, color=None):
self.input_cable = input_cable
self.output_cable = output_cable
self.color = color
self.price = 0
def __str__(self):
return "Input: " + str(self.input_cable) + "\nOutput: " + str(self.output_cable) + "\nColor: " + str(self.color)
# Getters
def get_input_cable(self):
return self.input_cable
def get_output_cable(self):
return self.output_cable
def get_color(self):
return self.color
def get_price(self):
return self.price
# Setters
def set_input_cable(self, input_cable):
self.input_cable = input_cable
def set_output_cable(self, output_cable):
self.output_cable = output_cable
def set_color(self, color):
self.color = color
def set_price(self, price):
self.price = price
# Behaviours (Methods)
def sale(self,discount=0):
sale_price = self.price - self.price * discount/100
return sale_price
def get_all_values(self):
values_list = [self.get_input_cable, self.get_output_cable, self.get_color, self.get_price]
return values_list
C1 = Charger("C type", "B type", "Black")
C2 = Charger("USB", "C type", "White")
C1.set_price(600)
C2.set_price(1300)
print(C1.get_price())
print(C2.get_price())
print(C1.get_all_values())
If you want to access the actual output value of a method called within another method in a Python class, you can either store the output value in a variable within the method and return it, or you can directly return the output value from the method call in the return statement of the calling method.
For example, if you have a method method1 that calls another method method2, you can either do:
class MyClass:
def method1(self):
result = self.method2()
# do something with result
return result
def method2(self):
# do some computation
return output_value
or you can simply do:
class MyClass:
def method1(self):
result = self.method2()
# do something with result
return result
def method2(self):
# do some computation
return output_value
In both cases, output_value is the actual output of method2.

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

Operator overloading with python outside a class

class A:
def __init__(self,m1,m2):
self.m1 = m1
self.m2 = m2
def __add__(self, other):
''' add takes 2 objects basically objects on RHS and LHS of + say a + b '''
print("Inside add")
s3 = A(self.m1+other.m1,self.m2+other.m2)
return s3
def disp(self):
print('{} {}'.format(self.m1,self.m2))
def __str__(self):
return '{} {}'.format(self.m1,self.m2)
def __add__(self,other):
return self*other
a = 2+5
print(a)
Output seen is: 7
Whereas expected is 10 since I am trying to overwrite the implicit add function with multiply operation.
What happens here?
Does operator overloading works only with pytclass?
class A:
def __init__(self,m):
self.m=m
def __str__(self):
return str(self.m)
#multiply two objects
def __mul__(self,other):
t=self.m*other.m
return A(t)
#add two objects
def __add__(self,other):
t=self.m+other.m
return A(t)
obj1=A(2)
obj2=A(5)
#calling operator overloading of '*'
print(obj1*obj2)
#calling operator overloading of '+'
print(obj1+obj2)

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.]

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.

Resources