views:

93

answers:

4

Hi there. I'm a very new python user (had only a little prior experience with html/javascript as far as programming goes), and was trying to find some ways to output only intermittent numbers in my loop for a basic bicycle racing simulation (10,000 lines of biker positions would be pretty excessive :P).

I tried in this loop several 'reasonable' ways to communicate a condition where a floating point number equals its integer floor (int, floor division) to print out every 100 iterations or so:

 for i in range (0,10000):
  i = i + 1
  t = t + t_step #t is initialized at 0 while t_step is set at .01
  acceleration_rider1 = (power_rider1 / (70 * velocity_rider1)) - (force_drag1 / 70)
  velocity_rider1 = velocity_rider1 + (acceleration_rider1 * t_step)
  position_rider1 = position_rider1 + (velocity_rider1 * t_step)
  force_drag1 = area_rider1 * (velocity_rider1 ** 2) 
  acceleration_rider2 = (power_rider2 / (70 * velocity_rider1)) - (force_drag2 / 70)
  velocity_rider2 = velocity_rider2 + (acceleration_rider2 * t_step)
  position_rider2 = position_rider2 + (velocity_rider2 * t_step)
  force_drag2 = area_rider1 * (velocity_rider2 ** 2)

  if t == int(t): #TRIED t == t // 1 AND OTHER VARIANTS THAT DON'T WORK HERE:(
   print t, "biker 1", position_rider1, "m", "\t", "biker 2", position_rider2, "m" 
+2  A: 

To print out every 100 iterations, I'd suggest

if i % 100 == 0: ...

If you'd rather not print the very first time, then maybe

if i and i % 100 == 0: ...

(as another answer noted, the i = i + 1 is supererogatory given that i is the control variable of the for loop anyway -- it's not particularly damaging though, just somewhat superfluous, and is not really relevant to the issue of why your if doesn't trigger).

While basing the condition on t may seem appealing, t == int(t) is unlikely to work unless the t_step is a multiple of 1.0 / 2**N for some integer N -- fractions cannot be represented exactly in a float unless this condition holds, because floats use a binary base. (You could use decimal.Decimal, but that would seriously impact the speed of your computation, since float computation are directly supported by your machine's hardware, while decimal computations are not).

Alex Martelli
Yeah, I was using my own crude method to avoid printing out the first value of t... always great to learn a little more computing theory with each mistake made, though :)
Jonathan Straus
+3  A: 

The for loop auto increments for you, so you don't need to use i = i + 1.

You don't need t, just use % (modulo) operator to find multiples of a number.

# Log every 1000 lines.
LOG_EVERY_N = 1000

for i in range(1000):
  ... # calculations with i

  if (i % LOG_EVERY_N) == 0:
    print "logging: ..."
Stephen
+2  A: 

The other answers suggest that you use the integer variable i instead. That also works, and is the solution I would recommend. This answer is mostly for educational value.

I think it's a roundoff error that is biting you. Floating point numbers can often not be represented exactly, so adding .01 to t for 100 times is not guaranteed to result in t == 1:

>>> sum([.01]*100)
1.0000000000000007

So when you compare to an actual integer number, you need to build in a small tolerance margin. Something like this should work:

if abs(t - int(t)) < 1e-6:
 print t, "biker 1", position_rider1, "m", "\t", "biker 2", position_rider2, "m" 
Thomas
hmm, that's really interesting, I never knew about this 'error margin' in simple operations before... I'll have to try it out :)
Jonathan Straus
A: 

With this, the program only prints out the stuff before the loop. Didn't know if there was anything built-in the library that would allow me to use a similar method for returning only desired multiples of input values?

Thanks again for reading :)

-Jonathan

Jonathan Straus
Thanks for all your help guys... I found using the modulo method on i worked particularly well!
Jonathan Straus