FE 'tkGooie' Utilities

'MATHtools' group

Compound Interest
Dream Crushed"

('e'   =
is the limit)

(FE = Freedom Environment)

The GUI interface to QUICKLY
'compound' interest for
various sub-periods of a year
showing that bankers could not
triple their money in a year at
100% annual interest --- even
when broken up and 'compounded'
every millisecond.

Larger, hi-res image is below.

FE Home Page > FE Downloads Page >

FE 'tkGooies' Description Page >

FE 'tkGooies' 'MATHtools' Page >

code Page

INTRODUCTION to Tcl-Tk script
'tkLenders CompoundInterestDreamCrushed'

For several years now (circa 2013-2015), I have been planning to make a Tk GUI that quickly performs some 'compound interest' calculations that clearly demonstrate that there is a definite limit to how much interest a lender could collect from a borrower, by 'compounding' a given annual interest rate over a year.

A Review of Compounding Interest:

Note that by compounding of an annual interest rate 'r', the lenders historically mean 'chopping up' that interest rate into equal amounts --- such as 12ths for 12 months of the year.

Then, instead of applying 'r' once, at the end of the year, to the principal P, the lender applies r/12 to P in the first month getting an amount owed at the end of the first month, say S1.

Then S1 is the original principal P plus r/12 times P --- or

P * (1 + r/12).

Now the lender takes that amount to be the new principal to be lent with interest for another month --- and we calculate the amount S2 owed at the end of the 2nd month.

So, the interest for the 2nd month is S1 * r/12, and that is added to the principal S1 at the start of the 2nd month.

This means that

    S2 = S1 + S1 * r/12
          = S1 * (1 + r/12)
          = P * (1 + r/12) * (1 + r/12)

where we used the expression for S1 that we found above.

You may see the start of a pattern here, but let's take this one more month.

We want to calculate the amount owed at the end of month 3, say S3.

The lender takes the amount owed at the end of month 2 to be the new principal --- which is lent with interest for another month.

The lender calculates the number S3 owed at the end of the 3rd month as follows.

The interest for the 3rd month is S2 * r/12, and that is added to the principal S2 at the start of the 3rd month.

This means that, using the expression the lender got for S2 above, the lender calculates

    S3 = S2 + S2 * r/12
          = S2 * (1 + r/12)
          = P * (1 + r/12) * (1 + r/12) * (1 + r/12).

By the end of the 12th month, the lender wants to know what the borrower would owe --- which would be given by an expression like

   S12 = P * (1 + r/12) * (1 + r/12) * ... 9 more times ... * (1 + r/12)

which in more compact, exponential notation is

S12 = P * (1 + r/12)^12

where '^12' denotes multiplying the number in parentheses by itself 12 times.

A Trip Back to the Middle Ages

It was not so hard for the lender of the Middle Ages to carry out computations for compounding twice a year (every 6 months) --- or 3 times a year (every 4 months) --- or 4 times a year (quarterly).

Let us take a simple value for r --- 1, corresponding to annual interest of 100 percent.

    Although this may sound like a quite-high lending interest in the 21st century, back in the Middle Ages, when people were lucky to live past 30 years old, the lender must have thought the probablity in getting his money back within a year was rather low.

    A year must have seemed like a long time to lend out money to a person. 100 percent interest probably would seem, to the lender, to be justified --- in light of the risk he was taking.

    Besides, the 'payday lenders' of the 21st century would consider 100% a quite reasonable annual interest rate.

At 100 percent interest, the lender would get results like the following --- for the amount owed at the end of one year:

  annual interest: P * (1 + 1) = 2.0 * P

  every 6 months:  P * (1 + 1/2) * (1 + 1/2) =
                   P * 1.5^2 = 2.25 * P

  every 4 months:  P * (1 + 1/3) * (1 + 1/3) * (1 + 1/3) =
                   P * 1.333^3 = 2.368 * P

  every 3 months:  P * (1 + 1/4) * (1 + 1/4) * (1 + 1/4) * (1 + 1/4) =
                   P * 1.25^4 = 2.441 * P

The lenders of the Middle Ages must have been very intrigued by this upward progression in the amount owed at the end of a year.

What if they 'compounded' interest every month? every week? every hour? every second?

It must have looked to them like 'the sky is the limit'.

Even if they used a lower annual interest rate --- like 50 percent or 25 percent --- it looked like they would be in for a huge pay-day at the end of a year.

But they were in for a grand letdown.

The sky was not the limit.

'e' was the limit.

Or, before Euler gave it a single character name, a factor of

2.718 (or slightly greater) was the limit.

Here is a quote from the book "e:The Story of a Number" by Eli Maor (page 187):

    The origins of determining this limit "seem to go back to the 16th century, when it was noticed that the expression (1 + 1/n)^n, appearing in the formula for compound interest tends to a certain limit --- about 2.71828 --- as n increases."

Maor goes on to say

    "Thus 'e' became the
    first number to be defined by a limiting process:

    e = limit of (1 + 1/n)^n as n goes to infinity."

The Swiss mathematician Euler is credited, in math texts, with assigning the lower-case letter E as a symbol to represent that limit.

    In fact, Maor, in his book on 'e', on page 153, points out:

    "we owe to Euler many of the mathematical symbols in use today, among them 'i', the Greek letter pi, 'e', and 'f(x)'."

On page xiii of his book on 'e', Maor points out that

    "Someone --- we don't know who or when --- must have noticed the curious fact that if a principal P is compounded n times a year ... at an annual interest rate of r, and if n is allowed to increase without bound, the amount of money S "

at the end of a year --- found from S = P * (1 + r/n)^n ---

    "seems to approach a certain limit.

    This limit, for P = 1 and r = 1 [that is, 100% interest] ... is about 2.718."

To cut short this introduction here, I summarize by saying that I decided to make a Tk GUI that would have made it easy for any lender of the Middle Ages to see what kind of return he would get on his money by taking 'compounding' to its extremes.

If you want more information on interest compounding or the 'natural number' denoted by 'e', you can do a WEB SEARCH on keywords such as

In Maor's book on 'e', Chapter 3, titled 'Financial Matters', may be of interest.

Several brief tables of calculations are shown there.


As I have done with other Tk scripts that I have written in the past year or so, I laid out a 'text image' of the GUI --- to aid me as I coded the frames and widgets.

I used the following conventions to make the sketch, with a text editor.

  SQUARE-BRACKETS indicate a comment (not to be placed on the GUI).
  BRACES          indicate a Tk 'button' widget.
  A COLON         indicates that the text before the colon is on a 'label' widget.
  UNDERSCORES     indicate a Tk 'entry' widget.
  CAPITAL-O       indicates a Tk 'radiobutton' widget.
  CAPITAL-X       indicates a Tk 'checkbutton' widget (if any).
  <---O--->       indicates a horizontal Tk 'scale' widget (if any).

  According to those conventions,
  I created the following 'text sketch'.

              tkLendersCompoundInterestDreamCrushed ('e' --- about 272% --- Is The Limit)
              [window title]

 .fRbuttons   {Exit} {Help}
 .fRcontrols1 Desired 'base' 
              annual interest (%): 100.00__  [This figure may be shown in a 'disabled' entry widget.]
 .fRcontrols2 Compounding
              period:     O annual  O monthly  O weekly  O daily  O hourly  O by minute  O by second
 .fRmsg       [... Messages to the user can be displayed here on a label widget ...]
 .fRresult    Actual annual
              interest (%): [ Calculated interest is shown in a text widget here. ]
 [The following 'plot' frames may be implemented in the future.]

 .fRplotcntl  {Plot value of  {Backgd  {Line  {Title-Labels  {TicMarks
               (1 + 1/n)^n}    Color}  Color}  Color}         Color}
 .fRplot      -----------------------------------------------------------------------------
              |                                                                           |
              |                                                                           |
              |                                                                           |
              |  ['Canvas' for displaying a plot of (1 + 1/n)^n  against n.]              |
              |                                                                           |
              |                           [eventually]                                    |
              |                                                                           |
              |                                                                           |
              |                                                                           |

From the diagram above, I could see that this GUI will contain about:

  • 2 'button' widgets (7 eventually)
  • 4 'label' widgets
  • 1 'entry' widget
  • 1 'text' widget
  • 7 'radiobutton' widgets
  • 1 'canvas' widget (eventually)
  • 0 'checkbutton' widgets
  • 0 'listbox' widgets
  • 0 'scale' widgets
    (I may someday replace the
    'compounding period' radiobuttons
    with a single scale widget, for an
    integral divisor of the year.)

Assembling the pieces
(The GUI)

Now it was a matter of putting the pieces together.

I took 'code-pieces' from some of my other Tk scripts that 'draw' in an image area on a Tk canvas.

I ended up with the following GUI as an initial display.

Note that I have provided several 'radiobutton' widgets by which to specify a compounding number 'N' --- mostly for 'natural' compounding-periods for which the calculation of 'the total amount owed at the end of a year' is tedious to compute manually.

    (Logarithm tables, that came along around the 1600's, could have provided some computational relief to the late Middle Agers.)

I chose values of 'N' for the following seven compounding periods.

They result in the following computations based on an interest rate of 100 percent for the period.

   annual:        (1 + 1)

   monthly:       (1 + 1/12)^12

   weekly:        (1 + 1/52)^52

   daily:         (1 + 1/365)^365

   hourly:        (1 + 1/8760)^8760            where 8760 = 365*24

   by the minute: (1 + 1/525600)^525600        where 525600 = 8760*60

   by the second: (1 + 1/31536000)^31536000    where 31546000 = 525600*60

Super-quick calculation

As the initial instruction on the message line indicates, a click on a radiobutton causes the compound interest calculation (in a fraction of a second), and the resulting 'actual annual interest percent' is shown in a 'RESULT' line of the GUI.

Wouldn't those Middle Age lenders (bankers and 'dark-ages racketeers' and such) have loved to be able to use Tcl-Tk?

Implementing some Color Buttons
(for lines-and-background on canvas)
(eventually, for plotting)

If I ever add a plotting option to this GUI, the color buttons (next to the 'Exit' and 'Help' buttons) will call on an 'external' color-selector-GUI script to set those colors.

You can make that color-selector script by cutting-and-pasting the code from the page that offers a non-obfuscated color selector GUI on this site.

You can see the code at the bottom of the Tk script to see how the name and location of the color selector script is set.


Below, I provide the Tk script code for this 'tkLenders CompoundInterestDreamCrushed' math-education or math-tool 'app'.

I follow my usual 'canonical' structure for Tk code, for this Tk script:

  0) Set general window & widget parms (win-name, win-position,
     win-color-scheme, fonts, widget-geometry-parms, win-size-control).

  1a) Define ALL frames (and sub-frames, if any).
  1b) Pack   ALL frames and sub-frames.

  2) Define & pack all widgets in the frames, frame by frame.
              Within each frame, define ALL the widgets.
              Then pack the widgets.

  3) Define keyboard and mouse/touchpad/touch-sensitive-screen action
     BINDINGS, if needed.

  4) Define PROCS, if needed.

  5) Additional GUI initialization (typically with one or more of
     the procs), if needed.

This Tk coding structure is discussed in more detail on the page A Canonical Structure for Tk Code --- and variations.

This Tk coding structure makes it easy for me to find code sections --- while generating and testing this script, and when looking for code snippets to include in other scripts (code re-use).

Experimenting with the GUI

As in all my scripts that use the 'pack' geometry manager (which is all of my 100-plus Tk scripts, so far), I provide the four main 'pack' parameters:

  • '-side'
  • '-anchor'
  • '-fill'
  • '-expand'

on all the 'pack' commands for the frames and widgets.

I think I have found a good setting of the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various widgets of this GUI.

In particular ...

Button and label and entry widgets stay fixed in size and relative-location if the window size is changed by the user --- and, if I implement plotting (someday), the 'canvas' widget will expand/contract appropriately when the window is resized.

    I allow the window to be resized --- in anticipation of implementing the plotting canvas someday --- and in planning to allow the canvas (the plot) to be resized when the user resizes the GUI window.

If anyone wants to change the way the GUI configures itself as the main window size is changed, they can experiment with the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various widgets --- to get the widget behavior that they want.

Or they can implement a 'wm' (window manager) command to make the GUI un-resizable. Simply un-comment the line:

wm resizable . 0 0


Additional experimentation with the GUI:

You could change the fonts used for the various GUI widgets.

For example, you could change '-weight' from 'bold' to 'normal' --- or '-slant' from 'roman' to 'italic'.

Or change font families.

In fact, you may NEED to change the font families, because the families I used may not be available on your computer --- and the default font that the 'wish' interpreter chooses may not be very pleasing.

Furthermore, there are variables used to set geometry parameters of widgets --- parameters such as border-widths and padding.

And you could change the '-relief' values for frames and widgets.

Feel free to experiment with those 'appearance' parameters as well.

Some features of the code

There are plenty of comments in the code to describe what most of the code-sections are doing.

The main calculations are done in a 'calc_interest' proc.

See the top of the 'PROCS' section for a list of the procs used in this Tk script.

See comments in the procs for details on the purpose of each proc and for details on the methods by which each proc was implemented.

Below is a quick overview of the procs --- to give an idea of the 'guts' of this utility.

There are only three procs in the initial implementation:

  - 'calc_interest'             - called by button1-release bindings on the
                                  compounding-period radiobuttons.

  - 'advise_user'               - called in the 'Additional GUI Initialization'
                                  section at the bottom of the Tk script
  - 'popup_msgVarWithScroll'    - called by 'Help' button

If I implement plotting, there will be procs like the following:

 'setMappingVars_for_px2wc'  - called by a 'draw_plot' proc.

                               Sets up constants to be used in converting
                               a 'world coordinate' to a 'pixel coordinate'
                               on the Tk canvas.

                        This proc takes the coordinates of an UpperLeft (UL)
                        point and a LowerRight (LR) point --- in BOTH 
                        'world coordinates' and 'pixel coordinates' and
                        sets some global variables to be used by the
                        other drawing procs --- mainly the ratio:

                        the number-of-pixels-per-world-coordinate-unit,
                        global variable 'PXperWC'

    'Xwc2px'     -  converts an x world-coordinate to pixel units,
                    in various draw-lines and draw-text procs.

    'Ywc2px'     -  converts a  y world-coordinate to pixel units,
                    in various draw-lines and draw-text procs.

  End of Drawing utility procs.

  Color-Button utility procs:

  'set_background_color'    - Called by the background color button.
  'set_line_color'          - Called by the plot lines (and points) color button.
  'set_title-labels_color'  - Called by the plot title (and labels) color button.
  'set_ticmarks_color'      - Called by the ticmarks color button.

  'update_button_colors'    - Sets the color of the 4 color buttons.

  End of Color-Button utility procs.

To potential Tcler's

It is my hope that the copious comments in the code might help Tcl-Tk coding 'newbies' get started in making GUI's like this.

Without the comments --- especially in the procs --- the code might look even more cryptic than it already is.

Without the comments, potential young Tcler's might be tempted to return to their iPhones and iPads and iPods (and Samsung and other equivalents) --- to look for videos of late-night news-dissection hosts, such as

dissecting the current political scene in the United States.

While it is tempting to 'tune in' to this exposure of the soft, white under-belly of American Idiocy, please break away occasionally to try some coding using the Tcl-Tk 'wish' interpreter.

The Tcl-Tk script CODE

Here is a link to CODE for the Tk script

'tkLendersCompoundInterestDreamCrushed_ eIsTheLimit.tk'.

With your web browser, you can 'right-click' on this link --- and in the menu that pops up, select an option like

' Save Link Target As ... '

to save this file to your local computer.

Then you can rename the file to remove the '.txt' suffix.

Make sure that you have execute permission set on the file --- in order to execute the script.


I have indicated above several of the enhancements that I am considering adding someday:

  1. Provide an XY plot of (1 + 1/N)^N against N

    I have provided the code (frame and widget definitions ; procs) for implementing a major part of this feature --- in the 'initial' code provided above.

    I may return to this 'app' someday and provide the 'draw' procs to put a plot on a Tk 'canvas' widget --- whose size will be determined by the current GUI window size.

    The XY plot would show the data points increasing to a level of 2.71828...

    A 'WritePlot' button could be added to the GUI to allow for quickly writing out the plot to an image file --- such as a Postscript file.

  2. Replace the several 'radiobutton' widgets by a single 'scale' widget

    This would allow the user to quickly choose from a huge range of values for N --- from 1 to 32 million, say.

    For this initial implementation, I wanted to avoid 'overloading' the user with a huge number of choices for N --- and keep the choices to ones that might have interested a lender in the Middle Ages (and a lender today).

  3. Remove the 'disabled' state from the interest-rate 'entry' widget

    Again, to avoid overloading the user with too many choices, in this initial implementation, I 'fixed' the 'base' annual interest rate at 100 percent.

    In the coming months, I would like to consider (dream up) ways that I could encourage the user to explore the 100-percent case first --- before trying out other interest rates.

    Of course, a Tcler could take the code above and simply remove or comment-out the 'configure' statement that applies '-state disabled' to the entry widget.

  4. UPDATE 2016mar28:

    After a little thought on the two enhancement proposals above, I have decided that the purpose of this Tk script is really to demonstrate how the 'natural number' 'e' comes about 'naturally' from questions raised about compound interest.

    For computations based on an essentially unlimited number of values allowed for a periodically-applied interest rate (R) and a number of compounding periods (N), I have developed another Tk script, at


    which can be used for essentially unlimited values for the input parameters.

    I may add plotting to that script.

    For this "Lenders' Dream Crushed" script, I could replace the annual-interest-rate 'entry' widget by another series of radiobuttons --- with the '.fRcontrols1' frame described above becoming:

  .fRcontrols1   Uncompounded 'base'             100%        50%        25%        20%        10%          5%
                 annual interest (100/M %):   O (M = 1)  O (M = 2)  O (M = 4)  O (M = 5)  O (M = 10)  O (M = 20)  

Note that the 'calc_interest' proc will be changed to evaluate the expression

   ( 1 + 1/(M*N) )^N     where 1/M is the annual interest rate as a fraction (not percent)  

Note that this expression bears a close resemblance to the sequence that defines the 'natural number' 'e'.

In fact, we can rewrite this expression as

   ( 1 + 1/(M*N) )^(M*N)*1/M   =  ( ( 1 + 1/(M*N) )^(M*N) )^1/M  

If we replace the integer M*N by a symbol K, representing integers, then it looks like we have the sequence of numbers that define 'e', but each one raised to the 1/M power.

This is actually the Mth-root of each of the numbers in the sequence, and we can expect the sequence on the left to approach the Mth-root of 'e':

   ( ( 1 + 1/K )^K )^1/M    -------->   e^1/M   as K 'goes to infinity'  
      the sequence
      that defines

If I code this radiobuttons enhancement, I will probably code the XY plotting enhancement --- the 'canvas' widget --- at the same time.

The plot proc will then calculate e^1/M and show that for any given M, the sequence of numbers

( 1 + 1/(M*N) )^N

rises up to meet a horizontal line at the height e^1/M (the Mth-root of 'e') on the graph.

In other words, we show that if a lender is lending money at an interest rate of 100/M percent --- and if the lender offers the money at smaller and smaller compounding intervals --- the 'actual annual interest' approaches a number given by the Mth-root of 'e':

(e^1/M - 1)*100 percent

not including the principal.

Note that e^1/M is always greater than 1, but approaches 1 as M goes to infinity.

This makes sense because M was the divisor of a 100% interest rate --- and as M goes to infinity, we are emulating an interest rate closer and closer to zero.


One advantage of this Tk script is that it is 'open' code --- available to anyone for enhancement.

So if you would like to take a different approach to approximating 'e' --- or the various interest-versus-principal results, you are welcome to take this code and build on it.


As I have said on other code-donation pages on this site ...

There's a lot to like about a utility that is 'free freedom' --- that is, no-cost and open-source so that you can modify/enhance/fix it without having to wait for someone else to do it for you (which may be never).

A BIG THANK YOU to Ousterhout for starting Tcl-Tk, and a BIG THANK YOU to the Tcl-Tk developers and maintainers who have kept the simply MAH-velous 'wish' interpreter going.

Bottom of this web page for
presenting Tcl-Tk code for Tk-GUI
'tkLendersCompoundInterestDreamCrushed_ eIsTheLimit'
--- a Tk script 'app' in the FE 'tkGooies' system,
in the 'MATHtools' group.

To return to a previously visited web page location, click on the Back button of your web browser a sufficient number of times. OR, use the History-list option of your web browser.
OR ...

< Go to Top of Page, above. >

Page history:

This FE web page was created 2016 Mar 24.

Page was changed 2016 Mar 28.
(Added an UPDATE item to the Proposed Enhancements section.)

Page was changed 2019 Mar 07.
(Added css and javascript to try to handle text-size for smartphones, esp. in portrait orientation.)

Page was changed 2019 Jul 01.
(Specified image widths in percents to size the images according to width of the browser window.)

This code and description has not been posted on a Tcler's Wiki page --- at wiki.tcl-lang.org --- formerly wiki.tcl.tk. If I ever do so, as a backup and alternative to this page, I plan to add a link to that Wiki page here.