Ask Your Question
1

For vs while loop

asked 2021-10-09 11:26:57 +0100

jhonvi2 gravatar image

updated 2021-10-09 11:35:58 +0100

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 appreciated

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
0

answered 2021-10-09 12:58:15 +0100

tmonteil gravatar image

updated 2021-10-09 17:30:11 +0100

The 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.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2021-10-09 11:26:57 +0100

Seen: 2,110 times

Last updated: Oct 09 '21