It is assumed you have access to a TI-85 calculator and are acquainted with the user's manual (such as it is.) Much of what's here can be applied a TI-8X or TI-92 as well, with minor changes in syntax. Be encouraged to experiment for yourself with programming concepts as they are introduced.
We start with some basic stuff you may know already, though perhaps the perspective will be new. The essentials of variables, graphs, input/output operations and program control mechanisms are introduced - in the context of what I hope are some interesting mathematical applications. The level of mathematical sophistication varies from basic algebra to sophomore level calculus.
We finish with some tips about program design you can use to start building a kit bag of scripts for accomplishing common programming tasks using the data structures and input/output features available to the TI 85.
I'll be adding to this document occassionally, so come back now and then to see what's new!
I would like to credit the folks at TI (http://www.ti.com/calc/docs/arch.htm) for helping me learn about the '85.
To see a complete list
of variables currently in use on you calculator, press
[2nd] [3] [F1].
You should get something similar to:
REAL: a real number between -10999 and 10999. The smallest positive real number the calculator can distinguish (to base 10) is 1*10-999 and the largest is 9.9999999999999*10999. Note that the first factor (the mantissa) can use at most 14 significant digits (12 of which are shown by the calculator) and the exponent can use at most 3 digits. Real numbers can be operated on in all the expected ways: math, right?
EX2: Redo the first exercise then press [2nd] [9] to bring up the complex number menu. Press [MORE] [F2] to convert your complex number back to rectangular form. Yeah? If you prefer rectangular mode, go back to the mode page and switch back to RectC before continuing.
EX3: Find all solutions for the polynomial equation
the solutions are given in complex form (note these
all have non zero imaginary parts) but the solver has a rounding error
in the twelfth digit: what should the solutions really be? How can you
check this? Use pencil and paper.
EX2: Press [2nd] [6] to bring up the string menu. Press [F1] to get a quotation mark (") - now repeat EX1.
EX3: Store your name to the variable N ("<your name>" -> N [ENTER]) then recall your name by entering N: [ALPHA] [9] [ENTER].
EX4: Enter N+N. Is it what you expected? How about N*N ?
EX2: It's easy to create a very long list of numbers in arithmetic or geometric progression using the seq function. Put 2 in x using [2] [STOå] [x-VAR] [ENTER]. Type [2nd] [X] to bring up the math menu and then [F5] [F3] to get "seq(" on the homescreen. Now enter [x-VAR] [^] [ALPHA] [9] [,] [ALPHA] [9] [,] [1] [,] [100] [,] [1] [)] [STOå] [SIN] to get seq(x^N,N,1,100,1). Press [ENTER]. The TI-85 will take awhile to compute the first 100 powers of 2 (currently in x) and store the result in the variable named "B." B is static however - that is, changing what's in x now will not change B. To see this put 3 in x and recall B - no difference, no?
EX3: The previous example generated a geometric series using a variable exponent, but any expression whose variables contain values can be used to generate the sequence. A sequence of 100 pseudo random numbers can be saved to a list by entering
Why? Now [EXIT] and make a scatter plot. The fastest way to get "Scatter" is using the catalog. Type [2nd] [CUSTOM] [6] [ENTER]. This will produce "Scatter" on the home screen. Now enter [ALPHA] [LOG] [,] [ALPHA] [SIN] so you have "Scatter A,B" press [ENTER] and wait for the show. Pressing [CLEAR] now will remove the menu from the screen so you can see the whole plot. Are these points randomly distributed? Why or why not?
In this case, the augmented matrix associated with this system has 4 rows and 5 columns (the fifth column is the right hand sides of the equations) so type [4] [ENTER] [5] [ENTER] and the cursor will move down to where you can enter the first row. Type [5] [ENTER] [2] [ENTER] [3] [ENTER] [4] [ENTER] [5] [6] [ENTER] and continue on typing in the other rows. Once the matrix is entered type [EXIT] [ALPHA] [LOG] [ENTER] to see the matrix on the homescreen. Does it look ok? Bring up the matrix menu and hit [F4] for the matrix operations menu. [F4] [ALPHA] [LOG] will reduce A to row echelon form. Also [F5] will give you reduced row echelon form, but the teacher wants to see the steps one row operation at a time. For these tools press [MORE] and you'll see rSwap, rAdd, multR and mRAdd. These are the row operations.
Type rSwap(A,1,4)->A to swap the rows
1 and 4.
This is an easy way to get a "1" in
the 1st row/1st column position.
Now do mRAdd(-4,A,1,2)->A to add
-4 times the first row to the second row.
To finish off the first column add -5 times
the first row to the fourth row with mRAdd(-5,A,1,4)->A.
Ok? First column complete!
Now multiply the second row by -1 to
get a 1 in the 2nd row/2nd column
position: multR(-1,A,2)->A.
Subtract the second row from the third.
Subtract twice the second row from the fourth row. So far we've been
able to avoid fractions, but now we have a bit of a problem. This could
be handled in a number of different ways.
Divide the third row by 5 (multR(1/5,A,3)->A)
and then subtract 33 times the third
row from the fourth.
Dividing the last row by 4.2 shows
that z=10. Back-substituting
yields the other solutions: y=4, x=-3 and
w=2.
By the way, it is worthwhile to take a moment to ponder the difference between a variable and function. A program can be thought of as a function if it accepts input and produces output uniquely determined by the input. A program can be thought of as a variable - in some sense, they are one and the same beast . Like a function, a variable's value can extend over any predefined range, but it is only a function if its value depends on another value in a well defined way.
In the sense that SINE is a name that holds the code of the program, it's a variable of type PRGM. In the sense that SINE is a program that takes input and produces output unique to that input, it's a function.
Also be careful with x, y, t, r, equ, exp, Q1...Q9, and QI1...QI9 since the are used by TI-85 when graphing and/or using the solver.
The variables y1...y99, r1...r99, xt1...xt99, yt1...yt99 and Q'1...Q'9 must hold "equations" - that is, variables of type EQU.
"xStat" and "yStat" must be variables of type LIST.
lower and upper must be real numbers, as must xMin, yMax, etc.
You cannot display text on the graph screen, nor graphs on the home screen, so when designing a program, choose either the more time-consuming good graphics graph path or the easier home screen path.
The TI-85 screen is made up of 127*63=8001 pixels (a pixel is a 'point' on the screen that can be dark=on or light=off.) These pixels are arranged in a rectangular array 127 pixels wide and 63 pixels high.
But these appear on the home screen. Of course, the same pixels are used for the graph screen. Pressing [GRAPH] brings up the graph screen and the first 5 of the 13 main graph menu options.
Let's explore the graphics tools available here.
y(x)=
This allows you to insert functions to graph.
RANGE Allows
you to set the x and
y ranges of the graph.
ZOOM As
the name implies, this allows you to zoom in and out.
TRACE Trace
the graph of a function displaying the x and
y values.
GRAPH Graphs
the current function.
MATH LOWER These
are used in combination with xMin and
xMax and
UPPER ZOOM change the range of the graph window
and/or some functions.
ROOT Uses the solver to find zero of the function
between LOWER and
UPPER.
dy/dx Compute the slope of a line tangent to the
curve at the cursor's x-value.
Sf(x) Compute numerical integral from LOWER
to UPPER.
FMIN Compute the minimum value of a function
between LOWER and
UPPER.
FMAX Compute the maximum value of a function
between LOWER and
UPPER.
YICPT Compute the y-intercept (f(0)).
ISECT Find where two functions intersect between
LOWER and UPPER.
DIST Find the straightline distance between
two points on function(s).
ARC Find the distance along the curve
of a function between two points.
TANLN Draw the line tangent to a curve at a point.
DRAW Shade Shades
the area between two functions.
Line Draws a line from starting point and again
to ending point.
Vert Draws a vertical line from the bottom
to the top of the screen.
CIRCL Draw a circle with radius selected by two points.
DrawF Draw a function - you must supply a variable
of type EQU.
PEN Turn the pen on and off with
ENTER and draw with arrows.
PTON Turn pixels on by positioning the cursor
and pressing ENTER.
PTOFF This (or PTCHG)
will turn pixels off (or change to its opposite.)
CLDRW Erase the all drawings on the screen - the
active functions remain.
CLDRW Erase the all drawings on the screen - the
active functions remain.
TanLn Draws a line that is tangent to function at
the x value.
DrInv Draws the graphical inverse of the function
provided.
FORMT Contains
graph formating options, such as show x/y axes.
StGDB Store
all the range and format preferences, all functions.
RcGDB Recalls
a graph database stored previously.
EVAL Function
evaluated and cursor positioned at given x.
StPic Similar
to StGDB but only stores the graph
itself.
RcPic Recalls
a picture or graph stored previously.
Note that we have too many oscillations and there are no points of intersection
below the axis, so I've created a zoom box on a portion around the upper
left where there may be some intersection. The coordinates of the lower
left corner of the zoom box are shown at the bottom of the screen.
After zooming in, you could simply trace and zoom again for accuracy -
I pressed [MORE] [F1] [MORE] [F5] to
initiate the ISECT function moved
the cursor some and pressed [ENTER] twice
and '85 came up with the point of intersection shown at left. Notice that
the third of four points of intersection in this window is highlighted.
Ok, so instead of entering a function where the vertical coordinate, y, is a function of the horizontal coordinate, x - we have the distance from the origin, r, as a function of the polar angle, θ. This makes the equations of some curves simpler. The circle of radius 1/2 centered at (1/2,0) is y = ±sqrt(x-x2) in rectangular coordinates and r = cosθ in polar form. Writing the polar function for the heart shaped (cardioid) function r(θ) = 1 - sinθ in rectangular forms yields the unwieldy sqrt(x2 + y2) - (x2 + y2) = y
What if we want to find the area common to the interiors of these closed
curves? To see this area on you '85, hit the r(θ)=
key and set r1=cosθ
and r2=1-sinθ
and then [GRAPH]. With
the ranges set for θMin=0 θMax=6.2832,
xMin=-1.4, xMax=1.4 we get the graph shown here (color is added
to the overlapping region by Photo Shop - the Shade
feature only works on the rectangular page.) Another
awkward gap is that you can't measure areas with the integrating function
as you can on the rectangular page.
Not to worry! The half circle has area pi/8 (half of pi*r2). For the cardioid, (r=1-sin(θ)), integrate r2/2 over θ in the interval from 0 to pi/2:
pi/2
1/2S(1-2sin*(x)+sin2(θ))
dθ
0
using the identity sin2θ = (1-cos2θ)/2, apply the fundamental theorem of calculus:
Adding in the area of the half circle we have a total area of
pi/2 - 1. Here's a screenshot of my check on the '85 at
left - just checking that the portion of the area enclosed by the cardioid
is right. fnInt is the numerical integrator which is accessible by pressing
[2nd] [<division>] to bring up the calculus menu, and
then [F5].
Ex3: To set parametric mode hit [2nd] [MORE] and scroll down and over to highlight Param and then [EXIT]. One of my favorite shapes which is best described using parametric equations is the epitrochoid. The epitrochoid is a shape drawn out by a point on a circle which is rolling around on another circle. Press [GRAPH] [F1] and type in
0
= S(sint+(sin(3t))/4)(-sint-3sin(3t)/4)dt
pi/2
pi/2
= S(sin2t+sintsin(3t)+3sin2(3t)/16)dt
0
This can be evaluated symbolically without much trouble, but let's use the numerical integrator on the '85. Bring up the CALC menu, hit [F5] and type in
fnInt((sin x)2+sin x*sin (3*x)+3*(sin (3*x))2/16,x,0,pi/2)
which evaluates to 0.93266 and thus we have a total area 4 times that: 3.73 square units.
A lorenz system is described by the solution of three simultaneous differential equations:
Here's a picture of the same system with the same initial conditions, only
viewing the plot of x=Q2; y=Q3. From
these two projections you can imagine what the 3-dimensional graph might
look like. To see a picture of it and read some more about how Lorenz used
this system to model air flow inside a heated box, check out this site:
http://www.students.uiuc.edu./~ag-ho/chaos/lorenz.html
Let me offer some reasons:
The Outpt()function is used to make the program print something on the screen. The general form is:
The "For" loop with syntax
As such, it's worth pausing to examine further. Here's some fought Thor food:
To have the program first prompt you, sir (or madam,) for a character to fill the screen with, write a program called FLLR with the following code:
The InpSt function is used whenever you want the user to input a string of letters: :InpSt <variable>. Try substituting InpSt for Input in this program. What do you think?
Ex2: How about taking a string and waving it around on the home screen? Here's a more complicated program which illustrates a few tricks.
Here's a list of keys and their return values:
Using getKy with the control command, While, is an effective way to branch a program from user input. Here's a little program fragment to illustrate this:
Note the relational operator, "==," should not be confused with the assignment operator, "=," which stores an expression in a variable of type EQU. The "equals?" operator, ==, checks to see if two values or strings match, and returns 1 if they match or 0 if they don't match.
The word Then is used after If when you need more than just one statement evaluated after If. The word End signals the end of the list of things to do. This has the form:
1) Decide what you want your program
to do.
2) Write pseudocode; that is, outline
in broad strokes how the flow will go.
3) Draw graphics, if necessary, on
graph paper - images that the program will use.
4) Work out methods to do difficult
routines, drawing on innovation and experience.
5) Type it in. It's easier to use
a computer keyboard, if you have the Link utility.
6) Test.
7) Debug.
8) Add on new features you think would
enhance the performance.
9) Test
10) Debug
11) Make documentation, bundle, other things
needed for full program.
12) Release beta version.
Step 2 refers to writing on paper, code which uses terms from the language but is just an outline of what will happen.
Step 3 is necessary if you want to test parts of the program before it is completed. If the Pics aren't finished it won't work.
Step 4 is where software engineers define their skill. You often run into routines you have no idea how to do. Use pencil and paper so you can see the whole thing. Make a flow chart, thread through the commands one at a time, making a list of what variable has what value when. Think of alternatives, look in the CATALOG for commands that may be useful.
Debugging (aka error checking or troubleshooting) in step 6 is really an extension of step 4. This is the "check" part of the "guess and check" method. Sometimes a bug is so elusive, you cannot find it. This is why professional software companies release "beta" versions of their software for free. If enough people try to use the software in crazy ways, its weaknesses usually surface fairly quickly. Go through the code step-by-step keeping a table of the values of all the variables involved at those points, and do the commands just as the TI would. This may help you to see where, when, and under what circumstances you run into the problem. Try using different input values: good software is idiot proof and will disallow crazy input. By the time you've done all that, you may have new ideas, don't be afraid to start from scratch again.
So that's step 1 in the design process. The pseudo code now might look like this:
Rather than start at the beginning and develop code linearly, it may be better to start in the middle and work outwards. Can you identify loops that will be employed? We'll need one loop to accept a character and another to bounce it around once we have it.
Some languages have a "case" statement which can be used to branch on a key press, on the TI, the If-Then-End commands can serve the purpose - but since there is no methodical way to converting the number value to an alphabetic character that I can think of, I think I'll need a separate If-Then-End statement for each key.
Does this mean retyping the code for moving the character inside each Then-End block? Fortunately, no. We can write what's called a "subroutine" as a separate program which can be called by the main program. Let's see how this might work.
Given the alphabetic character, the subroutine will need to to choose its initial position and send it moving with erase/redraw. It will also have to know when a new key is pressed. Finally, it will need a way of moving the figure. Assuming the alphabetic character has already been stored in the variable, S, after some fumbling, I come up with:
:1+int (20*rand)->H
// Choose a random integer between 1 and 21
:1+int (7*rand)->V
// Choose another between 1 and 8 (inclusive)
:1->I //
These are the increment variables, initially set to
:1->J // move
the character down and to the right.
:0->M // M will hold
the value of any key that is pressed.
:While M==0
// If a key is pressed, we'll exit the subroutine
:if H==21
// If at the right wall,
:-1->I
// then reverse the horizontal increment (bounce)
:if H==1
// If at the left wall,
:1->I
// bounce right.
:if V==8
// If at the bottom,
:-1->J
// bounce up.
:if V==1 //
If at the top,
:1->J
// bounce down.
:Outpt(V,H," ")
// Before incrementing the indices, erase.
:H+I->H
// Increment horizontal position.
:V+J->V
// Increment vertical position.
:Outpt(V,H,S) //
Redraw the character at the new position
:For (K,1,30) //
Kill some time (if it moves too fast, you can't see it.)
:1->N
// Whatever...
:End
// End For loop
:getKy->M
// Check to see if a key has been pressed
:End
// End while loop
:Return //
Go back to the main routine.
Enter this code under the name POSSUB.
Now all we need is a routine which will see which key has been pressed and convert its value to an alphabetic character. The following gets the job done, even if it looks a bit clunky:
:ClLCD
:1+int (20*rand)->H //
Initialize the horizontal position.
:1+int (7*rand)->V //
Initialize the vertical position.
:0->next //
When next is 1, we exit.
:ClLCD //
Clear the deck.
:0->M
:While (M==0) //
Wait for the first key press to get going.
:getKy->M
:End
:Repeat next
// This is the outer loop of the main routine.
:Outpt(1,1,"HEY")
// This was originally for error checking - I left it in.
:Outpt(3,1,M)
:If M==51
// If the value of the key pressed is 51
:Then
:"A"->S
// The "A" key was pressed so load S with "A".
:POSSUB
// Do subroutine stuff with "A" in S.
:End
:If M==52 //
Same as above, only the "B" key was pressed.
:Then
:"B"->S
:POSSUB
:End
....
// Repeat If-Then-End for each character of the alphabet.
:If M==103
:Then
:"Z"üS
:POSZ
:End
:If M==105 //
If the [ENTER] key is pressed
:Then
:1->next //
Load next with 1 so as to exit the Repeat loop.
:End
:End //
End Repeat loop.
Here's a program using a menu:
Getting Maximum Graphics on the '85.
Using the Graph Screen for Animation from a Program
Using Line() and PtOn() in cases where the pic will only require less than, say, 50 pixels is preferable to using ClDrw or RcPic which effect all 127*63 = 8001 pixels. In cases where more pixels are present, StPic does a better job at keeping things small. And, don't ever forget to set xMax at 127, yMax at 63, and xMin,yMin at 0.
Since the Outpt() command doesn't write to the graph screen, to print text on the graph screen requires drawing the character using the Line() and PtOn() commands.
Make a grid (or use graph paper) the size of your desired letter or number. Write y,y+1,y+2,... in a column on the left side of the grid, and x,x+1,x+2,... along the bottom. Then, fill in the boxes (corresponding to pixels) to draw the letter. For example:
When designing a full-screen graphic to be saved as a
Pic, make a 127 x 63 grid.
If you have access to a computer graphics software like Photo Shop Pro
or Paint for Windows, make a 127 x 63 rectangle
and use the software tools available to draw the picture, then transfer
to graph paper with a pencil. Then on the TI use the [PEN]
tool under the [GRAPH] [MORE] [DRAW] [MORE] menu.
If your range is set as in the DrA program
above, you will see the exact coordinates of the pixel the cross hair is
on at the bottom of the screen. Maybe this is how the Dilbert graphic shown
here was made? I don't who did it, or where I got it. Below is the Photo
Shop prototype of Cyclops with Birds I created, together with the TI Pic
I made from it:
Note that I got confused by the coordinate system of Photo Shop (which has y increasing as you go down) so the first bird is too low. Also, I ad-libbed a bit in the translation. Just impatient, I guess.
Better yet, in many ways, is the 86iview program available for free at the TI calculator archives: http://www.ti.com/calc/docs/arch.htm. Using 86iview I drew the following picture demonstrating the 3-colorability of the trefoil knot, in 2 minutes: