Class Variable Updating - python

I built a class to handle a lot of different functions that take common inputs. However, I just ran into the situation where one of the variables that's fed down through self needs to be changed. How do I do this? This is an example:
class Test:
def __init__(self, test_variable):
self.test_var = test_variable
#property
def some_function(self):
if self.test_var < 0:
self.test_var = 'New Output' #this is the line that I can't get
#get to work and I was hoping to update it here
#so I could use it in later functions
return self.test_var
Thank you!

You should drop the #property attribute. Then, you can set it by just doing x.test_var = 5. E.g.,
class Test:
def __init__(self, test_variable):
self.test_var = test_variable
def some_function(self):
if self.test_var < 0:
self.test_var = 'New Output' #this is the line that I can't get
#get to work and I was hoping to update it here
#so I could use it in later functions
return self.test_var
x = Test(-1)
print(x.some_function())
x.test_var = 5
print(x.some_function())
returns
New Output
5

Related

python, calling a method from another class

I am trying to call the sum_method function from my evaluation class to my main one, however I run into many errors. I want to use the new_data as the data parameter of my sum_method function.
evaluation class:
class evaluation():
def __init__(self, data):
self.data = data
def sum_method(self):
montant_init = self.data.loc[self.data['Initiateur'] == 'Glovoapp', 'Montant (centimes)'].sum()
print(montant_init)
main class:
class main(evaluation):
new_data.to_csv("transactions.csv", index=False)
self.data = new_data
def call_sum(self, new_data):
init_eval = evaluation.sum_method(self=new_data)
print(init_eval)
init_evalobj = main()
init_evalobj.call_sum()
if you use the method in your inherence class just use self
so:
init_eval = self.sum_method()
the self argument is passed in python automaticly as first parameter
update
you also should return a value:
def sum_method(self):
montant_init = self.data.loc[self.data['Initiateur'] == 'Glovoapp', 'Montant (centimes)'].sum()
print(montant_init)
return montant_init
I'd suggest making some changes to the both classes, to encapsulate the .data member variable in the base class. My preference would also be to separate out the calculation from the display, so leave all the print statements in the call_sum() function.
class evaluation:
def __init__(self, data):
self.data = data
def sum_method(self):
montant_init = self.data.loc[self.data['Initiateur'] == 'Glovoapp', 'Montant (centimes)'].sum()
return montant_init
class main(evaluation):
def __init__(self):
# Reduce csv content to what's needed for analysis
data_csv = pd.read_csv('transactions.csv')
# --> removing unnecessary data
new_data = data_csv[['Opération', 'Initiateur', 'Montant (centimes)', 'Monnaie',
'Date', 'RĂ©sultat', 'Compte marchand', 'Adresse IP Acheteur', 'Marque de carte']]
# --> saving changes...
new_data.to_csv("transactions.csv", index=False)
super().__init__(new_data) //Initialize the base class
def call_sum(self):
print('Glovoapp "montant" generated')
init_eval = self.sum_method() //Call the method from the base class
print(init_eval)

divide classes into sub functions/classes python

First time poster and python newbie here, this question is probably asked before, but I am not able to find any answer.
I have a Class that reads robot status data, this works fine and I am able to dive my data into methods that are working fine when i call them. But I would like to divide my class even more, so the data is structured better. for example
I have some methods the reads and return target_data
def target_joint_positions(self):
t_j_p = self.read_data()[1:7]
return t_j_p
def target_joint_velocities(self):
t_j_v = self.read_data()[7:13]
return t_j_v
def target_joint_currents(self):
t_j_c = self.read_data()[19:25]
return t_j_c
And similar methods returning actual_data:
def actual_joint_positions(self):
a_j_p = self.read_data()[31:37]
return a_j_p
def actual_joint_velocities(self):
a_j_v = self.read_data()[37:43]
return a_j_v
def actual_joint_currents(self):
a_j_c = self.read_data()[43:49]
return a_j_c
So what I would like to accomplish is that when i make a instance of my class, instead of getting all the methods i would like something like this:
inst = Class_Name()
inst.target. (list of target methods)
inst.actual. (list of actual methods)
I have looked into nested classes and inheritance but I have not been successful in achieving my goal. Thanks for any pointers.
Welcome!
You can do the following:
class TargetMetrics:
def __init__(self, data):
self.data = data
def joint_positions(self):
return self.data[1:7]
...
class ActualMetrics:
def __init__(self, data):
self.data = data
def joint_positions(self):
return self.data[31:37]
...
class RobotMetrics:
def __init__(self):
data = read_data()
self.actual = ActualMetrics(data)
self.target = TargetMetrics(data)
...

Python OOP output return is wrong, someone has an idea?

I'm currently learning how to write object oriented programming in python and I have this code I wrote (well part of it, some of it is part of the class I'm following)
class Toolbox:
def __init__(self, tool):
pass
class Hammer:
def __init__(self, color):
pass
class Screwdriver:
def __init__(self, size):
pass
class Screw:
MAX_TIGHTNESS = 5
def __init__(self):
self.tightness = 0
def loosen(self):
if (self.tightness > 0):
self.tightness -= 1
def tighten(self):
if (self.tightness < self.MAX_TIGHTNESS):
self.tightness += 1
def __str__(self):
return "Screw with tightness {}".format(self.tightness)
class Nail:
def __init__(self):
self.in_wall = False
def nail_in(self):
if (not self.in_wall):
self.in_wall = True
def remove(self):
if (self.in_wall):
self.in_wall = False
def __str__(self):
return "Nail {}in wall.".format("" if self.in_wall else "not ")
hammer = Hammer("blue")
sdriver = Screwdriver("300")
#tbox = Toolbox()
tool1 = Toolbox(hammer)
tool2 = Toolbox(sdriver)
screw1 = Screw()
print(screw1)
screw1.tighten()
print(screw1)
nail1 = Nail()
print(nail1)
nail1.nail_in
print(nail1)
The output of print(screw1) works but print(nail1) gives me the same output (Nail in wall.) twice instead Nail in wall. I guess there's a problem in my logic and I can't seem to figure it out. Can someone help me?
Thanks!
Marc
You need to call nail_in - just as you are already doing with screw1.tighten. So do this (note the brackets here):
nail1.nail_in()
With this fix, your code works:
Screw with tightness 0
Screw with tightness 1
Nail not in wall.
Nail in wall.
By referring to the function but without the brackets, it is a syntactically valid line of code, but it is just an expression for the function object itself, and as you are not doing anything with it (such as assigning it to a variable), it is then simply discarded.

python super :TypeError: __init__() takes 2 positional arguments but 3 were given

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)

calling a method inside a class-Python

class Time:
def __init__(self,x,y,z):
self.hour=x
self.minute=y
self.second=z
def __str__(self):
return "({:02d}:{:02d}:{:02d})".format(self.hour, self.minute, self.second)
def time_to_int(time):
minutes=time.hour*60+time.minute
seconds=minutes*60+time.second
return seconds
def int_to_time(seconds):
time=Time()
minutes,time.second=divmod(seconds,60)
time.hour,time.minute=divmod(minutes,60)
return time
def add_time(t1,t2):
seconds=time_to_int(t1)+time_to_int(t2)
return int_to_time(seconds)
start=Time(9,45,00)
running=Time(1,35,00)
done=add_time(start,running)
print(done)
I am new to python and i've been doing some practice lately.I came across a question and i've written the code for the same.But I am repeatedly getting an error: "add_time is not defined". I tried defining a main() method but then it doesn't print anything.Please help.
You haven't created an object to the above class.
Any function/method inside a class can only be accessed by an object of that class .For more information on the fundamentals of Object Oriented Programming, please check this page.
Meanwhile for this to work, define your class in the following way :
class Time:
def __init__(self,x=None,y=None,z=None):
self.hour=x
self.minute=y
self.second=z
def __str__(self):
return "({:02d}:{:02d}:{:02d})".format(self.hour, self.minute, self.second)
def time_to_int(time):
minutes=time.hour*60+time.minute
seconds=minutes*60+time.second
return seconds
def int_to_time(seconds):
time=Time()
minutes,time.second=divmod(seconds,60)
time.hour,time.minute=divmod(minutes,60)
return time
def add_time(t1,t2):
seconds=time_to_int(t1)+time_to_int(t2)
return int_to_time(seconds)
and outside the class block, write the following lines :
TimeObject = Time()
start=Time(9,45,00)
running=Time(1,35,00)
TimeObject.add_time(start,running)
print "done"
I however suggest you to write the add_time function outside the class because you are passing the objects to the class as the parameters to the function within the same class and it is considered as a bad design in object oriented programming.
Hope it helps. Cheers!
This works fine for me as long as you specified 3 args in your constructor
def int_to_time(seconds):
time=Time(0,0,0) # just set your 3 positionals args here
minutes,time.second=divmod(seconds,60)
time.hour,time.minute=divmod(minutes,60)
return time
Another way to avoid it could be:
class Time:
def __init__(self,x=0,y=0,z=0):
self.hour=x
self.minute=y
self.second=z
If you want to add your functions to your class (such as time_to_int, int_to_time or even add_time) then you will need to indent with one more level of 4 spaces and add self to your method parameters
Hii Mathers25,
I solve your problem try this below code to get the best output,
class TimeClass:
def __init__(self,x,y,z):
self.hour = x
self.minute = y
self.second = z
def __str__(self):
return "({:02d}:{:02d}:{:02d})".format(self.hour, self.minute, self.second)
def time_to_int(self,time):
minutes = (time.hour * 60) + time.minute
seconds = (minutes * 60) + time.second
return seconds
def int_to_time(self,seconds):
time = TimeClass(0,0,0)
minutes,time.second=divmod(seconds,60)
time.hour,time.minute=divmod(minutes,60)
return time
def add_time(self,t1,t2):
seconds = self.time_to_int(t1) + self.time_to_int(t2)
# Call method int_to_time() using self keyword.
return self.int_to_time(seconds)
# First time object create that time set value is 0 of hour,minute and second
TimeObject = TimeClass(0,0,0)
# After create second object
start=TimeClass(9,45,00)
# After create thired Object
running=TimeClass(1,35,00)
# Store the value which return by add_time()
done = TimeObject.add_time(start,running)
# Display the value of done variable
print(done)
class Employee:
def __init__(self):
self.wage = 0
self.hours_worked = 0
def calculate_pay(self):
return self.wage * self.hours_worked
alice = Employee()
alice.wage = 9.25
alice.hours_worked = 35
print('Alice:\n Net pay: {:.2f}'.format(alice.calculate_pay()))
barbara = Employee()
barbara.wage = 11.50
barbara.hours_worked = 20
print('Barbara:\n Net pay: {:.2f}'.format(barbara.calculate_pay()))
Works for me:
class C:
def f(a, b):
return a + b
x = f(1,2)
print(C.x)
but you should not do such things. Code in class-level is executing when class is "creating", usually you want static methods or class methods (decorated with #staticmethod or #classmethod) and execute code in some function/instantiated class. Also you can execute it on top (module) level if this is the simple script. Your snippet is "bad practice": class level (i'm talking about indentation) is for declarations, not for execution of something. On class-level is normal to execute code which is analogue of C macros: for example, to call decorator, to transform some method/attribute/etc - static things which are "pure" functions!

Categories

Resources