The Epsilon-Delta Game

Many calculus students regard the epsilon delta definition of function limits as the most intimidating part of calculus. But this notebook turns learning the topic into a game. The dual goals are to automate the teaching of epsilon and delta basics as much as possible, and to make the topic enjoyable! The notebook will first help you create a limit problem from a wide range of possibilities.  Then (for functions of four basic forms) you will receive the preliminary algebraic simplification that a solution requires, so that you may concentrate on the logic instead of the algebra.   In the background, the notebook calculates its own recipe for the deltas. After you develop your own recipe, there will be a game pitting the notebook's deltas against yours. (More on the rules of the competition, later.) You will see pictures which show you whether your deltas are working, and also whether you are "beating the notebook."  You can then choose to see a rigorous epsilon delta proof for the limit problem, as well as a geometric explanation of why the procedure used for finding the notebook's deltas is feasible.  After you absorb the explanations at the end, you will not only win the game every time; you should actually be able to write a good proof of why your δ recipe must work! 

Now let's talk about some of the technical details.  If some of them sound mysterious, that's because you haven't played the game yet!  Even if you have seen the limit definition, you may need to have your memory refreshed: "L is the limit of f(x) as x approaches x=a" means "No matter how small a vertical ("epsilon") target interval we specify around the limit height of L, there is a corresponding horizontal ("delta") interval around the x value x=a, such that for each x in that interval (ignoring x=a itself), its f(x) value is in the epsilon interval.  In more concise language: for each ϵ>0, there is a δ>0 such that if 0<|x-a|<δ, then |f(x)-L|<ϵ.  Again, don't think you have to understand this before you play: the game  will make the meaning clear!  

You might be tempted to select a very small catchall δ like ϵ*(10^(-30)) which will just "probably" work.  But the goal is to learn to construct a δ recipe which will surely work for your particular f[x]. The game therefore encourages you in that direction: to win, you not only have to generate δ's such that 0<|x-a|< δ insures |f(x)-L|<ϵ (that's all the mathematical definition requires); your δ's also have to be bigger than the Autoδ's that the notebook computes for itself. The explanation at the end will show you how to calculate a "winner." When every single one of your δ's wins during the testing, you probably understand the topic very well.

Proceed from top to bottom except as directed otherwise.  A few brief notes to those who haven't used Mathematica: to execute a cell, click on it and hit Enter on the keypad (not on the main keyboard).  If you later decide to re-execute a cell, you do not have to delete the old output: Mathematica will overwrite any old output.  When the "Local Kernel Input" dialog window appears, you may drag the window out of your way.   Enter your response by either clicking on OK or by hitting Enter on the keypad.   When the "Local Kernel Input" dialog window is open,  DO NOT click on the scroll bar to move back in the notebook.  If you click on the scroll bar while the "Local Kernel Input" window is open, the window will disappear, Mathematica will freeze in a "running mode", and your only recourse will be to quit the local kernel.  When you do that, all variable values will be lost and you will have to start over!  Not good!! 

Enough talk!  Let the game begin!

Do not execute this closed group of initialization cells manually.  When you first choose your function type by executing ONE of the green bracket cells below, Mathematica will ask whether you want to execute all the initialization cells.  Click on yes.

$TextStyle = {FontFamily -> "Courier New", 
          FontSize -> 11};

GetIPick := 
          Module[{}, {LegalIpick = "false"; 
While[
                  LegalIpick == "false", {LegalIpick = "true"; 
                    IPick = 
                      Input["Enter a 1 if you wish to select your own \
coefficients, 0 if you want Mathematica to select them."], 
                    If[IPick ≠ 1 && 
                        IPick ≠ 
                          0, LegalIpick = "false";]}]};];

(*This short module gives directions at the end of GetValueOfa[g_], which follows.*)
DirectionsToPurple:=Module[{},OtherWords=Graphics[Text["If you are not satisfied, execute this cell again.\nIf you are satisfied, go to the        bracket cell.", {-1,-.5}, {0,0}]];
Purple=Graphics[{RGBColor[1,0,1],Text["purple", {315,-2.2}, {0,0}]}];
Show[Purple,OtherWords, ImageSize->{500,25}, PlotRange->{{-100,100},{-3,2}}];];

GetValueOfa[g_]:=Module[{},{Finished = 0;While[Finished == 0, Print["We have g[x]=" <> 
                              ToString[g[HoldForm[x]],  
                                StandardForm] <> ". We will consider the \
limit at x=a." <> If[Opt > 
                                  1,  "\nChoose 'a' so that there is a \
visible interval centered on x=a where g[x] is continuous \nand some g[x] \
values are more than 2 units away from g[a].(If no value of 'a' makes \nthis \
happen, enter ANY 'a', but then re-execute this cell for another g[x].)", "\
"]];
Pause[3];
Legala = "false";
While[Legala == "false", 
                            Legala = "true"; 
                            a = Input["We will evaluate the limit at x=a; \
type your choice of a (avoid decimals) and click on OK or hit Keypad Enter to \
continue."];  If[IntegerPart[a] ≠ a && 
                                Denominator[a] == 1, 
                              Legala = "false"]];
If[Opt == 3 || Opt == 4,  
                            While[Denom[a] == 
                                0, a = 
                                  Input["Please try again;your previous \
choice of a=" <> ToString[a, 
                                        InputForm] <> " resulted in a \
vertical asymptote at x=a."];]];
Print["We will evaluate the limit at x=a=\
", a, ". You will later need the value of g[a] below."];
mapprox = (g[a +  .001] - 
                                  g[a -  .001])/ .002;
aGridLine = {a, {Thickness[ .00250], 
                                Dashing[{ .05,  .05}]}};TextAta = 
                            Graphics[
                              Text["x=a=" <> ToString[a, StandardForm], 
                                Scaled[{ .5,  .1}]]];
LabelForPoint = 
                            Graphics[
                              Text["[" <> 
                                  ToString[a, StandardForm] <> "," <> 
                                  ToString[g[a], 
                                    StandardForm] <> "]", {a, 
                                  g[a]}, {-1, 0}]];
CircleAta = 
                            Graphics[
                              Circle[{a, g[a]}, Scaled[{ .008,  .006}]]];
MaxDeltaGuideLines={Graphics[{If[Opt > 1, RGBColor[0,  .5, 1], 
                                      RGBColor[1, 1, 1]],Dashing[{ .01,  .01}] , Line[{ {LeftEnd, 
                                        g[a] - 2}, {RightEnd, g[a] - 2}}], Line[ { {LeftEnd, 
                                        g[a] + 2}, {RightEnd, g[a] + 2}}]}]};
If[Opt == 1,  
                            Supplement = {LabelForPoint}, 
                            Supplement = {LabelForPoint, 
                                MaxDeltaGuideLines}];
If[
                            Opt > 1, Show[OptPlot, CircleAta, Supplement, 
                                ImageSize -> 450, 
                                PlotRange -> {If[
                                      mapprox == 0, {LeftEnd, 
                                        RightEnd}, {Max[LeftEnd, 
                                        a - 4/Abs[mapprox]], 
                                        Min[RightEnd, 
                                        a + 4/Abs[mapprox]]}], {g[a] - 4, 
                                      g[a] + 4}}, 
                                Axes -> {True, False}];];
If[Opt == 3 || Opt == 4,  
                            DistToAsym =  Min[Abs[Asymptotes - a]]];
If [Opt == 1, {MaxDelta = 4/Abs[K[2]];},{\(MaxDelta = \(-1\); 
                                While[
                                  MaxDelta ≤ 0\  || \((\ 
                                      IntegerPart[MaxDelta] ≠ 
                                        MaxDelta && 
                                        Denominator[MaxDelta] == 1)\), 
                                  Print["For nonlinear functions, the mathematical procedure begins by setting an upper 
limit on δ, independent of what ϵ's might later be given. Call the limit MaxDelta." <> If[Opt > 
                                        2, "
If keeping 0<|x-a|<δ≤MaxDelta is to force |f(x)-L| to be small, clearly we need to make 
sure that the interval [a-MaxDelta,a+MaxDelta] must not reach to a vertical asymptote. 
There is no other mathematical restriction on MaxDelta.", ""] <> \ "
For tutorial reasons, we want to make sure the first admissible δ interval can not fill 
the graphing window. The instructions you will see involving the blue lines come from 
this restriction."]\ ; \ Pause[3]; MaxDelta = 
                                    Input["Enter a positive value of MaxDelta (avoid decimals) as described in the instructions on the screen." <> \ If[Opt == 3 || Opt == 4 || Opt == 
                                        5, "Avoid any vertical asymptote of g[x]: keep MaxDelta<" <> ToString[DistToAsym, InputForm] <> 
                                        If[Opt == 
                                        5, " if there IS a vertical asymptote.", "."], "."] <> "

Choose MaxDelta large enough that some x's in the interval [" <> \ ToString[a, 
                                        InputForm] <> "-MaxDelta," <> 
                                        ToString[a, 
                                        InputForm] <> "+MaxDelta] give a g[x] outside the blue lines. If no satisfactory MaxDelta is available, enter a MaxDelta " <> If[Opt == 3 || Opt == 4 || 
                                        Opt == 5, "under " <> 
                                        ToString[DistToAsym, 
                                        InputForm], ""] <> ", but then re-execute this cell with a new g[x] or 'a'."]]; 
\ \ \ \ \ \ \ \ 
\ \ \ \ \ If[Opt == 3 || Opt == 4, \ While[
                                    DistToAsym ≤ 
                                      MaxDelta, 
\ \ \ \ \ \ \ \ \ \ \(MaxDelta = Input["Try again;your previous choice of MaxDelta=" <> 
                                        ToString[MaxDelta, 
                                        InputForm] <> " resulted in a vertical asymptote in the interval [" <> \ ToString[a, 
                                        InputForm] <> "-MaxDelta," <> 
                                        ToString[a, 
                                        InputForm] <> "+MaxDelta]. To avoid an asymptote, keep MaxDelta<" <> \ ToString[DistToAsym, 
                                        InputForm] <> "."];\)]];\)}];
          MaxDeltaBoxLines = 
                            Graphics[{If[Opt > 1, RGBColor[0,  .5, 1],  
                                  RGBColor[1, 1, 1]], 
                                Dashing[{ .01,  .01}] ,  
                                Line[{ {a - MaxDelta, 
                                      g[a] - 4}, {a - MaxDelta, 
                                      g[a] + 4}}],  
                                Line[ { {a + MaxDelta, 
                                      g[a] - 4}, {a + MaxDelta, 
                                      g[a] + 4}}]}]; ShowChoices=Show[OptPlot, 
                              CircleAta, Supplement, MaxDeltaBoxLines, 
                              ImageSize -> 450, 
                              PlotRange -> {{a - 2*MaxDelta, 
                                    a + 2*MaxDelta}, {g[a] - 4, g[a] + 4}}, 
                              Axes -> True];
If[
                            Opt > 1, Print["Your current choices are \
a=" <> ToString[a, StandardForm] <> " and MaxDelta=" <> 
                                  ToString[MaxDelta, 
                                    StandardForm] <> "; The function \
g[x]=" <> ToString[g[HoldForm[x]], 
                                    StandardForm] <> ". \nFor some x \
between the vertical blue lines, g[x] should be outside the band between \n\
the horizontal blue lines. If this does NOT occur above, re-execute this cell \
with \nnew choices. If it does occur, then go down to the cell with the \
purple bracket."];, If[Opt > 1, 
                                Print["Regardless of the ϵ which \
the notebook give you later, the notebook will not let you \nchoose a \
δ above MaxDelta=" <> ToString[MaxDelta, 
                                      StandardForm] <> ", corresponding to \
the two blue lines. Staying under that \nvalue will not be hard: any time a \
δ works, every smaller δ also works!"]];]; ValidFinished = False;
While[ValidFinished == False,  
                            Finished = 
                              Input["Enter 1 if you want to go on to the \
purple bracket or if you plan to re-execute this cell for a new g[x] and new \
'a'; \nEnter a 0 if you want to change 'a' while keeping g[x]."];  
                            If[Finished == 0 || Finished == 1,  
                              ValidFinished = True, ValidFinished = False]];If[Finished == 0, Show[OptPlot], 
                            DirectionsToPurple]]}; ];