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, 09 Oct 2021 12:58:15 +0200For vs while loophttps://ask.sagemath.org/question/59301/for-vs-while-loop/Hi there! I am new to sageMath and I´m trying to solve a certain exercise with my buddy, the thing is that we need a list of perfect squares and I though that I could do it this way
n =95
squares=[]
edges=[];
for i in range(int(sqrt(n)+1)):
squares.append(i*i)
Then @tmonteil told me that it would be a good idea to use the while loop because I am interating until the `int(sqrt(n)+1)`condition is no longer true which make sense to me, therefore this would be what I think is equivalent.
n =95
squares=[]
edges=[]
i=0
root= int(sqrt(n)+1)
while i < root:
squares.append(i*i)
however I keep getting this `Traceback (most recent call last)` in different parts of the code, and I don't really know why, any help will be much I appreciatedSat, 09 Oct 2021 11:26:57 +0200https://ask.sagemath.org/question/59301/for-vs-while-loop/Answer by tmonteil for <p>Hi there! I am new to sageMath and I´m trying to solve a certain exercise with my buddy, the thing is that we need a list of perfect squares and I though that I could do it this way</p>
<pre><code>n =95
squares=[]
edges=[];
for i in range(int(sqrt(n)+1)):
squares.append(i*i)
</code></pre>
<p>Then <a href="/users/1305/tmonteil/">@tmonteil</a> told me that it would be a good idea to use the while loop because I am interating until the <code>int(sqrt(n)+1)</code>condition is no longer true which make sense to me, therefore this would be what I think is equivalent.</p>
<pre><code>n =95
squares=[]
edges=[]
i=0
root= int(sqrt(n)+1)
while i < root:
squares.append(i*i)
</code></pre>
<p>however I keep getting this <code>Traceback (most recent call last)</code> in different parts of the code, and I don't really know why, any help will be much I appreciated</p>
https://ask.sagemath.org/question/59301/for-vs-while-loop/?answer=59303#post-id-59303The main thing that is wrong in your code is that you do not update the value of `i` so that i stays equal to `0` forever, hence you get an infinite loop.
The idea behind my suggestion to use a while`` loop was to avoid the use of the computation of the square root , which is slow (moreover, the way it is done, it involves the symbolic ring, which is very slow).
Here is a simple possibility:
squares = []
i = 0
while i*i < n:
squares.append(i*i)
i += 1
As you can see, i do not compute any square root. To make my point, let me define two function and compare their speed:
def slow(n):
squares=[]
for i in range(int(sqrt(n)+1)):
squares.append(i*i)
return squares
def fast(n):
squares = []
i = 0
while i*i < n:
squares.append(i*i)
i += 1
return squares
Now, let us benchmark:
sage: n = 95
sage: %time slow(n)
CPU times: user 12.3 ms, sys: 0 ns, total: 12.3 ms
Wall time: 11.4 ms
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
sage: %time fast(n)
CPU times: user 71 µs, sys: 9 µs, total: 80 µs
Wall time: 91.8 µs
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
As you can see, it is 100 times faster. You can also increase `n` and use `%timeit` instead of `%time` to test many times in a row and avoid some startup bias (note however that the square root is computed only once).
As a last word, you can notice that i compute the square of `i` twice in my function which is useless and costly ; as an exercice, you could try to avoid such a double computation and check if your method increases the speed.Sat, 09 Oct 2021 12:58:15 +0200https://ask.sagemath.org/question/59301/for-vs-while-loop/?answer=59303#post-id-59303