This question already has answers here:
What is the meaning of single and double underscore before an object name?
(18 answers)
Closed 8 years ago.
This is the Traceback I am getting :
Traceback (most recent call last):
File "D:\School\Programming ll\Week 4\2.py", line 42, in
main()
File "D:\School\Programming ll\Week 4\2.py", line 38, in main
print('Name: ',emp.name())
AttributeError: 'ProductionWorker' object has no attribute 'name'
Code:
class Employee(object):
def __init__(self,name,id_number):
self.__name = name
self.__id_number = id_number
def set_name(self, name):
self. __name = name
def set_id_number(self,id_number):
return self.__name
def get_id_number(self):
return self.__id_number
class ProductionWorker(Employee):
def __init__(self, name,id_number,shift_num,pay_rate):
Employee.__init__(self, name, id_number)
self.__shift_num = shift_num
self.__pay_rate = pay_rate
def set_shift_num(self, shift_num):
self.__shift_num= shift_num
def set_pay_rate(self, pay_rate):
self.__pay_rate = pay_rate
#accessor functions for shift_number and pay_rate
def get_shift_num(self):
return self.__shift_num
def get_pay_rate(self):
return self.__pay_rate
def main():
#get the values of employee name, number , shif_number and pay_rate from user.
print ('Enter the following information for the employee')
name=input('Name: ')
id_number=input('Employee number: ')
shift_num=input('Shift number: ')
pay_rate=input ('Pay rate: ')
emp = ProductionWorker(name,id_number,shift_num,pay_rate)
print('Details of employee are shown below: ')
print('Name: ',emp.name())
print('Employee Number: ',emp.get_id_number())
print('Shift Number: ',emp.get_shift_num())
print('Pay Rate: ',emp.get_pay_rate())
main()
Please help me , I have been banging my head for hours now. Thanks
ProductionWorker is not a member of Employee. try instead :
emp = ProductionWorker(name,id_number,shift_num,pay_rate)
You may add a method in the Employee class :
def name(self):
return self.__name
The best way would be to use properties : https://docs.python.org/2/library/functions.html#property
Related
Doing a homework right now. The task is to create a class for students. But for some reason, I can't calculate the age right there?
Have tried several methods but nothing works for me. Keep getting this error "TypeError: 'tuple' object is not callable"
from datetime import datetime
def get_date_today():
return (2013, 10, 30)
dt = datetime(*get_date_today())
class Student:
def __init__(self, name, surname, birthdate, branch, grades):
self.name = name
self.surname = surname
self.birthdate = birthdate
self.branch = branch
self.grades = grades
def age(self):
return (datetime(*get_date_today()) - datetime(*self.birthdate())).days/365
def print_details(self):
print("Name:", self.name)
print("Grades:", self.grades)
print('Age: ', self.age())
print('Branch: ', self.branch)
print('Grades:', self.grades)
Will = Student('Will', 'Smith', (2001,10,12), 'Philosophy', [12,11,10,10,9,8])
print(Will.print_details())
Change datetime(*self.birthdate()) to
datetime(*self.birthdate)
The property self.birthdate is a tuple/list, and not a function.
I'm new to coding -- taking a Python college course. I know this will be obvious to many of you, but I can not figure out why I continue to get this error attribute error:
prodworker = employee.ProductionWorker(shift_num, pay_rate)
AttributeError: 'Employee' object has no attribute 'ProductionWorker'
Any help is greatly appreciated :)
class Employee: #writing new class called Employee:
def __init__(self, name, number): #accepts arguments for employee name and
self.__name = name #employee number
self.__number = number
def set_name(self, name): #mutator methods to set name and number
self.__name = name
def set_number(self, number):
self.__number = number
#accessor methods returns name and number
def get_name(self):
return self.__name
def get_number(self):
return self.__number
class ProductionWorker(Employee): #write subclass
def __init__(self, shift_num, pay_rate):
Employee.__init__(self, 'ProductionWorker')
self.__shift_num = shift_num
self.__pay_rate = pay_rate
def set_shift_num(self, shift_num):
self.__shift_num = shift_num
def set_pay_rate(self, pay_rate):
self.__pay_rate = pay_rate
def get_shift_num(self):
return self.__shift_num
def get_pay_rate(self):
return self.__pay_rate
#This program creates an instance of Employee Class
#and an instance of Production Worker Class:
again = 'Y'
while again.upper() == 'Y':
print('Enter the following data for the employee: \n')
name = input('What is the employee name?: ')
number = input('What is the employee number? ')
shift_num = input('What is the employee shift number? 1 = Day, 2 = Night :')
while shift_num != '1' and shift_num != '2':
shift_num = input('Invalid entry! Enter 1 for Day shift or 2 for Night shift!')
else:
if shift_num == '1':
shift_num = 'Day'
if shift_num == '2':
shift_num = 'Night'
pay_rate = float(input('What is the employee pay rate? '))
print()
print('This is an instance of the Employee class:')
employee = Employee(name, number)
print('EMPLOYEE: \t\t'+ employee.get_name())
print('EMPLOYEE NUMBER: \t' + employee.get_number())
print()
print('This is an instance of the Production Worker class: ')
prodworker = employee.ProductionWorker(shift_num, pay_rate)
print('SHIFT: \t\t\t' + ProductionWorker.get_shift_num())
print('PAY RATE: \t\t$' + format(ProductionWorker.get_pay_rate(), ',.2f'), sep='')
print('--------------------------------------------')
again = input('Enter Y to add another: ')
if again.upper() != 'Y':
print('Program End')
The ProductionWorker class is a subclass of the Employee class, but that doesn't mean you can call it through an instance of Employee. It's still a top-level class that you should call directly. Try replacing employee.ProductionWorker(...) with just ProductionWorker(...).
You'll get past the current error, but you may have new ones. For instance, I think the current attempt to call Employee.__init__ from ProductionWorker.__init__ will fail because it doesn't pass the right number of arguments. You may also have logic issues, if you expected employee.ProductionWorker to create a ProductionWorker instance that was related in some way to the employee object.
I'd also discourage you from using __double_leading_underscore names for your attributes. That invokes Python's name mangling system, which is mostly intended to help prevent accidental reuse of the same name from different classes in a large or unpredictable inheritance hierarchy. If you just want your attributes to be "private", use a single underscore. That doesn't protect them from being accessed by outside code, but it serves as documentation that they're not part of the object's public API. One of Python's design philosophies is that it's programmers are responsible for their own behavior (often described with the phrase "We're all consenting adults"). If a programmer wants to access an object's private data they can do so (which can be very useful for debugging). But if they break stuff, they have no one to blame but themselves.
I want to randomly pick a weapon and i want to write the name of it but the result is not like i expect what is wrong in that code?
import random
class Dusman:
def __init__(self,name='',weapon='',armor=''):
self.name= name
self.weapon= weapon
self.armor= armor
def name(self):
a=name
a = input("Write a name: ")
def weapon(self):
weapon=["Sword","Axe","Topuz"]
print(random.choice(weapon))
def print(self):
print("Name",self.name,"Weapon: ",self.weapon,"Armor: ",self.armor)
dusman1=Dusman()
dusman1.name
dusman1.weapon
dusman1.print()
Is this your expected result?
import random
class Dusman:
def __init__(self,name='',weapon='',armor=''):
self._name= name
self._weapon= weapon
self._armor= armor
def name(self):
self._name = input("Write a name: ")
def weapon(self):
weapons=["Sword","Axe","Topuz"]
self._weapon = random.choice(weapons)
print(self._weapon)
def __str__(self):
return "Name: {0} Weapon: {1} Armor: {2}".format(self._name,
self._weapon,
self._armor)
if __name__ == '__main__':
dusman1=Dusman()
dusman1.name()
dusman1.weapon()
print(dusman1)
Your problem is, that you have naming collisions. You are naming a variable the same as a function.
Currently, you only print the choice.
You need to set the result of the choice to the weapon instance variable:
def weapon(self):
weapons = ["Sword", "Axe", "Topuz"]
self.weapon = random.choice(weapons)
I've never used classes before and I am trying to get a general understanding of how they work with the code example I have below. Im having issues referencing one of the names i define for a class. i just want the program to print out a list of the employee names and salaries stored in the list when the option 2 is entered but it gives me the following error:
Traceback (most recent call last):
File "C:\Scott Glenn\Misc\classes.py", line 31, in
employees[i].displayEmployee
AttributeError: 'str' object has no attribute 'displayEmployee'
class Employee:
'Common base class for all employees'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
def AddNewEmployee():
NewEmployee = raw_input("What is the Employees name: ")
employees.append(str(NewEmployee))
NewEmployeeSalary = raw_input("What is the Employees salary: ")
NewEmployee = Employee(NewEmployee, NewEmployeeSalary)
return employees
#=============================================================================
employees=[]
while(1):
print'Welcome to the Employee Database!'
option = raw_input('Please select 1 to add new employee or 2 to display all current employees: ')
if option=='1':
employees.append(AddNewEmployee())
if option=='2':
for i in range(0,len(employees)):
employees[i].displayEmployee
The AddNewEmployee function is wrong. It's returning a list of a single string when you want to be returning a single object of your custom type Employee.
It should be more like this:
def AddNewEmployee():
#string variable to hold name
NewEmployeeName = raw_input("What is the Employees name: ")
#why make a list? you are appending the result of this function to that list
#employees.append(str(NewEmployee))
#plus this is adding the employee before he's even been created
NewEmployeeSalary = raw_input("What is the Employees salary: ")
#construct using name string and salary string
NewEmployee = Employee(NewEmployeeName, NewEmployeeSalary)
return NewEmployee #return Employee object (to be appended later)
Additionally, you are trying to access displayEmployee() as a field of your class, instead of as a method. Fields don't have parenthesis and methods do (so they can take parameters, though in this case the parenthesis are empty as no parameters are passed).
Finally, note that raw_input returns a string so you should cast to float if that is what you wish your NewEmployeeSalary to be. (Right now it's a string.)
I've updated your code below. The main issue that I saw that you had was that you were using 'employees' as a global and appending to it twice. I moved it out of the AddNewEmployee() function and had that return the new employee which is then appended to 'employees'
Also you weren't calling '.displayEmployees'
Notice the the parentheses that I added to the end.
I hope this helps!
class Employee(object):
'Common base class for all employees'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
def AddNewEmployee():
NewEmployee = raw_input("What is the Employees name: ")
NewEmployeeSalary = raw_input("What is the Employees salary: ")
NewEmployee = Employee(NewEmployee, NewEmployeeSalary)
return NewEmployee
# =============================================================================
if __name__ == "__main__":
employees = []
while True:
print'Welcome to the Employee Database!'
option = raw_input(
'Please select 1 to add new employee or 2 to display all current employees: ')
if option == '1':
employees.append(AddNewEmployee())
if option == '2':
for i in range(0, len(employees)):
employees[i].displayEmployee()
Here I have a sample code to test python class inheritence.
Here , the base class is ‘Person’ and the ‘Employee’ inherits the base class -‘Person’. Also, there are 2 more subclasses inhertis class ‘Employee’.
I would like to initialize subclass veriables in sub classes - ‘OfficeWorker’ and ‘ProductionWorker’, but I am getting ‘TypeError: __init__() takes 2 positional arguments but 7 were given’.
Need pyhton experts suggestion here to define and initialize subclass variable and correct my code
<snip of error>
#$ ./employee86253.py
Enter the name: sunnily
Enter the address: 41801
Enter the phone: 345
Enter the ID number: 12
Enter the employee type ('S' for salaried or 'H' for hourly): S
Enter the skill type ('eng', 'acc', 'sales', 'mgr'): eng
Enter the monthly salary: 123
Traceback (most recent call last):
File "./employee86253.py", line 110, in <module>
main ()
File "./employee86253.py", line 78, in main
**ERROR:**
**worker = OfficeWorker(worker_name, worker_address, worker_phone, worker_id, skill_type, salary)
TypeError: __init__() takes 2 positional arguments but 7 were given**
================== script =======================
#!/usr/bin/env python
# Base class
class Person:
def __init__ (self, name, address, phone_number):
self.name = name
self.address = address
self.phone_number = phone_number
def get_name(self):
return self.name
def get_address(self):
return self.adress
# subclass, inheriting class - Person
**class Employee (Person):
def __init__(self, id_number):
Person.__init__(self, name, address, phone_number)
self.id_number = id_number**
def get_id_number(self):
return self.id_number
# sub class, inheriting Class - Employee
class ProductionWorker (Employee):
**def __init__(self, shift_number, pay_rate):
super().__init__(id_number)
self.shift_number = shift_number
self.pay_rate = pay_rate**
def get_shift_number ( self ):
return self.shift_number
def compute_pay_for_hours( self, hours):
minutes = hours * 60
return ( minutes * self.pay_rate ) / minutes
def get_pay_rate(self ):
return self.pay_rate
# Subclass, inheriting class - Employee
class OfficeWorker (Employee):
**def __init__(self, skill_type, monthly_salary):
super().__init__(id_number)
self.skill_type = skill_type
self.monthly_salary = monthly_salary**
def get_skill_type(self):
return self.skill_type
def compute_pay_for_weeks(self, weeks):
return (weeks * self.monthly_salary ) / 4
def get_month_salary( self ):
return self.monthly_salary
def main():
# Local variables
worker_name= ''
worker_id = ''
worker_shift = 0
worker_pay = 0.0
skill_type = ''
salary = 0.0
emp_type = 'P'
**# Get data attributes
worker_name = input('Enter the name: ')
worker_address = input('Enter the address: ')
worker_phone = input('Enter the phone: ')
worker_id = input('Enter the ID number: ')
emp_type = input('Enter the employee type (\'S\' for salaried or \'H\' for hourly): ')
if emp_type == 'S':
skill_type = input('Enter the skill type (\'eng\', \'acc\', \'sales\', \'mgr\'): ')
salary = float(input('Enter the monthly salary: '))
worker = OfficeWorker(worker_name, worker_address, worker_phone, worker_id, skill_type, salary)
elif emp_type == 'H':
worker_shift = int(input('Enter the shift number: '))
worker_pay = float(input('Enter the hourly pay rate: '))
worker = ProductionWorker(worker_name, worker_address, worker_phone, worker_id, worker_shift, worker_pay)
else:
print('Invalid employee type')
return**
# Create an instance of ProductionWorker
# Display information
print ('Employee information:')
print ('Name:', worker.get_name())
print ('Address:', worker.get_address())
print ('Phone:', worker.get_phone())
print ('ID number:', worker.get_id_number())
if isinstance(worker,ProductionWorker):
print ('Shift:', worker.get_shift_number())
print ('Hourly Pay Rate: $', \
format(worker.get_pay_rate(), ',.2f'), sep='')
print ('Pay Amount for 5.2 hours: $', \
format(worker.compute_pay_for_hours(5.2), ',.2f'), sep='')
else:
print ('Skill type:', worker.get_skill_type())
print ('Monthly Salary: $', \
format(worker.get_month_salary(), ',.2f'), sep='')
print ('Pay Amount for 2.5 months: $', \
format(worker.compute_pay_for_weeks(10), ',.2f'), sep='')
# call the main function
main ()
Taking the simplest case as an example (but you've got clones of this all over the place):
def __init__(self, id_number):
Person.__init__(self, name, address, phone_number)
where do you think name, address, phone_number will come from? If they're supposed to be arguments to the call to Employee then they must be listed as arguments to its __init__ (and "passed up to it" from further subclasses as needed).