Python: passing an argument to a method within a class - python

So for instance I have a class called Employee and I have a class method designed to raise the wage of an an Employee.
I just have issues actually getting my desired raise for the wage passed into the class method as an argument, it's baffling me.
Class module;
Class Employee:
def __init__(self, name, salary, age):
self.name = name.title()
self.salary = salary
self.age = age
def raise_wage(self, raise):
self.salary = self.salary + raise
main module;
def main():
e1 = Employee("John Smith", 50000, 42)
Employee.e1.raise_wage(500)
Passing that 500 in as an arguement is the issue, i get missing positional argument errors for the method etc.
How do I pass the argument to the class method?
Hope this makes sense.

You can't use raise. It is a reserved word.
Use class instead of Class to define a class.
Write e1.raise_wage() instead of Employee.e1.raise_wage().
class Employee:
def __init__(self, name, salary, age):
self.name = name.title()
self.salary = salary
self.age = age
def raise_wage(self, amount):
self.salary = self.salary + amount
e1 = Employee("John Smith", 50000, 42)
e1.raise_wage(500)
print(e1.salary) # output: 50500

raise is a reserved keyword used to raise an exception, change it to other name and it will work just fine.
https://www.w3schools.com/python/ref_keyword_raise.asp

raise is a reserved keyword in python for raising exception. use another name for that argument then it will work. And you already created object for Employee so no need to call function with class name again.

Related

What's the point of method inheritance and calling Parent.method()?

I came across this example of method inheritance:
The child Manager class inherits from the parent Employee class, and modifies its give_raise() method, while also calling Employee.give_raise() in the new implementation.
# Parent class
class Employee:
def __init__(self, name, salary=30000):
self.name = name
self.salary = salary
def give_raise(self, amount):
self.salary += amount
# Child class
class Manager(Employee):
def display(self):
print("Manager ", self.name)
def __init__(self, name, salary=50000, project=None):
Employee.__init__(self, name, salary)
self.project = project
# Modify the give_raise method
def give_raise(self, amount, bonus=1.05):
new_amount = amount * bonus
# Call the parent method
Employee.give_raise(self, new_amount)
mngr = Manager("John Smith", 80000)
mngr.give_raise(5000)
print(mngr.salary)
My question is: isn't this a bit convoluted?
I get class inheritance. But calling a parent method within a child method of the same name?
Wouldn't it be better to write give_raise() in the Manager class as:
def give_raise(self, amount, bonus):
new_amount = amount * bonus
self.salary += amount
To me, it only makes sense to call Parent.method() if it's a completely different method that requires a lot of lines of code
I agree with you initial question in that the implementations are a bit convoluted and don't help to clearly convey the intended usage. The main goal of method inheritance is to encourage reusable, encapsulated behavior within the class hierarchy. That way the derived class could add some functionality or override the underlying functionality (or leave it be and add other functionality).
Parent.give_raise could be defined in a way that doesn't require it to be overriden in order to customize what raise different employee types get.
For example,
class Employee:
default_salary = 30000
def __init__(self, name, salary=None, bonus=1, **kwargs):
super().__init__(**kwargs)
if salary is None:
salary = self.default_salary
self.name = name
self.salary = salary
self.bonus_multiplier = bonus
def give_raise(self, amount):
self.salary += amount * self.bonus_multiplier
class Manager(Employee):
default_salary = 50000
def display(self):
print("Manager ", self.name)
def __init__(self, *, project=None, **kwargs):
if 'bonus' not in kwargs:
kwargs['bonus'] = 1.05
super.__init__(**kwargs)
self.project = project
mngr = Manager(name="John Smith", salary=80000)
mngr.give_raise(5000)
print(mngr.salary)

After inheriting a function how to give it more parameters

I inherited a student class for my masters_student class and and all the functions are working as expected but I want to give my masters_student class another parameter called Age.
How could I do that?
class masters_student(student , age):
self.age = age
def qualify(self):
if self.Gpa > 3.0 :
print("You qualify for the masters Programme")
else:
print("you dont qualify for Masters programme")
Then it shows a error
class student:
def __init__(self, name, major, Gpa, loan):
self.name = name
self.major = major
self.Gpa = Gpa
self.loan = loan
def On_honour_roll(self):
if self.Gpa >= 3.5:
return True
else:
return False
class masters_student(student):
def qualify(self):
if self.Gpa > 3.0 :
print("You qualify for the masters Programme")
else:
print("you dont qualify for Masters programme")
Here is some documentation on [https://rhettinger.wordpress.com/2011/05/26/super-considered-super/][super].
You need to tell python how to instantiate you children class following parent one.
class master_student(student):
def __init__(self, name, major, Gpa, loan, age):
super(student, self).__init__(name, major, Gpa, loan)
self.age = age
This should work.
First, we have to get our terminology correct. I don't see where you are taking an existing function that you are inheriting and then redefining it to have additional parameters. When you code:
class masters_student(student , age):
You are specifying multiple inheritance, that is, you are saying that class masters_student inherits from both class student and from class age. But then on the next line you code:
self.age = age
which does not make too much sense.
It seems that what you are trying to do is add to your new class, masters_student, an additional data attribute named age. I can't even be sure of that because I never see in your question any code that references age; I would have thought that it would be used in method qualify. But assuming that is your intent, there are several ways of doing this depending on whether you are running Python 3 or Python 2. The simplest way, which works on either Python 2 or Python 3 would be:
class masters_student(student):
def __init__(self, name, major, Gpa, loan, age):
student.__init__(self, name, major, Gpa, loan) # initialize the base class
self.age = age
If you are running Python 3, you can also code:
class masters_student(student):
def __init__(self, name, major, Gpa, loan, age):
super().__init__(name, major, Gpa, loan) # initialize the base class
self.age = age
If you are running Python 2 (or Python 3), you can also code:
class masters_student(student):
def __init__(self, name, major, Gpa, loan, age):
super(masters_student, self).__init__(name, major, Gpa, loan) # initialize the base class
self.age = age
But, you must ensure that your base class, student in this case, inherits from class object:
class student(object):
When you use super() to initialize base classes, the base classes, too, must use super() to initialize their base and sibling classes.

Why can't I add another variable in the class using setter and getter?

I wrote a class called person and used setter and getter. At first, the code was working fine when I used one variable.However when I added another variable , it said that 2 required positional arguments were missing:"name" and "age".
class person:
def __init__(self, name, age):
self.name = name
self.age = age
def set_name(self,y):
self.name = y
def get_name(self):
return self.name
def set_age(self,x):
self.age = x
def get_age(self):
return self.age
p1 = person()
p1.set_name("Armeen")
p1.set_age("20")
print(p1.get_age())
print(p1.get_name())
Your __init__ method takes two arguments namely name and age. You aren't providing any argument when creating an instance of Person. So you may want to do the following:
p1 = person('Armeen', 20)
As opposed to
p1 = person()
Or if you want to allow user not to specify name and age at the time of instance creation, you can set those parameter as optional by doing the following change in __init__
def __init__(self, name = None, age = None): ##This would work with your code as well

Trouble understanding python inheritance arguments

I've tried reading a few different tutorials, but I still can't figure it out. I have two simple classes. Animal and cat.
class Animal:
def __init__(self, name):
self.name = name
class Cat(Animal):
def __init___(self, age):
self.age = age
print('age is: {0}'.format(self.age))
def talk(self):
print('Meowwww!')
c = Cat('Molly')
c.talk()
Output is:
Meowwww!
The code runs, but I'm a little confused. I created an instance of the cat class with c = Cat('Molly'). So somehow by using "Molly" as an argument for the Cat() class instance, it feeds "Molly" to the original base class (Animal) instead of the Cat class instance I created? Why? So how do I feed the Cat class instance the age variable it requires?
I tried doing:
c = Cat('Molly', 10)
But it complains about too many arguments. And secondly, why doesn't the __init__ function of the Cat class get called? It should print "age is...". It just never does.
EDIT: Got it to work, thanks to Martijn Pieters! Here is the updated code (works with python3):
class Animal():
def __init__(self, name):
self.name = name
print('name is: {0}'.format(self.name))
class Cat(Animal):
def __init__(self, name, age):
super().__init__(name)
self.age = age
print('age is: {0}'.format(self.age))
def talk(self):
print('Meowwww!')
c = Cat('Molly', 5)
c.talk()
You misspelled __init__:
def __init___(self, age):
# 12 345
That's 3 double underscores at the end, not the required 2.
As such, Python won't call it as it is not the method it is looking for.
If you want to pass in both age and name, give the method another argument, then call the parent __init__ with just the name:
class Cat(Animal):
def __init__(self, name, age):
super().__init__(name)
self.age = age

error: person not found

#C:/Python32
class Person:
def __init__(self, name = "joe" , age= 20 , salary=0):
self.name = name
self.age = age
self.salary = salary
def __printData__(self):
return " My name is {0}, my age is {1} , and my salary is {2}.".format(self.name, self.age, self.salary)
print(Person)
class Employee(Person):
def __init__(self, name, age , salary ):
Person. __init__ (self,name = "Mohamed" , age = 20 , salary = 100000)
def __printData__(self):
return " My name is {0}, my age is {1} , and my salary is {2}.".format(self.name, self.age, self.salary)
print(Employee)
p= Person()
e = Employee()
Your problem can be simplified to:
class Person:
print(Person)
This will raise a NameError. When constructing a class, the body of the class is executed and placed in a special namespace. That namespace is then passed to type which is responsible for actually creating the class.
In your code, you're trying to print(Person) before the class Person has actually been created (at the stage where the body of the class is being executed -- Before it gets passed to type and bound to the class name) which leads to the NameError.
It appears that you want to have your class return certain information when print is called on it, and that you also want that information printed when you create an instance of that class. The way you would do this is to define a __repr__ ( or __str__, for more on that see Difference between __str__ and __repr__ in Python ) method for your class. Then everytime print is called on an instance of your class, it will print what is returned by that __repr__ method. Then you can just add a line to your __init__ method, that prints the instance. Within the class, the current instance is referred to by the special self keyword, the name of the class is only defined outside the scope of the class, in the main namespace. So you should call print(self) and not print(Person). Here's some code for your example:
class Person:
def __init__(self, name = "joe" , age= 20 , salary=0):
self.name = name
self.age = age
self.salary = salary
print(self)
def __repr__(self):
return " My name is {0}, my age is {1} , and my salary is {2}.".format(self.name, self.age, self.salary)
joe = Person()
>>> My name is joe, my age is 20 , and my salary is 0.

Categories