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.
Related
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.
I have some Python code in below written in Python 2.7 and I have problem with calling a function form inside another function.
class CSP:
def __init__(self, matrix):
self.X = []
self.D = []
self.C = []
self.matrix = util.copyMatrix(matrix)
self.counter = 0
# Matrix to Vector
vector = [item for line in self.matrix for item in line]
chars = map(str, vector)
result = ['*' if item == '0' else item for item in chars]
def solve(self):
""" Returns the result matrix.
The sudoku matrix is self.matrix.
Use util.printMatrix in purpose of debugging if needed. """
"*** YOUR CODE HERE ***"
def init(self,result):
for i in range(9):
for j in range(1,10):
var = var_char[i]+str(j)
self.X.append(var)
domain = set([1,2,3,4,5,6,7,8,9])
self.D.append(domain)
gamelist = result
for i in range(len(gamelist)):
if(re.match("\d+",gamelist[i])):
self.D[i] = set([int(gamelist[i])])
self.set_constraints()
#########################################################################
def set_constraints(self):
for x in self.X:
for y in self.X:
if((x[0] == y[0] and x[1] != y[1]) or (x[1] == y[1] and x[0] != y[0])):
flag = True
for c in self.C:
if(x in c and y in c):
flag = False
if(flag):
self.C.append(set([x,y]))
for a in [0,3,6]:
for b in [0,3,6]:
self.set_cube_constraints(a,b)
How to call init() function in solve() and also call self.set_constraint() inside init() function?
Within function solve(), init() is a function, not a method. Therefore it can only be called in the same manner that any other unbound function can be called: by passing the correct number of arguments to it. This would work:
init(self, results)
Note that you need to explicitly pass a reference to the object in self because init() is not a method. Within solve() self refers to the CSP instance, so this should work.
However, set_constraints() is also a normal function, so you can not call it from init() with self.set_constraints(), but set_constraints(self) should work. Note that you need to declare function set_constraints() before init() otherwise you will get a "referenced before assignment" error.
Having said all that, this is just awful. Why not make init() and set_constraints() proper methods of the class?
set_constraints is not a part of the class and therefore cannot be called with self.
If you put it one level up (remove one indentation level of it) then your code should work better.
I can see that this is some kind of coding exercise and you are told to write code in one particular place. I think you may be overcomplicating the answer because what you are coding here looks very messy by design and you should probably split out your functionality a lot more if this should be considerered clean code.
I wanted to practice recursive and decorators and try to do this simple function but it doesn't work:
def dec(func):
def wrapper(number):
print("Recursive count:")
rec_cou(number)
return wrapper
#dec
def rec_cou(number):
""" Count from 0 to a given number from 50 and up """
if number == 0:
print(number)
return number
num = rec_cou(number - 1)
print(num + 1)
return num + 1
rec_cou(53)
The recursive function alone works well, but when i add the decorator generates error: maximun recursion depth exceeded
There are two problems with your decorator:
You try to call the decorated function, effectively invoking the wrapper function again inside the decorator, thus you have an infinite recursive loop; call the original function func instead.
To the outside, the decorated function should behave just like the original function, particularly it should return its result; otherwise you will get type errors for trying to add numbers and None
Also, currently your decorator is not counting anything... try this:
def dec(func):
func.count = 0 # give each decorated function its own counter
def wrapper(number):
print("Recursive count: %d" % func.count)
func.count += 1 # increase counter
return func(number) # call original function 'func' and return result
return wrapper
Update: From your comments, it seems I misunderstood what your decorator is supposed to do, and you misunderstood how decorators work. The decorator is not called once when you first call the function, but it replaces the function with the one defined within the decorator. In other words,
#dec
def foo(...):
...
is equivalent to
def foo(...):
...
foo = dec(foo)
I.e. the decorator in invoked exactly once when the function is decorated, and the function constructed in the decorator is called each time the original function is called, replacing it. If you want to print only once, either use the decorator from the other answer, or rather use no decorator at all: Just create a wrapper that prints and then calls the function. This is not unusual for providing an 'entry point' to recursive functions.
def print_and_run(number):
print("Recursive count:")
rec_cou(number)
BTW, this is the decorator that I usually use to visualize recursive calls:
def trace(f):
trace.depth = 0
def _f(*args, **kwargs):
print " " * trace.depth, ">", f.__name__, args, kwargs
trace.depth += 1
res = f(*args, **kwargs)
trace.depth -= 1
print " " * trace.depth, "<", res
return res
return _f
To solve the maximum recursion depth problem, call the function passed into the decorator (func) rather than rec_cou and return the value of the function call. That is, on line 5, replace rec_cou(number) with return func(number).
Edit:
def decorate(function):
def wrapper(parameter):
if wrapper.initial:
print("Recursive count:")
wrapper.initial = False
result = function(parameter)
wrapper.initial = True
return result
wrapper.initial = True
return wrapper
#decorate
def count(number):
""" Prints integers on the interval [0, number] """
if number:
count(number - 1)
print(number)
count(53)
Without decorator:
def count(number):
""" Prints integers on the interval [0, number] """
if number:
count(number - 1)
else:
print("Recursive count:")
print(number)
count(53)
If all you want is for the function rec_cou to print something before its recursive descent, just modify that function and don't bother with decorators.
def rec_cou(number, internal_call=False):
""" Count from 0 to a given number from 50 and up """
if not internal_call:
print "Now performing recursive count, starting with %d" % number
if number == 0:
return number
num = rec_cou(number - 1, internal_call=True)
return num + 1
As I mentioned in my comments, all I've done is take the idea behind Joel's answer (which was to add a variable--which I called a "flag"--indicating whether the function is being called externally or as part of the recursion) and moved the flag variable (which I've called internal_call, whereas Joel called it initial) inside the function itself.
Additionally, I'm not sure what all this num business is about. Note that:
For the 0 case, rec_cou returns 0.
For number > 0, num is set to the value returned by rec_cou(number-1), then 1+num is returned.
For example, in the case of rec_cou(1), num is set to rec_cou(0), which is 0, then 0 + 1 is returned, which is 1. Similarly, for rec_cou(2), one more than the value of rec_cou(1) is returned, so 2 is returned.
In short, for every natural number, rec_cou(number) returns the value of the input number. It's not clear what you're trying to achieve, but what you've got is an identity function, which seems unlikely to be what you want.
OK, i'm using Python 2.7.3 and here is my code:
def lenRecur(s):
count = 0
def isChar(c):
c = c.lower()
ans=''
for s in c:
if s in 'abcdefghijklmnopqrstuvwxyz':
ans += s
return ans
def leng(s):
global count
if len(s)==0:
return count
else:
count += 1
return leng(s[1:])
return leng(isChar(s))
I'm trying to modify the variable count inside the leng function. Here are the things that I've tried:
If I put the variable count outside the lenRecur function it works fine the first time, but if I try again without restarting python shell, the count (obviously) doesn't restart, so it keeps adding.
If I change the count += 1 line for count = 1 it also works, but the output is (obviously) one.
So, my goal here is to get the length of the string using recursion, but I don't know how to keep track of the number of letters. I've searched for information about global variables, but I am still stuck. I don't know if i haven't understood it yet, or if I have a problem in my code.
Thanks in advance!
count in lenRecur is not a global. It is a scoped variable.
You'll need to use Python 3 before you can make that work in this way; you are looking for the nonlocal statement added to Python 3.
In Python 2, you can work around this limitation by using a mutable (such as a list) for count instead:
def lenRecur(s):
count = [0]
# ...
def leng(s):
if len(s)==0:
return count[0]
else:
count[0] += 1
return lenIter(s[1:])
Now you are no longer altering the count name itself; it remains unchanged, it keeps referring to the same list. All you are doing is altering the first element contained in the count list.
An alternative 'spelling' would be to make count a function attribute:
def lenRecur(s):
# ...
def leng(s):
if len(s)==0:
return leng.count
else:
leng.count += 1
return lenIter(s[1:])
leng.count = 0
Now count is no longer local to lenRecur(); it has become an attribute on the unchanging lenRecur() function instead.
For your specific problem, you are actually overthinking things. Just have the recursion do the summing:
def lenRecur(s):
def characters_only(s):
return ''.join([c for c in s if c.isalpha()])
def len_recursive(s):
if not s:
return 0
return 1 + len_recursive(s[1:])
return len_recursive(characters_only(s))
Demo:
>>> def lenRecur(s):
... def characters_only(s):
... return ''.join([c for c in s if c.isalpha()])
... def len_recursive(s):
... if not s:
... return 0
... return 1 + len_recursive(s[1:])
... return len_recursive(characters_only(s))
...
>>> lenRecur('The Quick Brown Fox')
16
I think You can pass count as second argument
def anything(s):
def leng(s, count):
if not s:
return count
return leng(s[1:], count + 1)
return leng(isChar(s), 0)
this should work better than muting objects from outer scope such as using mutable objects (list or dict) or monkey-patching function itself for example.
You need to make the variable count a function variable like
def lenRecur(s):
lenRecur.count = 0
However, I see a few problems with the code.
1) If you are trying to find the number of alphabets in a string through recursion, this one will do:
def lenRecur(s):
def leng(s, count = 0):
if not s:
return count
else:
count += int(s[0].isalpha())
return leng(s[1:], count)
return leng(s)
But still I would prefer having a single function to do the task, like there will be no leng method at all.
2) If your goal is just to find the number of alphabets in a string, I would prefer list comprehension
def alphalen(s):
return sum([1 for ch in s if ch.isalpha()])
If this is anything other than learning purpose, I suggest you to avoid recursion. Because, the solution cannot be used for larger strings(lets say, finding the alphabet count from contents of a file). You might hit the RunTimeError of Maximum Recursion Depth Exceeded.
Even though you can work around this through setting the recursion depth through setrecursionlimit function, I suggest you to go for other easy ways. More info on setting the recursionlimit here.
Define it outside all function definitions, if you want to use it as a global variable:
count = 0
def lenRecur(s):
or define it as a function attribute:
def lenRecur(s):
lenRecur.count = 0
def isChar(c):
This has been fixed in py3.x where you can use the nonlocal statement:
def leng(s):
nonlocal count
if len(s)==0:
You don't need count. The below function should work.
def leng(s):
if not s:
return 0
return 1 + leng(s[1:])
Global variable in recursion is very tricky as the depth reaches to its last state and starts to return back to the first recursive call the values of local variables change so we use global variables. the issue with global variables is that when u run the func multiple times the global variable doesn't reset.
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.