How to set a class of mathematical functions in Python? - python

I would like to create a math-visualisation class in Python where I can visualise optimisation algorithms. This is what I have so far:
class function_visualisation:
def objective1n1(x):
return x**5.0 - 2*x**4 - 0.5*x**3 + 4*x**2 - x
def objective2n1(x,y):
return x**5.0 - 2*y**4 - 15*x**3 + 4*y**2 - x
def __init__(self, input = 0):
self.fct_1 = self.objective1n1(x)
self.fct_2 = self.objective2n1(x,y)
Where right now I have 2 polynomials; the first taking one and the second two inputs.
Eventually I would like the class to have several adjustable function types and plotting methods. The problem is that when trying to instanciate Python says
self.fct_1 = self.objective1n1(x)
NameError: name 'x' is not defined
which I can understand.
In various posts I saw people use an intuitive technique to define functions with numpy; e.g. :
x = np.linspace(−4*np.pi,4*np.pi,50)
y = np.linspace(−4*np.pi,4*np.pi,50)
z = x**2 + y**2
Is there a good way to get something similar such that I don't have to give the function arguments in advance?
Edit:
Thanks to both of you.
but as I commented, when I initialise and insert a concrete value
fcts = function_visualisation()
print(fcts.fct_1(5))
I get
print(fcts.fct_1(5))
TypeError: objective1n1() takes 1 positional argument but 2 were given
The reason I do want a class like this is to package different plotting methods for different dimensions together and make it easy to change the function one contemplates. So how could I fix that?

When you have a function, such as
def objective1n1(x):
return x**5.0 - 2*x**4 - 0.5*x**3 + 4*x**2 - x
Calling objective1n1(x) will calculate this function at the input x, thus x has to be defined in advance (just like in your example with np.linspace).
If you simply want to assign a function object to another variable, use:
self.fct_1 = self.objective1n1
After that, you can call self.fct_1(x) for any x later in your code.

self.objective1n1(x) is the call of the function self.objective1n1. If you simply want to change which function is behind self.fct_1, you need
self.fct_1 = self.objective1n1
If you don't need the self-reference, you can use the #staticmethod decorator. However, you might want to think about not using a class for this in the first place.

To combine the answers of Martin Thoma, Mikhail Genkin and the comment of kindall:
Calling objective1n1(x) will calculate this function at the input x, thus x has to be defined in advance (just like in the example with np.linspace).
If one simply wants to assign a function object to another variable, use:
self.fct_1 = self.objective1n1
To be able to call the function like this
fcts = function_visualisation()
print(fcts.fct_1(5))
one has to define it either with a #staticmethod decorator
#staticmethod
def objective1n1(x):
return x**5.0 - 2*x**4 - 0.5*x**3 + 4*x**2 - x
or with a self reference
def objective1n1(self,x):
return x**5.0 - 2*x**4 - 0.5*x**3 + 4*x**2 - x

Related

Passing some values as variables

I'm a physics graduate student with some basic knowledge of Python and I'm facing some problems that challenge my abilities.
I'm trying to pass some variables as dummies and some not. I have a function that receives a function as the first argument, but I need that some values to be declared "a posteriori".
What I'm trying to mean is the following:
lead0 = add_leads(lead_shape_horizontal(W, n), (0, 0, n), sym0)
The function "add_leads" takes some function as well as a tuple and a third argument which is fine. But n hasn't any definition yet. I want that n has an actual sense when it enters "add_leads".
Here is the actual function add_leads
def add_leads(shape, origin_2D, symm):
lead_return = []
lead_return_reversed = []
for m in range(L):
n = N_MIN + m
origin_3D = list(origin_2D)+[n]
lead_return.append(kwant.Builder(symm))
lead_return[m][red.shape(shape(n), tuple(origin_3D))] = ONN + HBAR*OMEGA*n
lead_return[m][[kwant.builder.HoppingKind(*hopping) for
hopping in hoppings_leads]] = HOPP
lead_return[m].eradicate_dangling()
Note that n is defined under for, so, I wish to put the value of n in shape(n) (in this case leads_shape_horizontal with a fixed value for W, not for n).
I need this to be this way because eventually the function which is the argument for lead_shape might have more than 2 input values but still just need to vary n
Can I achieve this in Python? If I can, How to do so?
Help will be really appreciated.
Sorry for my english!
Thanks in advance
You probably should pass in the function lead_shape_horizontal, not the function with argument lead_shape_horizontal(W, n)
Because the latter one will return the result of the function, not function object itself. Unless the return value is also a function, you'll get an error when you later call shape(n), which is identical to lead_shape_horizontal(W, n)(n)
As for providing a fix value for W but not for n, you can either give W a default value in the function or just don't make it an argument
For example,
def lead_shape_horizontal(n, W=some_value):
# do stuff
or If you always fix W, then it doesn't have to be an argument
def lead_shape_horizontal(n):
W = some_value
# do stuff
Also note that you didn't define n when calling function, so you can't pass in n to the add_leads function.
Maybe you have to construct the origin_2D inside the function
like origin_2D = origin_2D + (n,)
Then you can call the function like this lead0 = add_leads(lead_shape_horizontal, (0, 0), sym0)
See Python Document to understand how default value works.
Some advice: Watch out the order of arguments when you're using default value.
Also watch out when you're passing in mutable object as default value. This is a common gotcha

Calling the result of a function in another function

The code is very long so I won't type it in.
What I am confused about as a beginner programmer, is function calling. So I had a csv file that the function divided all the content (they were integers) by 95 to get the normalised scores.
I finished the function by returning the result. its called return sudentp_file
Now I want to continue this new variable into another function.
So this new function will get the average of the studentp_file. So I made a new function. Ill add the other function as a template of what im doing.
def normalise(student_file, units_file)
~ Do stuff here ~
return studentp_file
def mean(studentp_file):
mean()
What I get confused about is what to put in the mean(). Do I keep it or remove it? I understand you guys don't know the file I'm working with my a little basic understanding of how functions and function calling works would be appreciated. Thanks.
When you call your function you need to pass in the parameters it needs (based on what you specified in your def statement. So you code might look like this:
def normalise(student_file, units_file)
~ Do stuff here ~
return studentp_file
def mean(studentp_file):
~ other stuff here ~
return mean
# main code starts here
# get student file and units file from somewhere, I'll call them files A and B. Get the resulting studentp file back from the function call and store it in variable C.
C = normalize(A, B)
# now call the mean function using the file we got back from normalize and capture the result in variable my_mean
my_mean = mean(C)
print(my_mean)
i assume that normalise function is executed prior to mean function? if so try out this structure:
def normalise(student_file, units_file):
#do stuff here
return studentp_file
def mean(studentp_file):
#do stuff here
sp_file = normalise(student_file, units_file)
mean(sp_file)
functions in python(2/3) are made for reusability and to keep your code organized in a block. these functions may or may not return a value, based on arguments you pass (if it accepts arguments). think of it as if functions are like real life factories making finished products. raw goods are fed into factories, so that they produce a finished product. functions are also like that. :)
now, notice that i assigned a variable called sp_file with the value of the function call normalise(...). this function call - accepted parameters (student_file, units_file) - which are your 'raw' goods to be fed towards your function normalise.
return - basically returns whatever value towards the point in your code which called your function. in this case return, returns the value of studentp_file back to sp_file. sp_file would then get studentp_file's value and can be then passed to mean() function.
/ogs
Well, it's unclear buy why not just (dummy example):
def f(a,b):
return f2(3)+a+b
def f2(c):
return c+1
Call the f2 in f and do return in f2
If the results from function one will always be called to function two you could do this.
def f_one(x, y):
return (f_two(x, y))
def f_two(x, y):
return x + y
print(f_one(1, 1))
2
Or just a thought... You could set up a variable z that works as a switch, if its 1 it passes the result to function to the next function , or if 2 returns result of function one
def f_one(x, y, z):
result = x + y
if z == 1:
return (f_two(result))
elif z == 2:
return result
def f_two(x):
return x - 1
a = f_one(1, 1, 1)
print(a)
b = f_one(1, 1, 2)
print(b)

How to save value returned from python function if call does not capture return

Let's say I have a python function, where x and y are relatively large objects (lists, NumPy matrices, etc.):
def myfun(x):
y=some complicated function of x
return y
If in an interactive session the user calls this as:
myfun(5)
The call is basically useless, since y is lost. Let's also suppose the function takes a while to run. Is there a way to retrieve the answer, so the user doesn't have to re-run, i.e. answer=myfun(5)? Alternatively, what is a good (pythonic) way to write the function to make it 'fool-proof' for this scenario? Some not-so-great options are:
Require a parameter that stores the value, e.g.
def myfun(x,y):
y = some complicated function of x
return y
Or maybe:
def myfun(x):
y = some complicated function of x
global temp
temp = y
return y
In the latter case, if a user then mistakenly called myfun(5), there's the option of y=temp to get the answer back.. but using global just seems wrong.
y=_
assuming you are in the interactive python console. _ is magic that holds the last "result"

Python: Calling Methods from a Method

I've been trying to make a soccer game using Python. Most of the problems I've run into I've been able to find a way around. However, I'm getting stuck on the error "global name '---' not defined", referring to a method name. From what I've seen, the problem deals with trying to call a method from a method. Since pasting my code would take too much time explaining what was going on, I wrote a very basic example of the problem:
class example():
def doMath(x,y):
z = x + y
z = square(z)
return z
def square(z):
z = z * z
return z
print doMath(5,4)
This is in no way meant to be a program worth writing, nor is it the smart way of doing that calculation... It just imitates the problem I'm having. This code will not work, because the method "doMath" doesn't know the method "square" exists. I've seen this fixed by making the square method a submethod (I don't know what it's called, it's just indented under the primary method). However, that is not viable in my soccer code since I'd be having multiple methods calling it. I've seen similar questions to this, but the answers still don't fit my code. A global function seems like it would be what I'm looking for, but it typically leads to an error of something not existing. I could just add a bunch of instructions to the main, but that's alot of work and lines of code that I'd prefer not to have to add - it would make it pretty ugly.
So the main question is... how can I get the doMath method to call the square method without having to combine them.
While we're at it... I've been calling these methods rather than functions... am I correct on that?
As others have noted, you need to use self, and you need to call your methods correctly, with an instance, for example:
#!/usr/bin/python
class example():
def doMath(self, x, y):
z = x + y
z = self.square(z)
return z
def square(self, z):
z = z * z
return z
p = example()
print p.doMath(5,4)
outputs:
paul#local:~/src/python$ ./square.py
81
paul#local:~/src/python$
Clearly, in this particular case there's no advantage to these methods being in a class at all, and you could more easily do:
#!/usr/bin/python
def square(z):
return z * z
def doMath(x, y):
return square(x + y)
print doMath(5,4)
While we're at it... I've been calling these methods rather than functions... am I correct on that?
method -> routine that is a member of a class.
function -> routine that returns a result (compare with mathematical function)
procedure -> routine that does not return a result
member -> part of a class or struct (either a member variable or a member function etc)
Procedures are odd in python because even though a procedure does not return anything you can still assign its result to a variable.
The result in this case is None see here: Python procedure return values
If doMath and square are part of a class, they both should have another parameter called self. Methods calls take place on this self parameter. For example:
def doMath(self, x, y):
z = x + y
z = self.square(z)
return z
class example():
def doMath(self,x,y):
z = x + y
z = self.square(z)
return z
def square(self,z):
z = z * z
return z
def p(self):
print self.doMath(5,4)
e=example()
e.p()

Python Large Functions Many Variables (Refactoring)

I have a large function in my script that contains the bulk of the logic of my program.
At one point, it used to span ~100 lines which I then tried to refactor into multiple smaller functions. However, I had many local variables that were eventually being modified in the smaller functions, and I needed some way to keep track of them in the scope of the larger function.
For instance, it looked like
def large_func():
x = 5
... 100 lines ...
to
def large_func():
x = 6
small_func_that_will_increment_x()
small_func()
....
What is a pythonic way to handle this?
The two approaches I can think of are:
1) global variables --- will probably get messy as I have many variables
2) using a dict to keep track of them like
tracker = {
'field1' : 5
'field2' : 4
}
and make modifications on the dict instead.
Is there a different way to do this that I might have overlooked?
Without more information, it's hard to know whether this is appropriate or not, but…
An object is a namespace. In particular, you can turn each of those local variables into attributes on an object. For example:
class LargeThing(object):
def __init__(self):
self.x = 6
def large_func(self):
self.small_func_that_will_increment_x()
self.small_func()
# ...
def small_func_that_will_increment_x(self):
self.x += 1
Whether the self.x = 6 belongs in __init__ or at the start of large_func, or whether this is even a good idea, depends on what all those variables actually mean, and how they fit together.
Closures will work here:
def large_func()
x = 6
def func_that_uses_x():
print x
def func_that_modifies_x():
nonlocal x # python3 only
x += 1
func_that_uses_x()
func_that_modifies_x()
Another tip - make use of Python's ability to return multiple values. If you have a function that modifies two variables, do something like this:
def modifies_two_vars(a, b, c, d):
return a+b, c+d
x, y = modifies_two_vars(x, y, z, w)
One alternative could be:
def small_func_that_will_return_new_x(old_x):
return old_x + 1
def large_func():
x = small_func_that_will_return_new_x(6)
instead of:
def large_func():
x = 6
small_func_that_will_increment_x()
Object composition. Create small objects that hold state, and then feed them as initializers an object that manages them. See Global State and Singletons
"Build the door knob, which you use to build the door, which you use to construct the house. Not the other way around"

Categories