1

This is a simple exercise found in a book, which asks us to determine how long it takes for an amount to double at a given interest rate. My code is like this:

def main():
  x = eval(raw_input("Initial Principal: "))
  y = eval(raw_input("Interest rate: "))
  count = 0
  while x < 2*x:
      x = x * (1 + y)
      count = count + 1

  print (x)
  print (count)

main()

What it returns is:

Initial Principal: 1000 Interest rate: 0.5 inf 1734

What's wrong with my code? Also I wonder if the above code would work if my amount and interest is small, e.g. amount = 1 and interest rate = 0.05, since there would include some floating point arithmetic I guess.

Thank you!

mathshungry
  • 153
  • 4

2 Answers2

3

The culprit is the fact that you write:

while x < 2*x:

Since x > 0, that relation will always be False, you do not compare the new x with the old x, you compare the new x with twice the new x.

We can solve this effectively by using a variable x0 that store the initial amount:

def main():
  x = x0 = eval(raw_input("Initial Principal: "))
  y = eval(raw_input("Interest rate: "))
  count = 0
  while x < 2*x0:
      x = x * (1 + y)
      count = count + 1

  print (x)
  print (count)

main()

But there are still some problems with the code. For example you use eval. Do not use eval unless you absolutely have to: now a person can enter any type of Python code, also code that will break the system. Use float(..) instead to convert a string to an int:

def main():
  x = x0 = float(raw_input("Initial Principal: "))
  y = float(raw_input("Interest rate: "))
  count = 0
  while x < 2*x0:
      x = x * (1 + y)
      count = count + 1

  print (x)
  print (count)

main()

But now the code is still inefficient. There exists a fast way to calcuate the number of years using logarithms:

from math import log, ceil, pow

def main():
  x = x0 = float(raw_input("Initial Principal: "))
  y = float(raw_input("Interest rate: "))
  count = ceil(log(2.0, y+1.0))
  newx = x * pow(1.0+y, count)
  print (newx)
  print (count)
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
2

The problem is your while guard, which checks if the number is less than two times itself. To solve this, save the threshold you want to reach in a variable before the loop, and you have done:

threshold = 2 * x
count = 0
while x < threshold:
    x = x * (1 + y)
    count = count + 1
Roberto Trani
  • 1,217
  • 11
  • 14
  • Oh right! I know what's wrong with the condition, the variable will keep on changing. – mathshungry Jan 28 '18 at 15:31
  • As pointed out by @Rawing, avoid to use eval of raw_input. It's safer to use `float(raw_input(...))` in your case, which converts the string into a float as required, and raises an exception if the string cannot be converted. – Roberto Trani Jan 28 '18 at 15:36