-1

I'm trying to write a function in Python which gives me values for normalized variables in a desired number of steps. I'm having a problem with rounding values and reaching 1. Since I will need these values in later computations, it is not good enough for me just to get it printed with certain number of decimals. Instead, I need Python to use them in computations like 0,0.00001,0.00002 and so on up to 1...

Here is the code....Any ideas? I forgot to mention that I wouldn't like to use the for loop....

Just to make it clear...im using recursive function to get values for u 0-> 1 which ill later use in berstain polynoms to compute bezier curves/surfaces.

from itertools import count
import sys

def b(u):

    if u>=0 and u<=1:
        u=count(0.0,0.001)
        u=u.next
        u=round(u.next(),4)   

        print(u)

        b(u)
    else:
        sys.exit(0)

b(0)
Ryne Everett
  • 6,427
  • 3
  • 37
  • 49
python starter
  • 183
  • 1
  • 12
  • 1
    Could you fix the indentation? Why are you calling b(u) within itself? – user2963623 Jul 18 '14 at 22:53
  • 1
    There are always ranges and numbers of steps which make it impossible to hit 1 exactly. You have to specify more exactly what you would like to have in those cases. – Achim Jul 18 '14 at 22:55
  • @user 2963623 I think indentation is now ok.I want to use this function for something like for loop.When I figure this out I want to implement this in code that draws bezier curve (had question related to this,you can look if you like) – python starter Jul 18 '14 at 23:00
  • @Achim of course there are but im not sure this is the case...Or is it?In which case,any ideas how to solve it? – python starter Jul 18 '14 at 23:02

1 Answers1

0

Use count from itertools:

>>> from itertools import count
>>> c = count(0.0, 0.0001)
>>> c.next()
0.0
>>> c.next()
0.0001
>>> c.next()
0.0002

count is an infinite iterator. So, as long as you keep doing .next() it will keep giving your the next number.

Keep in mind, due to the funny ways float numbers are stored, you'll eventually reach this after a few hundred .next() calls:

>>> c = count(0.0, 0.0001)
>>> ... (many .count() calls later)
>>> c.next()
0.9998999999999062
>>> c.next()
0.9999999999999062
>>> c.next()
1.0000999999999063

So either way you'll have to decide what precision you really need in your calculations. For example, if you are only concerned with 4 decimals of precision:

>>> round(c.next(), 4)
0.0999
>>> round(c.next(), 4)
0.1
>>> round(c.next(), 4)
0.1001
>>> round(c.next(), 4)
0.1002
>>> round(c.next(), 4)
0.1003

You don't need another function anymore if you use the iterator. Just call it as many times as you need to get your number range:

>>> from itertools import count
>>> numbers = []
>>> c = count(0.0, 0.0001)
>>> how_many = 10
>>> while len(numbers) != how_many:
...   numbers.append(round(next(c), 4))
... 
>>> numbers
[0.0, 0.0001, 0.0002, 0.0003, 0.0004, 0.0005, 0.0006, 0.0007, 0.0008, 0.0009]
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
  • This is different thing that I tried with my code,but Ill try this too....thank you for your answer,but can you maybe think of the way to solve the problem in the spirit of my code? – python starter Jul 19 '14 at 00:02
  • I tried it and I get Attribute error 'ittertools.count object' has no attribute 'next' ' where am I mistaking? Im using Python 3.3.4 – python starter Jul 19 '14 at 00:24
  • If you are on Python 3.4, you can do `next(c)` – Burhan Khalid Jul 19 '14 at 11:52
  • I have no doubts about solution you offered me but my implementation is,obviously incorrect....i have changed the code in my question,so if you can,please tell me why i keep getting Attribute error? – python starter Jul 19 '14 at 19:32
  • For some reason, you only use one variable `u` and keep using it for everything. At this line: `u=round(u.next(),4)` you are assigning it a float, so obviously it won't have `next` attribute. – Burhan Khalid Jul 19 '14 at 19:36
  • Burhan,thank you for your time and help...as you can guess im still learning....reason why im using only one variable is because is imagined this code in another way,and im not good at morphing code....can you please tell me how to change it...i hope im not asking too much.Thank you for your help so far,and in advance for my latest request – python starter Jul 19 '14 at 19:53
  • I have tried once more to run the code and noticed that error is in the line u=u.next().And i saw your edited answer and i would like to avoid using loops,if possible – python starter Jul 19 '14 at 19:59
  • You are using one variable `u` and you keep changing what it is pointing to. Your function, even if was to work would not do what you want because you are not returning anything. It will just print whatever `u` is; and everytime the function runs it resets the counter - in effect, you have an infinite loop. Stop giving yourself arbitrary restrictions like "avoid using loops" because a recursive function _is a loop_. – Burhan Khalid Jul 19 '14 at 20:09
  • Reason why this is just printing u is because i firstly want to make sure how it works.Later i want to implement it in a code that would use u as normalised variable in Bernstain polynoms to draw bezier curves,surfaces and many other things.I kinda solved this with for loop but had to do things like for i in range (1,1000) and then i=i/1000,and sometimes it gives me some funny things ,while loop wouldnt have this problem,but it would be good if i could just have one function which would take care of the value of u,thats why im thinking this way,plus i wanna learn several ways of dooing things – python starter Jul 19 '14 at 20:22
  • And i think that loop wasnt infinite beofre i started fixing rounding issue :) because of if statement,well it couldnt reach 1,but if you put 0.9 everything "worked" – python starter Jul 19 '14 at 20:23
  • It was infinite because you keep resetting u in the loop :) The first time u is 0, then in the loop you start a new counter, at 0, and then set u to the next value ... which will be ... 0, now you call it again in side the loop with b(0) .. and so on. Since you keep resetting the value of `u` to zero inside the loop, the if condition will never be false. – Burhan Khalid Jul 19 '14 at 20:54
  • Oh,i see but, function call b(0) is outside of loop and its just a first call of the function,i tried this function,it does increment the value of u...only problem are funny results with decimals....and i still dont know how to solve it :) – python starter Jul 20 '14 at 12:08