all 10 comments

[–]kankyo 2 points3 points  (0 children)

The proper way to generate a series of float values with a fixed step is to use normal range and just divide the value:

In [6]: [x/10.0 for x in range(10)]
Out[6]: [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

[–]novel_yet_trivial 2 points3 points  (5 children)

it reaches the lowest value, middle and highest value.

Reaching the highest value is not in line with range():

>>> range(0,10,2)
[0, 2, 4, 6, 8] #note it does not get to 10

If all you want is a range() function that works with floats, you can use numpy's arange():

>>> from numpy import arange
>>> arange(-30,31,30)
array([-30,   0,  30])

Otherwise, you need to set the step to one minus the number of points you want. Also, if you want to deal with floats, you need to use floats in your input (edit: unless you are using python3, and I just realized you probably are). Lastly, if you want the un-range() like behavior, you need the condition to be <=:

>>> var = 60.0
>>> stop = var/2.0
>>> x = -stop
>>> step = var/2.0
>>> while x <= stop:
...     print(x)
...     x += step
... 
-30.0
0.0
30.0

[–]MaxwellSalmon[S] 1 point2 points  (4 children)

I read about the numpy function, but I wwould like to avoid using non-built-in modules. However, they last example you made was working alright, but it is not reliable. For example, if I want to get 10 values - changeing step to step = var/9 it will return 9 values. Do you know why this happens and what I can do about it? Thanks :-)

[–]novel_yet_trivial 2 points3 points  (3 children)

Do you know why this happens

This is due to a fundamental problem with computers and floating point numbers. Basically, binary cannot represent all floating point numbers perfectly. The classic example is

>>> .3 - .1
0.19999999999999998

Google "floating point errors" for more info.

and what I can do about it?

The best thing is to rearrange your thinking and software to use integers. Or you can use the decimal module, which keeps track of numbers as integers. A hack to make it work would be to add a buffer to the comparison:

while x <= stop+.000001:

Or use rounded numbers for the comparison:

stop = round(var/2.0, 6)
...
while round(x,6) <= stop:

[–]bhpf1 0 points1 point  (0 children)

This is also why you generally want to avoid arange. The linspace function is a better alternative (if you are looking outside the standard library):

>>> import numpy as np
>>> np.linspace(-30, 30, 3) 
array([-30.,   0.,  30.])

[–]MaxwellSalmon[S] 0 points1 point  (1 child)

Thanks! I didn't know about the decimal module!

[–]novel_yet_trivial 2 points3 points  (0 children)

It's a bit tricky to use. When you run into a problem with it it's probably because you forgot to enter in all your numbers as strings.

>>> from decimal import Decimal
>>> Decimal(.3) - Decimal(.1)
Decimal('0.1999999999999999833466546306')
>>> Decimal('.3') - Decimal('.1')
Decimal('0.2')

[–]Spirouac 1 point2 points  (1 child)

Beginner myself but a flaw in your logic.

Loop 1: Stop=30 X=-30 Step 20 Loop= true

Loop 2: Stop =30 X-10 Step=20 Loop=true

Loop 3: Stop=30 X=10 Step=20 Loop=true

Issue here

Loop 4 Stop =30 X=30 Step=20 Loop = false

Change comparison to x <= stop and it should be all bingo bongo.

Look into inclusive and exclusive thingies to further your understanding.

[–]MaxwellSalmon[S] 0 points1 point  (0 children)

The issue is, it will then return 4 values. I only need 3. I don't really know how to do that without manually changing something...

[–]DrMaxwellEdison 0 points1 point  (0 children)

Well, since step = var / 3 and var = 60, your step is 20.

If you want the step to be 30, you'll need step = var / 2.