name 'self' is not defined when in eval() - python-3.x

Dears,
I'm trying to run this code into an eval function, but i'm getting the error below:
"name 'self' is not defined"
. Is there a way to avoid it without using global variables? Thanks!!!
This is basically the eval:
eval(sum(
sum(
self.dataset['Exposure'][c]
* self.suggested_decisions[c][d]
* int(self.constants['scaling_factor'] * self.decisions[d].variables[
'Recovery_Percentage_Segment_2'])
* self.dataset['Segment2'][c]
for c in self.all_records
)
for d in self.all_decisions
)
)
To give a bit of context I'm putting here a simplified version of my code where I'm using the eval:
class Engine:
def __init__(self, xmlpath=None, timeout=30, expr=None):
self.xml_path = xmlpath
self.decisions = None
self.dataset = None
self.constants = None
self.expr = expr
self.load_problem(self.xml_path)
self.num_records = len(self.dataset['ID'])
self.all_records = range(self.num_records)
self.all_decisions = range(len(self.decisions))
self.suggested_decisions = {}
self.timeout = timeout
def run(self):
eval("recovered_amn_segment_1 ==" + self.Sum_ForAllRecordsAndDecisions(self.expr))
def Sum_ForAllRecordsAndDecisions(self, expr):
return "sum(sum(" + expr + "for r in self.all_records) for d in self.all_decisions)"
def client():
expr = "self.suggested_decisions[r][d]*(self.dataset['Exposure'][r]*int(self.constants['scaling_factor'] * self.decisions[d].variables['Recovery_Percentage_Segment_1']*self.dataset['Segment1'][r]))"
xml_path = 'C:/Documenti/S1/Requirements/ottimizzatore/CollectionProblem.xml'
timeout = 30
engine = Engine(xml_path, timeout, expr)
engine.run()
client()
Basically from the client I'm passing a string "expr" to a class that manipulate the string and execute it. I hope it clarifies.
Thanks!!!

Related

Python 3.6 How do I create a Singleton with attributes and methods

all the examples shown just explain how to create a singleton of a class without the instantiation of any members.
But how can I produce a singleton of the following class in Python 3:
class NotOneOnly:
def __init__(self, a, b):
print("Instatiation of objects.")
self.a = a
self.b = b
def run(self):
print("Variable a = " + str(self.a) + " and variable b = " +
str(self.b))
In the main program, the use would be:
not_one_only = NotOneOnly(5, 10)
not_one_only.run()
Thanks 4 help.
After investigating a little bit, I've discovered this. So my conclusion is:
class OneOnly:
_singleton = None
a = None
b = None
def __new__(cls, a, b):
if not cls._singleton:
print("Object is created and the variables are instantiated.")
cls._singleton = super(OneOnly, cls).__new__(cls)
cls.a = a
cls.b = b
else:
print("Sorry, byt object is already made.")
return cls._singleton
def run(self):
print("Variable a = " + str(self.a) + " and variable b = " + str(self.b))
Now in the mainfile I made the following experiments showing that the singleton was created in the right way:
print("Singleton Experiment:")
a = 10
b = 5
one_only1 = OneOnly(a, b)
print(one_only1)
one_only1.run()
one_only2 = OneOnly(1, 2)
print(one_only2)
one_only2.run()
one_only1.a = 100
one_only1.run()
one_only2.run()
Now the output is:
Singleton Experiment:
Object is created and the variables are instantiated.
<__main__.OneOnly object at 0x7fa4295cbcc0>
Variable a = 10 and variable b = 5
Sorry, byt object is already made.
<__main__.OneOnly object at 0x7fa4295cbcc0>
Variable a = 10 and variable b = 5
Variable a = 100 and variable b = 5
Variable a = 100 and variable b = 5

How should define a polynomial in Python 3.7.4

I have the error in the scalar multiply and power method. I tried everything but the result always an error. Which method should fix ???
import math
import numpy as np
from scipy.integrate import quad
class Poly:
def __init__(self,coefficients):
self.coefficients = list(coefficients)
def __call__(self,x):
res = 0
for i in range(len(self.coefficients)):
res += self.coefficients[i] * x**i
return res
def add(self,p):
(coefficients1, coefficients2) = (self.coefficients, p.coefficients)
if(len(coefficients1)>len(coefficients2)):
(coefficients1, coefficients2) = (coefficients2, coefficients1)
coefficients1 = [0]*(len(coefficients2)>len(coefficients1))+coefficients1
coefficients = [coefficients1[i] + coefficients2[i] for i in range(len(coefficients1))]
return Poly(coefficients)
def scalar_multiply(self,n):
np.array(list(coefficients))
return np.array(list(coefficients))**n
def multiply(self,p):
a = self.coefficients
b = p.coefficients
M = len(a)-1
N = len(b)-1
result_coeff = np.zeroes(M+N+1)
for i in range(0,M+1):
for j in range(0,N+1):
result_coeff[i+j] += a[i]*b[j]
return Poly(result_coeff)
def power(self,n):
return np.array(list(coefficients))**n
def diff(self):
for i in range(1, len(self.coefficients)):
self.coefficients[i-1] = i*self.coefficients[i]
del self.coefficients[-1]
def integrate(self):
i = quad(diff,0,x)
print(i[x])
def eval(self):
sum = 0
for i in range(len(self.coefficients)-1,0,-1):
sum+=self.coeffs[i]*(x**i)
return sum(coeff * x**exp for exp, coeff in enumerate(reversed(self.coefficients)))
def print(self):
print(res)
The most immediate problem with the functions you mention is that they try to use a variable coefficients that has not been defined in them. You probably want to be using self.coefficients instead.
That said, there are a lot of other issues in your code (such as returning different types unexpectedly), so just fixing this one problem probably won't lead to your code working correctly, but you can try to address each other issue as you get to them.

whiile using __sub__ , the desired result is not produced in a Fraction class

Sub didn't work properly, instead of substraction in the num , it adds the num values. see my code below, other operators are working perfectly.
any help is welcome with respect. :)
def gcd(m,n):
while m%n != 0:
oldm = m
oldn = n
m = oldn
n = oldm%oldn
return n
class Fraction:
def __init__(self,top,bottom):
self.num = top
self.den = bottom
def __str__(self):
return str(self.num)+"/"+str(self.den)
def show(self):
print(self.num,"/",self.den)
def __add__(self,otherfraction):
newnum = self.num*otherfraction.den + \
self.den*otherfraction.num
newden = self.den * otherfraction.den
common = gcd(newnum,newden)
return Fraction(newnum//common,newden//common)
def __mul__(self,otherm):
newnum = self.num * otherm.num
newden = self.den * otherm.den
return Fraction(newnum, newden)
def __truediv__(self,otherd):
newnum = self.num * otherd.den
newden = self.den * otherd.num
common = gcd(newnum, newden)
return Fraction(newnum // common, newden // common)
def __eq__(self, other):
firstnum = self.num * other.den
secondnum = other.num * self.den
return firstnum == secondnum
def __sub__(self,others):
firstnum = (self.num * others.den) - (self.den * others.den)
secondnum = (self.den * others.den)
common = gcd(firstnum, secondnum)
return Fraction(firstnum // common, secondnum // common)
x = Fraction(1,3)
y = Fraction(1,3)
print(x+y)
print(x == y)
print(x * y)
print(x / y)
print(x - y)
the results produced by the machine is:
2/3
True
1/9
-2/3.
see the last one , rather than substracting, it adds in the denominator.
the actual result should be 0
at a first glance i'd say you got the numerator wrong in your __sub__. it should be:
def __sub__(self,others):
firstnum = (self.num * others.den) - (self.den * others.num) # <--
secondnum = (self.den * others.den)
common = gcd(firstnum, secondnum)
return Fraction(firstnum // common, secondnum // common)
in the line i marked with a comment i replaced ohters.den with others.num.
(not tested...)
i hope you are doing this as an exercise and you are aware that math.gcd and fractions.Fraction are implemented in python.
also gcd could be written more concise:
def gcd(a, b):
while b:
a, b = b, a % b
return a
It would be simpler to use:
def __sub__(self,others):
return self + (others * Fraction(-1,1)) # since a-b = a+(-1*b)

How to use Groovy Eval

I have a string like the following:
def slurper = new JsonSlurper()
def request = slurper.parseText(dataRequest)
def response1 = slurper.parseText(dataResponse)
Eval.me('request.variable1 = request.variable2')
But I got an error: javax.script.ScriptException: ReferenceError: "request" is not defined in at line number 1
Use groovy expression like
def a = 2
def b = 3
Eval.me("$a == $b")
or use the xy method instead
Eval.xy(a, b, 'x == y')
http://docs.groovy-lang.org/latest/html/api/groovy/util/Eval.html

Python OO, self calling other functions inside class?

I am new to object oriented concepts, and I've tried solving this problem using OO technique. I have solved it using normal programming technique, but I cant get it to work with OO technique.
here is the problem:
https://www.hackerrank.com/challenges/30-nested-logic?utm_campaign=30_days_of_code_continuous&utm_medium=email&utm_source=daily_reminder
What I've tried:
At first, I only called student1.print(). that didnt work so I called parseDate() and calculateFine().
I put self in all the variables in my student class as I fail to truly understand why or how self works.
Apologizes if I incorrectly labeled the title, but I didnt know what else to write, as I am not certain what exactly is the problem in my code.
class getFine():
def __init__ (self,expectedDate,actualDate):
self.expectedDate = expectedDate
self.actualDate = actualDate
def parseDates(self):
self.ya = self.actualDate[0]
self.ma = self.actualDate[1]
self.da = self.actualDate[0]
self.ye = self.expectedDate[0]
self.me = self.expectedDate[1]
self.de = self.expectedDate[2]
def calculateFine(self):
self.fine = 0
if(self.ya>self.ye):
self.fine = 10000
elif self.ya==self.ye:
if(self.ma>self.me):
self.fine = 500 * (self.ma-self.me)
elif(self.ma==self.me) and (self.da>self.de):
self.fine = 15 * (self.da-self.de)
def print(self):
print(self.fine)
def main():
expectedDate = str(input().split(" "))
actualDate = str(input().split(" "))
student1 = getFine(expectedDate, actualDate)
student1.parseDates()
student1.calculateFine()
student1.print()
if __name__ == "__main__":
main()
Your dates are strings, which you then want to subtract from each other. First convert them to integers or floats using something like this:
expectedDate = [int(i) for i in (input().split(" "))]
actualDate = [int(i) for i in (input().split(" "))]
Does this solve your problem?
If you want to only call the getFine.print() function and not the other funtions, you could call these class methods in the getFine.print() method. Since you probably want to separate the year month and date on every function call, you could move that part to the init method
class getFine():
def __init__ (self,expectedDate,actualDate):
self.expectedDate = expectedDate
self.actualDate = actualDate
self.ya = self.actualDate[0]
self.ma = self.actualDate[1]
self.da = self.actualDate[2] # typo here 0 --> 2
self.ye = self.expectedDate[0]
self.me = self.expectedDate[1]
self.de = self.expectedDate[2]
def calculateFine(self):
self.fine = 0
if(self.ya>self.ye):
self.fine = 10000
elif self.ya==self.ye:
if(self.ma>self.me):
self.fine = 500 * (self.ma-self.me)
elif(self.ma==self.me) and (self.da>self.de):
self.fine = 15 * (self.da-self.de)
def print(self):
self.calculateFine()
print(self.fine)
expectedDate = [int(i) for i in (input().split(" "))]
actualDate = [int(i) for i in (input().split(" "))]
student1 = getFine(expectedDate, actualDate)
student1.print()

Resources