ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Sat, 03 Mar 2012 09:22:16 +0100Type error in recursionhttps://ask.sagemath.org/question/8765/type-error-in-recursion/Consider the following function:
<pre>
def f(n) :
def retfunc(x) :
return 1 if n == 0 else x*add(f(n-k) for k in (1..n))
return retfunc
</pre>
The test
<pre>
w = f(9); print w, type(w)
</pre>
gives
<pre>
"function retfunc at 0x43d3de8" "type 'function'"
</pre>
which looks fine to me. However an evaluation w(3) gives
<pre>
TypeError: unsupported operand type(s) for +: 'int' and 'function'
</pre>
How can I get around this error?
EDIT: One solution is, as indicated by DSM,
<pre>
def f(n):
retfunc(x) = 1 if n == 0 else add(x*f(n-k) for k in (1..n))
return retfunc
</pre>
What I am trying to do here? Let's see:
<pre>
for i in [1..8] : [c[0] for c in expand(f(i)(x)).coeffs()]
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
</pre>
Sat, 03 Mar 2012 02:32:30 +0100https://ask.sagemath.org/question/8765/type-error-in-recursion/Answer by Laurent Claessens for <p>Consider the following function:</p>
<pre>def f(n) :
def retfunc(x) :
return 1 if n == 0 else x*add(f(n-k) for k in (1..n))
return retfunc
</pre>
<p>The test</p>
<pre>w = f(9); print w, type(w)
</pre>
<p>gives </p>
<pre>"function retfunc at 0x43d3de8" "type 'function'"
</pre>
<p>which looks fine to me. However an evaluation w(3) gives </p>
<pre>TypeError: unsupported operand type(s) for +: 'int' and 'function'
</pre>
<p>How can I get around this error?</p>
<p>EDIT: One solution is, as indicated by DSM,</p>
<pre>def f(n):
retfunc(x) = 1 if n == 0 else add(x*f(n-k) for k in (1..n))
return retfunc
</pre>
<p>What I am trying to do here? Let's see:</p>
<pre>for i in [1..8] : [c[0] for c in expand(f(i)(x)).coeffs()]
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
</pre>
https://ask.sagemath.org/question/8765/type-error-in-recursion/?answer=13327#post-id-13327Your error is not due to recursion. The following example (slightly simplified with respect to yours) produces the same error :
def f(n) :
def retfunc(x) :
if n==0:
return 1
return x*f(3)
return retfunc
w=f(9)
w(3)
The error is at x*f(3). f(3) is a function, not a number. I don't really understand what you are trying to do. Some kind of factorial ?
The following code does not produce the error :
def f(n) :
def retfunc(x) :
if n==0:
return 1
return x*f(n-1)(3)
return retfunc
w=f(9)
print w(3)
Note : f(n-1)(3)
Hope it helps
LaurentSat, 03 Mar 2012 05:00:28 +0100https://ask.sagemath.org/question/8765/type-error-in-recursion/?answer=13327#post-id-13327Comment by petropolis for <p>Your error is not due to recursion. The following example (slightly simplified with respect to yours) produces the same error :</p>
<pre><code>def f(n) :
def retfunc(x) :
if n==0:
return 1
return x*f(3)
return retfunc
w=f(9)
w(3)
</code></pre>
<p>The error is at x*f(3). f(3) is a function, not a number. I don't really understand what you are trying to do. Some kind of factorial ?</p>
<p>The following code does not produce the error :</p>
<pre><code>def f(n) :
def retfunc(x) :
if n==0:
return 1
return x*f(n-1)(3)
return retfunc
w=f(9)
print w(3)
</code></pre>
<p>Note : f(n-1)(3)</p>
<p>Hope it helps</p>
<p>Laurent</p>
https://ask.sagemath.org/question/8765/type-error-in-recursion/?comment=20177#post-id-20177Thank you Laurent for your help. "The following code does not produce the error." Unfortunately the code also does not produce what I need :) "I don't really understand what you are trying to do." Well, I hoped that this would happen:
f(0) returns the function
retfunc(x) = 1
f(1) returns the function
retfunc(x) = x*add(f(1-k) for k in (1..1))
= x*f(0)
= x
f(2) returns the function
retfunc(x) = x*add(f(2-k) for k in (1..2))
= x*(f(1)+f(0))
= x*(x+1)
f(3) returns the function
retfunc(x) = x*add(f(3-k) for k in (1..3))
= x*(f(2)+f(1)+f(0))
= x*(x*(x+1)+x+1)
Sat, 03 Mar 2012 08:13:56 +0100https://ask.sagemath.org/question/8765/type-error-in-recursion/?comment=20177#post-id-20177Answer by DSM for <p>Consider the following function:</p>
<pre>def f(n) :
def retfunc(x) :
return 1 if n == 0 else x*add(f(n-k) for k in (1..n))
return retfunc
</pre>
<p>The test</p>
<pre>w = f(9); print w, type(w)
</pre>
<p>gives </p>
<pre>"function retfunc at 0x43d3de8" "type 'function'"
</pre>
<p>which looks fine to me. However an evaluation w(3) gives </p>
<pre>TypeError: unsupported operand type(s) for +: 'int' and 'function'
</pre>
<p>How can I get around this error?</p>
<p>EDIT: One solution is, as indicated by DSM,</p>
<pre>def f(n):
retfunc(x) = 1 if n == 0 else add(x*f(n-k) for k in (1..n))
return retfunc
</pre>
<p>What I am trying to do here? Let's see:</p>
<pre>for i in [1..8] : [c[0] for c in expand(f(i)(x)).coeffs()]
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
</pre>
https://ask.sagemath.org/question/8765/type-error-in-recursion/?answer=13328#post-id-13328I think the confusion here involves the fact that your examples use f(1) as an expression, but Python functions and the values those functions take are two different things. There are several ways to get around this:
(1) Use Sage-level functions instead; those can be added and multiplied.
# method 1
def f(n):
if n == 0:
retfunc(x) = 1
else:
retfunc(x) = add(x*f(n-k) for k in (1..n))
return retfunc
sage: f(0)
x |--> 1
sage: f(1)
x |--> x
sage: f(2)
x |--> x^2 + x
sage: f(3)
x |--> (x^2 + x)*x + x^2 + x
sage: f(3)(4)
100
(2) Use expressions instead, and substitute manually when you want to call it later:
# method 2
def f(n):
if n == 0:
retexpr = 1
else:
retexpr = add(x*f(n-k) for k in (1..n))
return retexpr
sage: f(0)
1
sage: f(1)
x
sage: f(2)
x^2 + x
sage: f(3)
(x^2 + x)*x + x^2 + x
sage: f(3)(x=4)
100
(3) Evaluate the function at x before doing the addition in your code:
# method 3
def f(n) :
def retfunc(x) :
return 1 if n == 0 else x*add(f(n-k)(x) for k in (1..n))
return retfunc
sage: [f(i) for i in [0..3]]
[<function retfunc at 0x10eee66e0>, <function retfunc at 0x10eee6668>, <function retfunc at 0x10eee6758>, <function retfunc at 0x10eee67d0>]
sage: [f(i)(x) for i in [0..3]]
[1, x, (x + 1)*x, ((x + 1)*x + x + 1)*x]
sage: [f(i)(x) for i in [0..3]]
[1, x, (x + 1)*x, ((x + 1)*x + x + 1)*x]
sage: f(3)(x=4)
100
I'd prefer (1) or (2) because it's somewhat easier to work with Sage-level objects in a calculus-y way than Python functions, but YMMV.Sat, 03 Mar 2012 08:57:50 +0100https://ask.sagemath.org/question/8765/type-error-in-recursion/?answer=13328#post-id-13328Comment by petropolis for <p>I think the confusion here involves the fact that your examples use f(1) as an expression, but Python functions and the values those functions take are two different things. There are several ways to get around this:</p>
<p>(1) Use Sage-level functions instead; those can be added and multiplied.</p>
<pre><code># method 1
def f(n):
if n == 0:
retfunc(x) = 1
else:
retfunc(x) = add(x*f(n-k) for k in (1..n))
return retfunc
sage: f(0)
x |--> 1
sage: f(1)
x |--> x
sage: f(2)
x |--> x^2 + x
sage: f(3)
x |--> (x^2 + x)*x + x^2 + x
sage: f(3)(4)
100
</code></pre>
<p>(2) Use expressions instead, and substitute manually when you want to call it later:</p>
<pre><code># method 2
def f(n):
if n == 0:
retexpr = 1
else:
retexpr = add(x*f(n-k) for k in (1..n))
return retexpr
sage: f(0)
1
sage: f(1)
x
sage: f(2)
x^2 + x
sage: f(3)
(x^2 + x)*x + x^2 + x
sage: f(3)(x=4)
100
</code></pre>
<p>(3) Evaluate the function at x before doing the addition in your code:</p>
<pre><code># method 3
def f(n) :
def retfunc(x) :
return 1 if n == 0 else x*add(f(n-k)(x) for k in (1..n))
return retfunc
sage: [f(i) for i in [0..3]]
[<function retfunc at 0x10eee66e0>, <function retfunc at 0x10eee6668>, <function retfunc at 0x10eee6758>, <function retfunc at 0x10eee67d0>]
sage: [f(i)(x) for i in [0..3]]
[1, x, (x + 1)*x, ((x + 1)*x + x + 1)*x]
sage: [f(i)(x) for i in [0..3]]
[1, x, (x + 1)*x, ((x + 1)*x + x + 1)*x]
sage: f(3)(x=4)
100
</code></pre>
<p>I'd prefer (1) or (2) because it's somewhat easier to work with Sage-level objects in a calculus-y way than Python functions, but YMMV.</p>
https://ask.sagemath.org/question/8765/type-error-in-recursion/?comment=20176#post-id-20176Thank you! First time that I hear about Sage-level functions versus Python functions.Sat, 03 Mar 2012 09:22:16 +0100https://ask.sagemath.org/question/8765/type-error-in-recursion/?comment=20176#post-id-20176