Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Implementing some pseudocode in python

Tags:
  1. Oct 29, 2015 #1
    I need to implement the following pseudocode in Python:

    Code (Text):
    N=5            #where N is number of years
        For (rate = 0.05, rate <= 0.15, rate = rate + 0.05)
          For (principal=10000, principal <=15000, principal=principal+1000)
             simple = principal * (1 + rate * N) #where N is number of years
             compound = principal * (1 + rate) ^ N
             print simple + “ “ + compound
          EndFor
        EndFor
    However, this psudocode uses the for loop in the style of a C language. Python uses a foreach type loop, which takes a variable and iterates over a list. We typically use `range()` for this for the list, but this only takes integers as arguments, while the for loop I am trying to implement needs to take floating point numbers. Is there any simple way in which I can use a typical Python for loop to implement this? Or will I have to fall back on using a while loop with a counter variable?
     
  2. jcsd
  3. Oct 29, 2015 #2
    You can't use the built-in range() for this without obfuscating contortions. You can write your own generator for this task, with the usual caveats about floating point comparisons. Alternatively, if numpy is available you can use numpy.linspace. (Don't avoid numpy feeling that it isn't standard, it's ubiquitous for Python numeric work. Furthermore you will usually get better performance from it than by rolling your own solutions.)
     
  4. Oct 29, 2015 #3
    So assuming that I don't want to do any of the things that you suggested, I would have to use a while loop?
     
  5. Oct 29, 2015 #4

    Mark44

    Staff: Mentor

    You can use a while loop.
    Code (Python):

    rate = .05
    while rate <= .15:
       #do stuff if rate is <= .15
       rate += .05
    I should mention that because of the way floating point numbers are stored, the above loop body executes only twice, not the three times that one would expect. In most programming languages, comparison of equality of two floating point numbers is fraught with difficulty.

    The following code behaves more like what one would expect.
    Code (Python):

    rate = .125
    while rate <= 1.0:
       #do stuff if rate is <= 1.0
       rate += .125
    This loop body executes 8 times. The reason this loop works as one might expect is that all of the numbers involved (.125 and 1.0) are powers of 2 (2-3 = 1/8 = .125, and 20 = 1), and so are stored exactly. In the previous example, the numbers involved aren't powers of 2, and what is stored for each is only an approximation.
     
  6. Oct 30, 2015 #5

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    The above is problematic in almost every language. (Caveat: It's not a problem if you use fixed point decimal arithmetic package. But who does that, by default?) The problem is in how computers represent real numbers. It is quite possible that 0.05+0.05+0.05 will be greater than 0.15. On some computers, that for loop will only execute twice.

    In this particular case, you only have three values to be examined. I myself would use
    Code (Python):
    for rate in (0.05, 0.10, 0.15) :
        calculate_interests_given_rate
    This says exactly what you want to do: You want to do some calculations with those three specific rates. There's no mucking around with the vagaries of floating point arithmetic, no obfuscations involving an integer loop variable multiplied by some real scale factor.

    Being pythonic used to seem to mean finding the cleverest, most obscure way to do something. That was never the intent of being "pythonic". Being pythonic has always supposed to have meant using the one approach that is clearest and most obvious (at least to someone who understands python). In this case, explicitly enumerating the three rates you want to cover is about as pythonic as you can get. As a bonus, you can't do that in C or C++ without some contortions. Even with C++11, you'll need to use a dummy variable to hold those rates:
    Code (C):
    double rates[] = {0.05, 0.10, 0.15};
    for (auto rate : rates) {
        calculate_interests_given_rate(rate);
    }
     
    Last edited: Oct 30, 2015
  7. Oct 30, 2015 #6
    In this case your idea will work well--using a list to iterate over rather than a while loop. However, what would I do in situations that call for a large number of percentages, like 1000? I couldn't possibly store them all in a list before run-time. Usually a for-loop would be used for this, but floats are imprecise... So what would I do? (I just want to know so that I don't run into the problem in the future without knowing what to do).
     
  8. Oct 30, 2015 #7

    DrClaude

    User Avatar

    Staff: Mentor

    I don't know about python, but usually what you want is to use an integer as the loop argument, and derive floats from it:
    Code (C):

    // For (rate = 0.05, rate <= 0.15, rate = rate + 0.05)
    for (int i_rate = 5; i_rate <= 15; i_rate += 5)
       {
          float rate = i_rate /100.;
          // ...
       }
     
     
  9. Oct 30, 2015 #8
    D H provided a nice specific solution, but if you want a general one that efficiently handles large data sets then it's back to generators. They yield successive values in a sequence without constructing the entire sequence. If you want to construct your own generator rather than use something like numpy.linspace as I suggested above (this is a solved problem), then I recommend you mitigate floating point accumulation errors by calculating at the start how many values you expect in total, then multiply the output of the builtin range() function against your step size each interation.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Implementing some pseudocode in python
  1. Program Implementation (Replies: 21)

  2. Python installation (Replies: 10)

Loading...