1 | initial version |

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 (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*o < 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.

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.

2 | No.2 Revision |

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 (infinite loop).~~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*o < 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.

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.

3 | No.3 Revision |

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*o < 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.~~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.

4 | No.4 Revision |

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.

Here is a simple possibility:

```
squares = []
i = 0
while i*i < n:
squares.append(i*i)
i += 1
```

```
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*o ~~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).

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

Copyright Sage, 2010. Some rights reserved under creative commons license. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license.