Python Implementing some pseudocode in python

  • Thread starter Thread starter Mr Davis 97
  • Start date Start date
  • Tags Tags
    python
Click For Summary
The discussion centers on converting pseudocode for calculating simple and compound interest into Python. The pseudocode employs a C-style for loop, which is not directly compatible with Python's for-each loop structure. Participants highlight that Python's `range()` function only handles integers, complicating the implementation for floating-point numbers. Suggestions include using a while loop to increment the rate and principal, but caution is given regarding floating-point precision issues that can lead to unexpected results. An alternative approach is proposed: explicitly enumerating the specific rates (0.05, 0.10, 0.15) to avoid floating-point complications, which is considered a more "pythonic" solution. For scenarios requiring a large number of rates, the discussion suggests using integer indices to derive floating-point values or creating a generator to yield values without constructing the entire sequence, thereby efficiently managing large datasets.
Mr Davis 97
Messages
1,461
Reaction score
44
I need to implement the following pseudocode in Python:

Code:
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?
 
Technology news on Phys.org
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.)
 
Integrand said:
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.)

So assuming that I don't want to do any of the things that you suggested, I would have to use a while loop?
 
Mr Davis 97 said:
I need to implement the following pseudocode in Python:

Code:
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?
You can use a while loop.
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.
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.
 
Mr Davis 97 said:
Code:
For (rate = 0.05, rate <= 0.15, rate = rate + 0.05)
    calculate_interests_given_rate

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.

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?

In this particular case, you only have three values to be examined. I myself would use
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:
C:
double rates[] = {0.05, 0.10, 0.15};
for (auto rate : rates) {
    calculate_interests_given_rate(rate);
}
 
Last edited:
D H said:
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
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:
C:
double rates[] = {0.05, 0.10, 0.15};
for (auto rate : rates) {
    calculate_interests_given_rate(rate);
}

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).
 
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:
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.;
      // ...
   }
 
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.
 

Similar threads

  • · Replies 16 ·
Replies
16
Views
3K
  • · Replies 0 ·
Replies
0
Views
1K
  • · Replies 4 ·
Replies
4
Views
6K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 6 ·
Replies
6
Views
2K
Replies
3
Views
4K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 1 ·
Replies
1
Views
4K
Replies
12
Views
7K
  • · Replies 14 ·
Replies
14
Views
5K