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, 16 Nov 2019 03:18:26 +0100Different results with for loop and while loophttps://ask.sagemath.org/question/48767/different-results-with-for-loop-and-while-loop/ While writing a Sage script, I ran into a strange case where code worked correctly with specific constants, but when I looped over them in a `for` loop, it no longer worked. After trying this and that, I found that a `while` loop did not have this problem! As this felt very strange, recording the question here as a possible "gotcha".
Here's the code:
var('z')
from collections import defaultdict
p = defaultdict(dict)
N = 30
for h in range(N): p[0][h] = z**h
def fill(w):
for h in range(N - w):
p[w][h] = w/(w+h)*p[w-1][h+1] + h/(w+h)*(p[w][h-1] if h>=1 else 0)
## This doesn't work:
# for w in range(1, N): fill(w)
## Instead we need the below:
w = 1
while w < N:
fill(w)
w += 1
In short, the problem is that `for w in range(1, N): ...` results in all zero polynomials, while `w = 1; while w < N: ...` does not.
Fri, 15 Nov 2019 23:35:56 +0100https://ask.sagemath.org/question/48767/different-results-with-for-loop-and-while-loop/Comment by ShreevatsaR for <p>While writing a Sage script, I ran into a strange case where code worked correctly with specific constants, but when I looped over them in a <code>for</code> loop, it no longer worked. After trying this and that, I found that a <code>while</code> loop did not have this problem! As this felt very strange, recording the question here as a possible "gotcha".</p>
<p>Here's the code:</p>
<pre><code>var('z')
from collections import defaultdict
p = defaultdict(dict)
N = 30
for h in range(N): p[0][h] = z**h
def fill(w):
for h in range(N - w):
p[w][h] = w/(w+h)*p[w-1][h+1] + h/(w+h)*(p[w][h-1] if h>=1 else 0)
## This doesn't work:
# for w in range(1, N): fill(w)
## Instead we need the below:
w = 1
while w < N:
fill(w)
w += 1
</code></pre>
<p>In short, the problem is that <code>for w in range(1, N): ...</code> results in all zero polynomials, while <code>w = 1; while w < N: ...</code> does not.</p>
https://ask.sagemath.org/question/48767/different-results-with-for-loop-and-while-loop/?comment=48769#post-id-48769Related question: https://ask.sagemath.org/question/30733/error-when-using-for-in-range-but-not-for-in/Sat, 16 Nov 2019 02:07:12 +0100https://ask.sagemath.org/question/48767/different-results-with-for-loop-and-while-loop/?comment=48769#post-id-48769Answer by ShreevatsaR for <p>While writing a Sage script, I ran into a strange case where code worked correctly with specific constants, but when I looped over them in a <code>for</code> loop, it no longer worked. After trying this and that, I found that a <code>while</code> loop did not have this problem! As this felt very strange, recording the question here as a possible "gotcha".</p>
<p>Here's the code:</p>
<pre><code>var('z')
from collections import defaultdict
p = defaultdict(dict)
N = 30
for h in range(N): p[0][h] = z**h
def fill(w):
for h in range(N - w):
p[w][h] = w/(w+h)*p[w-1][h+1] + h/(w+h)*(p[w][h-1] if h>=1 else 0)
## This doesn't work:
# for w in range(1, N): fill(w)
## Instead we need the below:
w = 1
while w < N:
fill(w)
w += 1
</code></pre>
<p>In short, the problem is that <code>for w in range(1, N): ...</code> results in all zero polynomials, while <code>w = 1; while w < N: ...</code> does not.</p>
https://ask.sagemath.org/question/48767/different-results-with-for-loop-and-while-loop/?answer=48768#post-id-48768Figured out the the reason as well: with
for w in range(1, N):
fill(w)
the type of `w` is `int`, and so is the type of `h` inside the inner loop in `fill`. So something like `w/(w+h)` uses integer division (on `int`s), giving 0.
On the other hand, with
w = 1
while w < N:
fill(w)
w += 1
the type of `w` is `Integer`, so `w/(w+h)` results in a proper fraction and not 0.
Fri, 15 Nov 2019 23:38:34 +0100https://ask.sagemath.org/question/48767/different-results-with-for-loop-and-while-loop/?answer=48768#post-id-48768Comment by nbruin for <p>Figured out the the reason as well: with</p>
<pre><code>for w in range(1, N):
fill(w)
</code></pre>
<p>the type of <code>w</code> is <code>int</code>, and so is the type of <code>h</code> inside the inner loop in <code>fill</code>. So something like <code>w/(w+h)</code> uses integer division (on <code>int</code>s), giving 0.</p>
<p>On the other hand, with</p>
<pre><code>w = 1
while w < N:
fill(w)
w += 1
</code></pre>
<p>the type of <code>w</code> is <code>Integer</code>, so <code>w/(w+h)</code> results in a proper fraction and not 0.</p>
https://ask.sagemath.org/question/48767/different-results-with-for-loop-and-while-loop/?comment=48770#post-id-48770You can use `srange` to get a range of `Integer` type integers.Sat, 16 Nov 2019 03:18:26 +0100https://ask.sagemath.org/question/48767/different-results-with-for-loop-and-while-loop/?comment=48770#post-id-48770