There was a problem entering the fields of class. At the time of calling the add_well function, the default class fields specified in init function are displayed in the console. I don't understand why this behavior occurs and how to get rid of it. Can you help me?
def InputConsole(self, param):
return input(param)
#class of well
class well:
def __init__(self):
self.code_name = ''
self.depth = 0
self.pressure = 0
self.work = False
def input_properties(self):
print("-------- ADD WELL --------")
print('Code name: ')
self.code_name = InputConsole(self, self.code_name)
print('Depth: ')
self.depth = InputConsole(self, self.depth)
print('Pressure: ')
self.pressure = InputConsole(self, self.pressure)
print('Work: ')
self.work = InputConsole(self, self.work)
#class of field, container class
class field():
def __init__(self):
self.field = dict()
self.id_max = 0
def add_well(self):
wl = well()
wl.input_properties()
self.field[self.id_max] = wl
self.id_max += 1
print('Well was added\n\n')
def print_console(self):
print(self.field)
if self.id_max != 0 :
print("-------- INFO ABOUT FIELD --------")
for i in range(self.id_max):
self.field[i].print_properties()
print('')
else:
print('List is empty\n\n')
def main():
field = field()
field.add_well()
main()
Calling input() with a parameter uses the parameter as a prompt. Change the calls of InputConsole(self, self.code_name) to InputConsole(self, “Enter code name: “) and so on.
In addition, there’s really no reason you should be making an InputConsole function. You should also not be using self as a parameter for some of these methods, because your InputConsole, add_well, and print_console functions are not members of a class.
Related
I created a super simple Character and Buildable class for a miniature game I am developing and I have created a nested class where Character is for the outer class and Buildable is the inner class. I am trying to loop through resources from Character inside my upgradeBuildable function within Buildable.
class Character:
# Constructor -- Also why do comments use # and not // -_-
def __init__(self):
self.name = "Pickle"
self.health = 100
self.resources = ["Fire", "Coal"]
self.buildObj = self.Buildable() # Object for nested 2nd class
# Function to display character info
def characterInfo(self):
print("CharacterInfo --> " + "Name:", self.name, "| Health:", self.health, "| Resources:", self.resources)
def printRes(self):
print(self.resources)
# Function for collecting resources
def collectResource(self, newResource):
self.resources.append(newResource)
class Buildable:
def __init__(self):
self.buildings = ["Fire 1"]
self.upgradeStatus = 0
self.outer = Character()
def displayBuildable(self):
print("Buildables -->", self.buildings)
def createBuildable(self, newBuilding):
self.buildings.append(newBuilding)
def upgradeBuildable(self, replaceBuilding):
if self.upgradeStatus == 0:
# Update selected building
for i in range(len(self.buildings)):
if self.buildings[i] == replaceBuilding:
self.buildings[i] = "2x"
break
print(Character.resources)
self.upgradeStatus = self.upgradeStatus + 1
print(self.upgradeStatus)
When I try to access print the resource attribute from Character in upgradeBuildable I get a recursion error "RecursionError: maximum recursion depth exceeded" which is confusing to me.
All I am trying to do is try and print the resources the character has inside my inner Buildable class. Any help is much appreciated !!
My main is followed below:
from BW_Classes import Character
pick = Character()
pick.characterInfo()
# Object created for inner class -- Buildable()
build = pick.buildObj
build.displayBuildable()
print()
print("Building......")
build.createBuildable("Fire 2")
build.createBuildable("Coal Mine")
build.createBuildable("Coal Supreme")
build.createBuildable("Ocean")
build.displayBuildable()
print()
print("Upgrading....")
build.upgradeBuildable("Fire 2")
build.displayBuildable()
I believe what you are look for is Inheritance. Inheritance basically means that a class inherits the properties and methods of another class, which I am assuming you are looking for when you say nested classes.
The error is being thrown because when you initialize the character, the function initializes the buildable. When the buildable is initialized, it initializes the character. See the loop?
Your code will probably look something like this:
class Character(Buildable):
def __init__(self):
self.name = "Pickle"
self.health = 100
self.resources = ["Fire", "Coal"]
#initialize the buildable class
super().__init__()
# Function to display character info
def characterInfo(self):
print("CharacterInfo --> " + "Name:", self.name, "| Health:", self.health, "| Resources:", self.resources)
def printRes(self):
print(self.resources)
# Function for collecting resources
def collectResource(self, newResource):
self.resources.append(newResource)
class Buildable():
def __init__(self):
self.buildings = ["Fire 1"]
self.upgradeStatus = 0
def displayBuildable(self):
print("Buildables -->", self.buildings)
def createBuildable(self, newBuilding):
self.buildings.append(newBuilding)
def upgradeBuildable(self, replaceBuilding):
if self.upgradeStatus == 0:
# Update selected building
for i in range(len(self.buildings)):
if self.buildings[i] == replaceBuilding:
self.buildings[i] = "2x"
break
print(Character.resources)
self.upgradeStatus = self.upgradeStatus + 1
print(self.upgradeStatus)
I am working on a project for school, simulating a payroll program, and I am getting an error. The error I am getting is
'Expected type 'Classification', got 'Employee' instead'. The relevant code is (I put *** around the code generating the error, it is the 5th function under the Employee Class).
class Employee:
def __init__(self, emp_id, first_name, last_name, address, city, state, zipcode, clas = None):
self.emp_id = emp_id
self.first_name = first_name
self.last_name = last_name
self.address = address
self.city = city
self.state = state
self.zipcode = zipcode
self.classification = clas
def make_hourly(self, hourly_rate):
self.clas = Hourly(hourly_rate)
self.classification = self.clas
def make_salaried(self, salary):
self.clas = Salaried(salary)
self.classification = self.clas
def make_commissioned(self, salary, rate):
self.clas = Commissioned(rate, salary)
self.classification = self.clas
def issue_payment(self):
***pay = Classification.compute_pay(self)***
print('Mailing', pay, 'to', self.first_name, self.last_name, 'at', self.address, self.city, self.state, self.zipcode)
class Classification(ABC):
''' Interface for employee classifications '''
#abstractmethod
def compute_pay(self):
pass
class Hourly(Classification):
''' Manages timecard info. Computes pay '''
def __init__(self, hourly_rate):
self.hourly_rate = hourly_rate
self.timecards = [] # A list of floats representing hours worked
def compute_pay(self):
for i in list_of_timecards:
if i[0] == self.emp_id:
self.timecards.extend(i[1:])
total = list(map(float, self.timecards))
total = sum(total)
self.timecards.clear()
return total * self.hourly_rate
def add_timecard(self, hours):
self.timecards.append(hours)
class Salaried(Classification):
def __init__(self, salary):
self.salary = salary
def compute_pay(self):
return self.salary / 24
class Commissioned(Salaried):
def __init__(self, salary, commission_rate):
self.commission_rate = commission_rate
self.salary = salary
self.receipts = []
def add_receipt(self, amount):
self.receipts.append(amount)
def compute_pay(self):
for i in list_of_receipts:
if i[0] == self.emp_id:
self.receipts.extend(i[1:])
total = list(map(float, self.receipts))
total = sum(total)
self.receipts.clear()
return (self.salary / 24) + ((self.commission_rate / 100) * total)
My understanding of the problem is that I need to pass my 'employee' object to the 'compute_pay' function, which then passes it to the relevant child class (hourly etc...) to run and return the result. I have tried changing
pay = Classification.compute_pay(self)
to
pay = Classification.compute_pay(self.clas)
however that returns error 'AttributeError: 'Employee' object has no attribute 'clas'
which makes no sense. Maybe it is that I am not assigning the employees to the class correctly?
The code for that is (it pulls from a CSV file, and it is pulling the data correctly and generating the class objects, I have checked)
def load_employees():
f = open("employees.csv")
f.readline() # skip header line
for line in f:
fields = line.strip().split(',')
emp = Employee(*fields[:7])
if fields[7] == '3':
clas = Hourly(fields[10]) # Need to define Hourly
emp.classification = clas
elif fields[7] == '2':
clas = Commissioned(fields[8], fields[9])
emp.classification = clas
elif fields[7] == '1':
clas = Salaried(fields[8])
emp.classification = clas
employees.append(emp)
I will figure out your line Classification.compute_pay(self):
Classification => the class Classification
compute_pay => class
method self => this = an Employee instance
pass means do nothing and is used to avoid unneccessary code.
Every class method has self as an argument to allow refering to this instance of the class.
To pass an argument (here your employee) use a parameter. Also implementing a method of the parent class overrides this method.
Every function compute_pay should have a second argument
def compute_pay(self, employee):
# do your stuff
And then you can use this line in issue_payment
pay = self.clas.compute_pay(self)
Two issues here,
Firstly, your Employee instance has two attributes: clas and classification. However, in your constructor, only classification is set.
def __init__(...
...
self.classification = clas
But self.clas is not set to anything. That's why you are getting that error 'Employee' object has no attribute 'clas'. It is only set when one of the make_hourly, make_salaried, or make_commissioned methods are invoked. So when you load the employees CSV, instead of manually creating the instance like you are doing here
clas = Hourly(fields[10])
you should be calling the method make_hourly on your emp instance, like so
emp.make_hourly(fields[10])
It's worth noting that fields[10] is terrible naming. Instead of unpacking all the fields at once, try to unpack them during the for loop:
for a, b, c, d in csv:
...
Secondly, this line of code is wrong in multiple ways
pay = Classification.compute_pay(self)
compute_pay is not a static function or a classmethod. So it shouldn't be called on the Classification class itself, but the Classification instance. This is what you stored in your self.clas attribute. So, compute_pay should be called on self.clas:
def issue_payment(self):
pay = self.clas.compute_pay()
...
In addition to that, when you call a method of a class from inside of another method in the same class, you don't ever need to pass the self argument. It is implied. So even if compute_pay was static or a class method, which it isn't, it would be called like so,
Classification.compute_pay()
Notice there is no self inside the parentheses. Similarly, when you call another method that is not static, self is never passed as an argument:
def my_method(self):
self.another_method()
Disregard the naming conventions as to what class is part of which it is just a test run.
I need some help with the OOP inheritance i have created a class of Students, Teachers, and the principal. My goal is for the principal to be able to add employees. The problem is i just want to use a for loop to get the names and then pass that method as an attribute for the principal object. i was able to do it with the class Input without the self parameter. can someone tell me
what is going on here and how can i fix this with self. i removed input from names so that my question wont get shut down
class Input:
def count():
cnt = []
for i in range(4):
name = ('Enter name here: ')
cnt.append(name)
return cnt
class Student:
def __init__(self,name,lastname):
self.name = name
self.lastname = lastname
class StudentCouncil(Student):
def __init__(self, name, lastname, tenure):
super().__init__(name,lastname)
self.tenure = tenure
class Principal(StudentCouncil):
def __init__(self, name, lastname, tenure,employees=None):
super().__init__(name,lastname,tenure)
if employees is None:
self.employees = []
else:
self.employees = employees
def display(self):
for names in self.employees:
print(names,end=' ')
count = Input.count()
tij = Principal('Mike','Thoma','3',count)
tij.display()
If the method takes a self parameter, you need to create an instance of the class. So it would be:
class Input:
def count(self):
cnt = []
for i in range(4):
name = input('Enter name here: ')
cnt.append(name)
return cnt
and then you would do:
myinput = Input()
count = myinput.count()
Your count() method doesn't use any attributes of self, so it doesn't currently need to be written this way. But you might want to redefine it like this:
class Input:
def __init__(self, howmany):
self.howmany = howman
def count(self):
return [input('Enter name here: ') for _ in range(self.howmany)]
myinput = Input(4)
count = myinput.count()
If count is all you want from Input, just make it a function:
def input_names():
cnt = []
for i in range(4):
name = ('Enter name here: ')
cnt.append(name)
return cnt
If you want a configurable Input type of some sort, then you want to run count on an instance of that, you need self:
class Input:
def count(self):
cnt = []
for i in range(self.num_names): # if we need some configuration
name = ('Enter name here: ')
cnt.append(name)
return cnt
Else, the kosher way to do this is to use the staticmethod decorator:
class Input:
#staticmethod
def count():
cnt = []
for i in range(4):
name = ('Enter name here: ')
cnt.append(name)
return cnt
Your current code will work as you use it currently, Input.count(), but if you instantiated an input, Input().count() would throw an exception. The staticmethod decorator ensures that this method is safe to call on either the class directly or on an instance of that class.
every one I am practicing Python, and I found something strange, here is my code
LogicG.py
class LogicGate:
def __init__(self,n):
self.label = n
self.output = None
def getLabel(self):
return self.label
def getOutput(self):
self.output = self.performGateLogic()
return self.output
class BinaryGate(LogicGate):
def __init__(self,n):
LogicGate.__init__(self,n)
self.pinA = None
self.pinB = None
def getPinA(self):
return int(input("Enter Pin A input for gate "+ self.getLabel()+"-->"))
def getPinB(self):
return int(input("Enter Pin B input for gate "+ self.getLabel()+"-->"))
class UnaryGate(LogicGate):
def __init__(self,n):
LogicGate.__init__(self,n)
self.pin = None
def getPin(self):
return int(input("Enter Pin input for gate "+ self.getLabel()+"-->"))
class AndGate(BinaryGate):
def __init__(self,n):
super(AndGate,self).__init__(self,n)
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a==1 and b==1:
return 1
else:
return 0
however, it shows the error below, I use python 3.6.4
after I mark out the code "the super" it can work ok
super(AndGate,self).init(self,n)
class AndGate(BinaryGate):
# def __init__(self,n):
# super(AndGate,self).__init__(self,n)
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a==1 and b==1:
return 1
else:
return 0
above those code just I copy from this site for python study, see that site in Listing 11, it shows these code work, but when I copy to my computer the code did not work?? I have to mark out "super" part?? why? thank you
When using super, self is passed automatically.
Also, in Python3.3 and above, super does not even need to receive arguments to know from which class it is being called. You can simply do this.
super().__init__(n)
This greatly improves maintainability, so it would be the prefered approach.
If you are using Python 3.3 and above, you should replace
LogicGate.__init__(self,n)
with
super().__init__(n)
It is better to use this format when ever you want to call super class constructor.
You don't need to pass self here:
super(AndGate,self).__init__(self,n)
It should be
super(AndGate,self).__init__(n)
I'm supposed to call on 2 different classes that then run the program so that the menu appears and the user chooses an option. I have most of the program running, but cannot check if anything is working because I keep getting the error that animal_type and name are not defined and am having trouble figuring out why. I've attached parts of each program.
Main file:
import Animal
import Zoo
def main():
#set user choice
animal = Animal.Animal()
Zoo.py:
import Animal
class Zoo:
#initialize attribute
def __init__(Animal):
Animal.__animals = []
def add_animal(Animal, animals):
Animal.__animals.append(animal)
def show_animals(Animal):
size = len(animals)
if size == 0:
print("There are no animals in your zoo!")
else:
return __animals
Animal.py:
import random
class Animal:
#initialize attributes
def __init__(self,animal_type, name, mood = None):
self.__animal_type = animal_type
self.__name = name
if mood:
self.__mood = mood
else:
self.check_mood()
# set methods
def set_animal_type(self, animal_type):
self.__animal_type = animal_type
def set_name(self, name):
self.__name = name
def set_mood(self, mood):
self.__mood = mood
In your main function, you aren't passing any of the required variables to Animal. (animal_type and animal)
You need to define them or just directly call with them.
animal = Animal.Animal('Goat', 'Billy')
or
atype = 'Goat'
aname = 'Billy'
animal = Animal.Animal(atype, aname)