name 'generateRandom' is not defined" - python

I'm trying to run this code but I'm getting an error msg ---> "NameError: name 'generateRandom' is not defined"
Can anyone help me please?
`import numpy as np
class Mul:
def __init__ (self,ra_result=None,rb_result=None):
self.ra_result = ra_result
self.rb_result = rb_result
def generateRandom():
return np.random.randint(0,2**32), np.random.randint(0,2**32)
def Multi_test(self):
self.ra_result,self.rb_result= generateRandom()
print("expected_output (python) = ")
print("ra=",self.ra_result,"rb=",self.rb_result," (ra*rb)=")
return self.ra_result*self.rb_result
object = Mul()
object.Multi_test()`

You have to use keyword self to let your class know you are using a method of itself.
You have to specify the self when calling the function self.generateRandom() and also you need to either specify when creating the function that it takes self as an argument, but since you have a static method, you can wrap it in #staticmethod
This is a working versio of your class Mul
class Mul:
def __init__ (self,ra_result=None,rb_result=None):
self.ra_result = ra_result
self.rb_result = rb_result
#staticmethod
def generateRandom():
return np.random.randint(0,2**32), np.random.randint(0,2**32)
def Multi_test(self):
self.ra_result,self.rb_result = self.generateRandom()
print("expected_output (python) = ")
print("ra=",self.ra_result,"rb=",self.rb_result," (ra*rb)=")
return self.ra_result*self.rb_result

I am not going to discuss why you have written your code in this way and directly talk about your error. You are getting this error because generateRandom is a method within Mul class. To refer to the other methods of the same class within a method, you should use 'self'. Additionally add static method since generateRandom doesn't use self. It would also be good if you could improve how you name variables, methods etc. The code will look like below
\
import numpy as np
class Mul:
def __init__ (self,ra_result=None,rb_result=None):
self.ra_result = ra_result
self.rb_result = rb_result
#staticmethod
def generateRandom():
return np.random.randint(0,2**32), np.random.randint(0,2**32)
def Multi_test(self):
self.ra_result,self.rb_result= self.generateRandom()
print("expected_output (python) = ")
print("ra=",self.ra_result,"rb=",self.rb_result," (ra*rb)=")
return self.ra_result*self.rb_result
my_object = Mul()
my_object.Multi_test()

The function you're trying to call, is itself a class function, I.E. it needs to be called like this:
self.generateRandom()
Edit:
You could make the generateRandom() an internal private function, by changing it to
def __generateRandom(self):
...
rng = self.__generateRandom()
In this case you can easily access it and it's still out of reach

Related

Constructing a class in python without directly calling the constructor

In python if we define a class called Start and initialize it with an argument as seen below...
class Start:
def __init__(self, a):
self.a = a
Once defined, and after importing Start into another python file is there any way to make a function or attribute inside the class so I can construct the class directly like this?
# Start.make or Start.make()
# Sample usage below
s = Start.make #initializes Start with the argument of 1
What I'm trying to do is to have Start.make accomplish the same objective as Start(1) so I can potentially create other method of constructing commonly used values without having to manually place the arguments inside the Start() constructor. Is this in anyway possible in Python? If not, are there any alternatives solutions I can follow to achieve a similar result?
You can use a static method, or you can also use a class method:
class Start:
def __init__(self, a):
self.a = a
#classmethod
def make(cls):
return cls(1)
To create an instance use the following:
>>> s = Start.make()
>>> s.a
1
With a static method:
class Start:
def __init__(self, a):
self.a = a
#staticmethod
def make():
return Start(1)
s = Start.make()

Using an attribute as argument of a method of the same class

I want to define an attribute of a class and then use it as argument of a method in the same class in the following way
class Class1:
def __init__(self,attr):
self.attr=attr
def method1(self,x=self.attr):
return 2*x
It returns an error: NameError: name 'self' is not defined
How can I define the method in such a way that whenever I don't write x explicitly it just uses the attribute attr ?
In the example, what I mean is that I would like to have
cl=Class1()
print cl.method1(12) # returns '24'
cl.attr= -2
print cl.method1() # returns '-4'
This is because in method1, you just define the self variable in the first argument. And the self variable will only useable in the function body.
You probably think self is a special keyword. Actually self is just anormal varialbe like any variable else.
To solve the issue:
Use default value in function defination and check it in the function body:
class Class1:
def __init__(self):
self.attr = 3
def method1(self, x=None):
x = self.attr if x is None else x
return 2*x
cl = Class1()
print(cl.method1(12))
cl.attr=-2
print(cl.method1())
Result:
24
-4
In your code it seems like you are naming x as an argument you are passing to the function when in reality you are giving the init function the value, try the following code:
class Class1:
def __init__(self,attr = 3):
self.attr=attr
def method1(self):
y = (self.attr)*(2)
return y
When you call the function you should do it like this:
result = Class1(4)
print(result.method1())
>>8
P.T. Im kind of new in Python so don't give my answer for granted or as if it's the best way to solve your problem.

invoking a class method inside the class itself

Hi everyone i wanna use a calculated value from a method of the class itself for the rest of the class methods but it must calculate once for all and i need to invoke method inside the class itself i write an example:
class something():
def __init__():
pass
def __sum(self, variable_1, variable_2):
self.summation = sum(variable_1, variable_2)
# I need to calculate summation here once for all:
# how does the syntax look likes, which one of these are correct:
something.__sum(1, 2)
self.__sum(1, 2)
# If none of these are correct so what the correct form is?
# For example print calculated value here in this method:
def do_something_with_summation(self):
print(self.summation)
Something like this seems to be what you're looking for:
class Something:
def __init__(self):
self.__sum(1, 2)
def __sum(self, variable_1, variable_2):
self.summation = sum(variable_1, variable_2)
Not saying this is the ideal approach or anything, but you haven't really given us much to go off of.
In general, make sure self is the first argument in all class methods, and you can call that class method at any time using either self.method_name() if you are using it from within another class method or instance.method_name() if you're using it externally (where instance = Something()).
Assuming that you would receive variable1 and variable2 when you instantiate the class one solution could be:
class something():
def __init__(self, variable1, variable2):
self.summation = variable1 + variable2
def do_something_with_summation(self):
print(self.summation)
If instead you're creating variable1 and variable2 inside other methods, then you could make them class variables:
class Something():
def __init__(self):
#Put some initialization code here
def some_other_method(self):
self.variable1 = something
self.variable2 = something
def sum(self):
try:
self.summation = self.variable1 + self.variable2
except:
#Catch your exception here, for example in case some_other_method was not called yet
def do_something_with_summation(self):
print(self.summation)

Get variable value defined in another python code

In order to create a code, I have decided to create a python class to just define some variables with default value. you can see this as "struct" in C.
the file is name : ScreenStructure.py
Inside I have defined this code
class ViewIdleScreen():
def _init_(self):
self.menu_access = "id/no_id/21"
self.Call_app = "id/no_id/23"
self.Email_app = "idno_id/24"
self.Camera_app = "id/no_id/27"
self.Browser_app = "id/no_id/26"
self.Contacts_app = "id/no_id/9"
self.Calendar_app = "id/no_id/10"
self.Messaging_app = "id/no_id/11"
self.Notes_app = "id/no_id/12"
def Call_app(self):
return self.Call_app
In the main file, I have added :
from ScreenStructure import ViewIdleScreen
later in the code of the main file:
IdleScreenView = ViewIdleScreen()
print IdleScreenView.Call_app()
but instead of displaying "id/no_id/23" it display
<bound method ViewIdleScreen.Call_app of <ScreenStructure.ViewIdleScreen instance at 0x02A16990>>
First, you're naming __init__ _init_. This is wrong. You need two underscores.
Second, you're setting an attribute Call_app there, but that's the same name as the method you define later:
def Call_app(self):
return self.Call_app
In addition to being shadowed by the attribute (if __init__ were declared properly), this method returns the method itself, which is the bound method you're seeing.
Avoid the collision of attribute and method names, and name __init__ correctly
you should not make functions named the same as data members
hello = "hello world"
def hello():
print "goodbye!"
print hello
often times people will make a variable name preceded by an underscore or something
class X:
def __init__(self,*args):
self._x = "yellow"
def x(self):
return self._x
but as #mhlester points out a main problem is that you named __init__ incorrectly

Lambda function for classes in python?

There must be an easy way to do this, but somehow I can wrap my head around it. The best way I can describe what I want is a lambda function for a class. I have a library that expects as an argument an uninstantiated version of a class to work with. It then instantiates the class itself to work on. The problem is that I'd like to be able to dynamically create versions of the class, to pass to the library, but I can't figure out how to do it since the library expects an uninstantiated version. The code below describes the problem:
class Double:
def run(self,x):
return x*2
class Triple:
def run(self,x):
return x*3
class Multiply:
def __init__(self,mult):
self.mult = mult
def run(self,x):
return x*self.mult
class Library:
def __init__(self,c):
self.c = c()
def Op(self,val):
return self.c.run(val)
op1 = Double
op2 = Triple
#op3 = Multiply(5)
lib1 = Library(op1)
lib2 = Library(op2)
#lib3 = Library(op3)
print lib1.Op(2)
print lib2.Op(2)
#print lib3.Op(2)
I can't use the generic Multiply class, because I must instantiate it first which breaks the library "AttributeError: Multiply instance has no call method". Without changing the Library class, is there a way I can do this?
Does the library really specify that it wants an "uninitialized version" (i.e. a class reference)?
It looks to me as if the library actually wants an object factory. In that case, it's acceptable to type:
lib3 = Library(lambda: Multiply(5))
To understand how the lambda works, consider the following:
Multiply5 = lambda: Multiply(5)
assert Multiply5().run(3) == Multiply(5).run(3)
There's no need for lambda at all. lambda is just syntatic sugar to define a function and use it at the same time. Just like any lambda call can be replaced with an explicit def, we can solve your problem by creating a real class that meets your needs and returning it.
class Double:
def run(self,x):
return x*2
class Triple:
def run(self,x):
return x*3
def createMultiplier(n):
class Multiply:
def run(self,x):
return x*n
return Multiply
class Library:
def __init__(self,c):
self.c = c()
def Op(self,val):
return self.c.run(val)
op1 = Double
op2 = Triple
op3 = createMultiplier(5)
lib1 = Library(op1)
lib2 = Library(op2)
lib3 = Library(op3)
print lib1.Op(2)
print lib2.Op(2)
print lib3.Op(2)
This is sort of cheating, but you could give your Multiply class a __call__ method that returns itself:
class Multiply:
def __init__(self,mult):
self.mult = mult
def __call__(self):
return self
def run(self,x):
return x*self.mult
That way when the library calls c() it actually calls c.__call__() which returns the object you want.
def mult(x):
def f():
return Multiply(x)
return f
op3 = mult(5)
lib3 = Library(op3)
print lib3.Op(2)
If I understand your problem space correctly, you have a general interface that takes 1 argument which is called using the Library class. Unfortunately, rather than calling a function, Library assumes that the function is wrapped in a class with a run method.
You can certainly create these classes programatically. Classes may be returned by methods, and thanks to the concept of closures you should be able to wrap any function in a Class that meets your needs. Something like:
def make_op(f):
class MyOp(object):
def run(self, x):
return f(x)
return MyOp
op1 = make_op(lambda x: return x*2)
op2 = make_op(lambda x: return x*3)
def multiply_op(y):
return make_op(lambda x: return x*y)
op3 = multiply_op(3)
lib1 = Library(op1)
lib2 = Library(op2)
lib3 = Library(op3)
print( lib1.Op(2) )
print( lib2.Op(2) )
print( lib3.Op(2) )
That being said, changing Library to take a function and then providing functions is probably the stronger way to do this.
Since type is the default class of a python class object, and calling a class creates a new instance of that class, calling type with the correct arguments will result in a new class.
my_class = type("my_class", (object,), {"an_attribute": 1})
my_class now refers to a new class named "my_class", which is a subclass of object, with an attribute called "an_attribute", whose value is 1. Since methods are also just class attributes pointing to a function object, you can add them to the dictionary of attributes as well:
{"an_attribute": 1, "a_method": lambda self: print("Hello")}
This is how it works. I do not recommend doing it this way, unless you absolutely need to. In 99% of all cases, you don't. Refer to #Parker Coates' answer for the clean way to achieve your goal.

Categories