Logarithms: A Practical Use in Python

This is a simple Python project demonstrating a useful application of logarithms. The logarithm of a number to a specified base is the power to which the base must be raised to get the number. Since their invention by John Napier in the 17th century until a few decades ago slide rules and books of log tables were used to simplify multiplication by turning it into a process of addition. Modern science, technology and engineering all depended on that simple idea.

The following example demonstrates logarithms. If...

Exponentiation

102 = 100

...then the base 10 logarithm of 100 is 2:

Logarithm

log10(100) = 2

Any number can be used as the base, but the usual bases are 2, 10 and e which is the base of natural logarithms. e is an irrational number and is 2.718281828 to 9dp. Python's math module provides functions for all three of these, and scientific calculators usually provide at least base e and base 10 logarithm keys.

The three Python functions are:

  • math.log - base e, ie. natural logarithm
  • math.log10 - base 10
  • math.log2 - base 2

John Napier, inventor of logarithms

John Napier 1550-1617, discoverer of logarithms

Coding

This project will consist of two functions, plus a main function to call them. The first function is ridiculously simple and just calculates compound interest over a period of several years, firstly just calculating the final amount and secondly calculating all interim yearly amounts.

The second function will carry out the process in reverse: starting with the opening balance and an interest rate we will calculate how long it will take for our money to grow to a specified amount. This is probably one of those little bits of mathematics that makes you think "hmm, we did that in school but I'd forgotten all about it".

I have used interest as an obvious example but of course the principle can be applied to any form of exponential growth or decay - reproduction of bacteria, radioactive decay and so on.

Create a new folder somewhere convenient and within it create an empty file called logarithms.py. You can download the zip file or clone/download the Github repo if you prefer. Then paste the following into the file.

Source Code Links

ZIP File
GitHub

logarithms.py

import math


def main():

    """
    Run the calculateamounts and timetoamount function.
    """

    print("-----------------")
    print("| codedrome.com |")
    print("| Logarithms    |")
    print("-----------------\n")

    calculateamounts(1000, 1.1, 12)

    print("")

    timetoamount(1000, 1.1, 3138.43)


def calculateamounts(startamount, interest, years):

    """
    Calculate totals including compound interest from arguments,
    as a final total and then including intermediate yearly totals.
    """

    # Calculate and show final amount
    currentamount = startamount
    # Due to operator precedence ** is evaluated before *
    endamount = startamount * interest ** years

    print("startamount {:.2f}".format(startamount))
    print("years       {:d}".format(years))
    print("interest    {:.2f}%".format((interest - 1) * 100))
    print("endamount   {:.2f}\n".format(endamount))

    # Calculate all yearly amounts.
    for y in range(1, years + 1):

        currentamount*= interest

        print("Year {:2d}: {:.2f}".format(y, currentamount))


def timetoamount(startamount, interest, requiredamount):

    """
    Calculate and print the number of years required to reach
    requiredamount from startamount at given rate of interest.
    """

    yearstorequiredamount = math.log(requiredamount / startamount) / math.log(interest)

    print("startamount           {:.2f}".format(startamount))
    print("interest              {:.2f}%".format((interest - 1) * 100))
    print("requiredamount        {:.2f}".format(requiredamount))
    print("yearstorequiredamount {:.2f}".format(yearstorequiredamount))


main()

calculateamounts

This function takes as arguments a start amount, an interest rate (which is expressed as a decimal fraction, eg. 10% would be 1.1) and a number of years. It calculates how much you will have after earning the specified interest for the specified number of years.

It actually does this twice, firstly in one hit by multiplying start amount by interest to the power of years - note the comment regarding operator precedence. It then does it year by year within a for loop.

timetoamount

Now lets get to the main purpose of this little program: given a certain amount of money earning a certain amount of interest, how long will it take for the balance to grow to a certain amount? This is calculated by taking the logarithm of the new amount as a proportion of the original amount, and dividing it by the logarithm of the growth rate. That sentence probably doesn't make sense, even if you understood how to do it beforehand, so here it is as a formula.

Formula for yearstorequiredamount

yearstorequiredamount = log(requiredamount / startamount) / log(interest)

Using the values hardcoded into main we already know that in 12 years £1,000 will grow to £3,138 at 10%pa. (If you know where I can get 10% interest please let me know immediately!) Plugging those numbers into the formula we get

Formula for yearstorequiredamount - example

yearstorequiredamount = log(3138.43 / 1000) / log(1.1)
= log(3.13843) / log(1.1)
= 0.496712446 / 0.041392685
= 12.00000546

The rounding error is less than 3 minutes so probably not worth worrying about, but basically we have turned the process round and calculated what we already knew, that it takes 12 years to get to the final amount from our starting point at the specified interest rate.

I have used math.log, the natural logarithm (base e) but it doesn't matter which you use as we are calculating ratios rather than actual amounts, as long as you use the same one both times. If you have a minute to spare try out all three, and then try breaking the code by mixing up different log functions.

Now run the program with this command:

Running the Program

python3.7 logarithms.py

This should give you the following output:

Program Output

-----------------
| codedrome.com |
| Logarithms    |
-----------------

startamount 1000.00
years       12
interest    10.00%
endamount   3138.43

Year  1: 1100.00
Year  2: 1210.00
Year  3: 1331.00
Year  4: 1464.10
Year  5: 1610.51
Year  6: 1771.56
Year  7: 1948.72
Year  8: 2143.59
Year  9: 2357.95
Year 10: 2593.74
Year 11: 2853.12
Year 12: 3138.43

startamount           1000.00
interest              10.00%
requiredamount        3138.43
yearstorequiredamount 12.00

The first chunk of output tells you that after 12 years at 10% £1000 will have grown to £3138.43. We then have the same information again but this time calculated year by year.

Lastly we reverse the process by calculating how long it will take to get to £3138.43 from £1000 at 10% pa.

Please follow this blog on Twitter for news of future posts and other useful Python stuff.

Leave a Reply

Your email address will not be published. Required fields are marked *