Python - how to define a variable using a function? - python

I have a function that returns a number. I want to assign a variable to have this value, but python gives a runtime error when I say temp = foo(i, j) : NameError: name 'foo' is not defined. Note that I've changed the function bodies of bar and foo around, obviously having a function that just returns 1 is useless, but it doesn't change my error.
sum = 0
for i in range(2, 100):
for j in range(2, i):
temp = foo(i, j)
if (temp > 100):
sum = sum + 1
print sum
def bar (n, a):
r = 1
return r
def foo (n, a):
s = bar(n, a)/factorial(5);
return s
def factorial (n):
r = 1
for i in range (2, n + 1):
r *= i;
return r

Names in Python do not exist until they are bound. Move the def foo(...): block above the code that uses foo().

Your definition of foo is AFTER you use it in the file. Put your function definition above the for loop.

As per other answers, your issue is the order in which you run your code: foo hasn't been defined yet when you first call it. Just wanted to add a comment about best practices here.
I always try to put everything in a function and then call any scripts at the bottom. You've probably encountered this pattern before, and it's a good habit to get into:
CONSTANT = 5
def run():
for i in xrange(CONSTANT):
print foo(i) # whatever code you want
def foo(n):
# some method here...
pass
if __name__ == "__main__":
run()
if you run this with python script.py or by hitting f5 in idle, run() will be executed after everything is defined.
By following this pattern you don't have to worry about the order you define your functions in, and you get the added benefit of being able to import foo with other functions without having your script execute during the import, which is probably not a desired behavior.

Related

Varialble re-initalized in multiple function calls

I have to execute the following code wherein I will be calling the function main again and again.
so here as I need to use i = i+1, I need to declare and initialize i in the first place right, but when i call the main function it again defines i=0 and the whole purpose of i = i+1 is lost.
How can I solve this error?
I have given the condition just as an example.
Basically what I want is i should be initialized only once, inspite of how many number of times main is called.
def main():
i = 0
if 0<1:
i = i+1
y = i
There are a couple ways to do this that don't involve globals. One is capture the value of i in a closure and return a new function that increments this. You will need to call the initial function once to get the returned function:
def main():
i = 0
def inner():
nonlocal i
i += 1
return i
return inner
f = main()
f()
# 1
f()
# 2
You can also create a generator which is a more pythonic way to do this. The generator can be iterated over (although use caution since it iterates forever) or you can get a single value by passing it to next():
def main():
i = 1
while True:
yield i
i += 1
f = main()
next(f)
# 1
next(f)
# 2
You can also use itertools.count
So you haven't declared i as a global variable
Do something like this
global i
i = 0
def main():
if 0<1:
global i
i = i+1
y = i
The reason behind this is because inside a function all the variables are local meaning they only exist inside the function while the function is called, so if you want a function to be able to change a variable for the whole code, you'll need to announce it as a global so python knows to change the value of it for the entire code
I'm not sure exactly what you are trying to do, but I believe there is an easier way to do whatever it is you are doing
It looks like you want to maintain state in a function call which is a good reason to convert it to a class.
class MyClass:
def __init__(self):
self.i = 0
def main(self):
self.i += 1
y = self.i
myclass = MyClass()
myclass.main()
myclass.main()
print(myclass.i)

To call python code implemented as a class

I'm new to python, just installed vs code on my Ubuntu 18.04 and ran some simple python code such as
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 20, 100) # Create a list of evenly-spaced numbers over the range
plt.plot(x, np.sin(x)) # Plot the sine of each x point
plt.show() # Display the plot
but how could I call a python snippet defining a class?
Here I got a solution for the "longest palindromic substring" problem, implemented as a class, but without any entry point similar to C++ 's main() function. How shall I call this "longest palindromic substring" code?
class LPS:
"""
#param s: input string
#return: the longest palindromic substring
"""
def longestPalindrome(self, s):
if not s:
return ""
n = len(s)
is_palindrome = [[False] * n for _ in range(n)]
for i in range(n):
is_palindrome[i][i] = True
for i in range(1, n):
is_palindrome[i][i - 1] = True
longest, start, end = 1, 0, 0
for length in range(1, n):
for i in range(n - length):
j = i + length
is_palindrome[i][j] = s[i] == s[j] and is_palindrome[i + 1][j - 1]
if is_palindrome[i][j] and length + 1 > longest:
longest = length + 1
start, end = i, j
return s[start:end + 1]
Outside of class (and after it!) call
LPS().longestPalindrome("someString")
Note the parenthesis after LPS and before .longestPalindrome. This way you create an object of class LPS allowing you to call its "nonstatic" methods (see that longestPalindrome has self as a parameter).
Another way would be to call it as
lps = LPS()
lps.longestPalindrome("someString")
Alternatively, omit the self parameter which is completely redundant in your case and call as
LPS.longestPalindrome("someString")
Note: self is like this in Java.
Edit: I see some answers omitting () after LPS, like LPS.longestPalindrome(“someString”). This is highly unhigienic Python, just like using ”” for character literals and ’ ’ for strings, although both are correct.
Generally in Java or C we create the object of the class and access any method of that class via the object.
But in Python you can simply use the class name followed by the dot operator and finally the method you want to access, like
LPS.longestPalindrome(s)
in your case
You can simply import your class by name and use class method in another python script or same script like this
import LPS
LPS.longestPalindrome(0, "Your String")
you can do it by adding these lines of code:
if __name__ == "__main__":
# Creates object of your class
lp = LPS()
# Calls the longesetPalindrome() with "prateek" as argument
response=lp.longestPalindrome("prateek")
# Prints the response which the function returns.
print(response)
Since, you are new to python and if you are looking for something similar like 'main()' of c++ in python then you can use
if __name__ == "__main__":
it works almost similar to main() but it is not a function.
Basically, Every Python module has its name defined and if this is ‘main’, it implies that the module is being run standalone by the user and we can do corresponding appropriate actions.
The if __name__ == “main”: is used to execute some code only if the file was run directly, and not imported.

How to write a function as range?

I need to use a function as range but an error appears saying that n was not set:
NameError: name 'n' is not defined
I'm actually learning how to use python and I do not know if the syntax is correct, I just find examples of lists as ranges.
Could someone clear my ideas, give me some suggestions?
[EDIT1] My function z depends on j and f(n).
[EDIT2] I´m usind fibonacci ranges for integrate over a sphere.
The program is something like this:
def f(n):
a, b = 0, 1
for i in range(n):
a, b = b, a+b
return a
def y(n):
return f(n) + some_const
def z(j):
for j in range(0,f(n-1)):
return j*y(n) + j*f(n-1) + j*f(n)
You have
def z(j):
for j in range(0,f(n-1)):
return j*y(n) + j*f(n-1) + j*f(n)
Notice you say this takes something called j while your other functions take n.
Did you mean
def z(n):
for j in range(0,f(n-1)):
return j*y(n) + j*f(n-1) + j*f(n)
When you get an error check the line number it refers to.
Also, consider giving your variables longers names - just single letters get easy to muddle up!
As pointed out by the comment, once this stops giving the error message it might not do what you want.
You first function loops and then returns:
def f(n):
a = something
for i in range(n):
a = a + i
return a
(I presume something is set to, er, something)
Your z function returns as soon as it gets into the loop: perhaps you just want to collect the results and return them?
def z(n):
stuff = []
for j in range(0,f(n-1)):
stuff.append( j*y(n) + j*f(n-1) + j*f(n) )
return stuff
Notice the return is further left - no longer indented inside the for loop.
In fact you could use a list comprehension then:
def z(n):
return [j*y(n) + j*f(n-1) + j*f(n) for j in range(0,f(n-1))]
There are several problems with the snippet that you posted.
It would help if you include the code that calls the functions. It also seems that you should look into local-scope of vars in Python- it does not matter what you call the parameter passed into the function, so you could call the var in the brackets "n" for every function, but it is preferable to give them a meaningful name that indicates what that parameter represents- just useful for others looking at the code, and good practice!
Lastly, using a docstring inside the function makes it very clear what the functions do, and may include a desc. of the params passed (type/class).
def range_sum(n): # instead of f- range_sum seems appropriate
"""
Sums the range of numbers from 0 to n
>>> range_sum(4) # example data
10
"""
# no idea what a is meant to be, unless an accumulator to
# store the total, in which case it must be initialised
accum = 0
for i in range(1, n+1): #iterates from 1 to n
accum = aaccum + i
return a # returns the total
def y(m, const): # use a descriptive func name
"""
Sums the range of numbers from 0 to m and adds const
>>> y(4, 7) # example data
17
"""
return range_sum(m) + const
def z(j, n, m): # pass all the vars you need for the function so they have a value
"""
Something descriptive
>>> z(4, 2, 5) # example data
?
"""
total
for j in range(0,f(n-1)):
total += j*y(m) + j*f(n-1) + j*f(n)
return total
print("First Func, ", range_sum(4))
print("Second Func, ", y(4, 7))
print("Third Func, ", z(4, 2, 5))
Note that the number of arguments passed to each function matches the number expected by the function. It is possible to set defaults, but get the hang of getting this right first.
Not sure what the last function is meant to do, but as mentioned in the comment above, showing some code to illustrate how you call the code can be useful, as in the sample.

Use output of one function and average it in another function

please keep in mind that while I showcase my code, that I am fairly new to programming. So please forgive any problems. I am writing a piece of python code that uses the output of one function and then averages it in another function. I am having troubling proceeding on how to do that, this is what I have so far:
def avg(A):
if not A:
return 0
return sum(A) / len(A)
Using the function above, I have to use it to calculate the average of the function produced below:
def SampleFunction(): # Example Function
A = list(range(300))
for i in range(300):
if i%2:
A[i] = 3.1*(i+1)**1.2 - 7.9*i
else:
A[i] = 4.2*(i+2)**.8 - 6.8*i
return A
Below this is a function I have trying to tie the two together.
def average(SampleFunction):
if len(SampleFunction) == 0: return 0
return sum(SampleFunction) / len(SampleFunction)
def avg(A):
if not A:
return 0
return sum(A) / len(A)
def SampleFunction(): # Example Function
A = list(range(300))
for i in range(300):
if i%2:
A[i] = 3.1*(i+1)**1.2 - 7.9*i
else:
A[i] = 4.2*(i+2)**.8 - 6.8*i
return avg(A) #Return the avg of A instead of just A
You are right at the moment of passing SampleFunction as parameter, but it's a function, you have to call invoke it inside average():
def average(some_function):
result = some_function() # invoke
return avg(result) # use the already defined function 'avg'
When you call it, pass the function you want to average():
print average(SampleFunction)
Note:
I would recommend you to follow Python naming conventions. Names like SomeName are used for classes, whereas names like some_name are used for functions.

Taking Input from a Function Name in Python

I am attempting to write a program to perform arithmetic mod n, given n. I was wondering if there is any way within Python (preferably 2.7) to dynamically define a function such that its behavior depends on the name used to call it. More concretely, I would like to define a function named "*mod", where * is an integer, that then does arithmetic mod *. Perhaps more clearly, I would like to write one function definition for *mod that defines the functions 2mod, 3mod, 4mod, and so on. Is this possible? I apologize if a similar question has already been asked or if my answer is readily available in documentation; I tried to search for it, but I didn't know exactly how to describe the functionality that I'm looking for, so I may have missed it.
Thanks!
You don't want to do that. Just make a simple function and pass both numbers as arguments:
def mod(x, n):
return x % n
print mod(5, 2)
# 1
Well, if you really, really want to, look at this quick hack. It uses a wrapper class to wrap the module in a class, so you can use __getattr__:
import sys
import functools
def add(a, b):
return a + b
def sub(a, b):
return a - b
class Wrapper(object):
def __init__(self, wrapped):
self.wrapped = wrapped
def __getattr__(self, name):
try:
# quick hack. Don't try this at home :-)
f = ''.join(x for x in name if not x.isdigit())
n = ''.join(x for x in name if x.isdigit())
return functools.partial(getattr(self.wrapped, f), int(n))
except:
return getattr(self.wrapped, name)
sys.modules[__name__] = Wrapper(sys.modules[__name__])
Now, when you call e.g. add10(12) on this module, the result is 22. Note that method names must not start with a number, but you could use names like _add and call the methods like _55add(45) and so on.
But I would follow Haidro advice: You don't want to do that. Just calling the method with two arguments is a lot simpler.
Using globals, lambda:
for i in range(2, 5):
globals()['mod{}'.format(i)] = lambda x, n=i: x % n
assert mod2(4) == 0
assert mod2(3) == 1
assert mod3(2) == 2
assert mod3(1) == 1
assert mod4(1) == 1
assert mod4(2) == 2
assert mod4(3) == 3
assert mod4(9) == 1
You could achieve this by generating the functions as a string, and then exec this string to get the function in the current namespace. Something like:
n = 2
s = 'def mod%i(x):' % n
s += ' return x %% %i' % n
exec s
This would define the function mod2(x)

Categories

Resources